constructor(props) {
   super(props);
   this.state = {
     editorState: props.editorState
       ? EditorState.createWithContent(convertFromRaw(props.editorState))
       : EditorState.createWithContent(ContentState.createFromText('Insert text ...'))
   };
 }
 createEntity(type: string, data: DataMap<string>, mutability: EntityMutability = 'MUTABLE') {
   this.contentStateForEntities = this.contentStateForEntities.createEntity(
     type,
     mutability,
     data,
   );
   return this.contentStateForEntities.getLastCreatedEntityKey();
 }
/**
 * This function merges contentBlocks into existing article
 * @param {*} contentBlocks - draft ContentBlock
 * @param {*} article - Article to merge data
 */
export default function DraftToJSON(contentState: ContentState, srcCover: LdJsonDocument) {
  const blockMap = contentState.getBlockMap();
  const filteredBlockMap = filterBlockMap(blockMap);
  const cover = mkCoverJson(srcCover.getElementOfType('ImageObject'), filteredBlockMap); // first pass
  const order = getOrderOffset(cover);

  // second pass to create links images and socials
  filteredBlockMap.forEach((element, i) => {
    let entity;
    const findEntityOfType = type => (char) => {
      const entityKey = char.getEntity();
      entity = entityKey ? Entity.get(entityKey) : null;
      return !!entity && entity.getType() === type;
    };
    const mkLink = block => (anchorOffset, focusOffset) => {
      const data = entity.getData();
      const url = data.linkUrl;
      const name = data.linkTitle || '';
      const linkText = block.getText().substring(anchorOffset, focusOffset);
      cover.mentions.push(getMention(name, '', formatMention(url, linkText, order + i, anchorOffset)));
    };

    element.el.findEntityRanges(findEntityOfType('LINK'), mkLink(element.el));
  });
  return cover;
}
示例#4
0
 it('should get selected block key', () => {
   const contentState = ContentState.createFromText('we need to connect the bluetooth SSL capacitor!');
   const block = contentState.getFirstBlock();
   const blockKey = block.getKey();
   const editorState = EditorState.createWithContent(contentState);
   expect(getSelectedBlockKey(editorState)).toEqual(blockKey);
 });
示例#5
0
describe('ImageRenderer', () => {
  const contentBlocks = convertFromHTML('<div>test</div>');
  const contentState = ContentState.createFromBlockArray(contentBlocks);
  const editorState = EditorState.createWithContent(contentState);
  const entityKey = contentState
    .createEntity('IMAGE', 'MUTABLE', { src: 'testing' })
    .getLastCreatedEntityKey();
  const newEditorState = AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ');

  it('should have state initialized correctly', () => {
    const Image = getImageRender({
      isReadOnly: () => false,
      isImageAlignmentEnabled: () => true,
    });
    const control = shallow(
      <Image block={getAllBlocks(newEditorState).get(1)} contentState={contentState} />,
    );
    expect(control.state().hovered).toBeFalsy();
  });

  it('should have 1 child element by default', () => {
    const Image = getImageRender({
      isReadOnly: () => false,
      isImageAlignmentEnabled: () => true,
    });
    const control = shallow(
      <Image block={getAllBlocks(newEditorState).get(1)} contentState={contentState} />,
    );
    expect(control.children().length).toEqual(1);
  });
});
示例#6
0
 it('should not change depth if block is not a list', () => {
   const { contentBlocks } = convertFromHTML('<h1>aaaaaaaaaa</h1>');
   const contentState = ContentState.createFromBlockArray(contentBlocks);
   let editorState = EditorState.createWithContent(contentState);
   editorState = changeDepth(editorState, 1, 4);
   assert.equal(getSelectedBlock(editorState).getDepth(), 0);
 });
示例#7
0
export const removeDisallowedBlocks = (editorState, blocks, layout, hasFeatures, keepExisting) => {
  const allowedBlocks = blockRenderMapArray(layout, hasFeatures)
  const currentContent = editorState.getCurrentContent()
  const selection = editorState.getSelection()
  let newState

  const cleanedBlocks = blocks.map((contentBlock) => {
    const unstyled = stripCharacterStyles(contentBlock, true)
    const isAllowedBlock = allowedBlocks.includes(unstyled.getType())
    const isLink = unstyled.getType() === 'LINK'

    if (isAllowedBlock || isLink) {
      return unstyled
    } else {
      return unstyled.set('type', 'unstyled')
    }
  })

  const newBlocks = ContentState.createFromBlockArray(cleanedBlocks, blocks)

  if (keepExisting) {
    const newContent = Modifier.replaceWithFragment(currentContent, selection, newBlocks.blockMap)
    newState = EditorState.push(editorState, newContent, null)
  } else {
    newState = EditorState.push(editorState, newBlocks, null)
  }

  return newState
}
export default (text, plugins) => {
  const compositeDecorator = createCompositeDecorator(plugins);
  return EditorState.createWithContent(
    ContentState.createFromText(text),
    compositeDecorator,
  );
};
示例#9
0
describe('<FontFamily />', () => {
  const contentBlocks = convertFromHTML('<div>test</div>');
  const contentState = ContentState.createFromBlockArray(contentBlocks);
  const editorState = EditorState.createWithContent(contentState);

  it('should have a div when rendered', () => {
    const wrapper = mount(
      <FontFamily
        onChange={() => {}}
        editorState={editorState}
        config={defaultToolbar.fontFamily}
        modalHandler={new ModalHandler()}
      />,
    );
    expect(wrapper.find('.be-ctrl__group').length).toBe(1);
  });

  // it('should have a dropdown child component well defined', () => {
  //   const control = mount(
  //     <FontFamily
  //       onChange={() => {}}
  //       editorState={editorState}
  //       config={defaultToolbar.fontFamily}
  //       modalHandler={new ModalHandler()}
  //     />,
  //   );
  //   expect(control.childAt(0).props().children.length).toBe(2);
  //   expect(control.childAt(0).props().onChange).toBeDefined();
  // });
});
示例#10
0
    EditorCore.prototype.Reset = function Reset() {
        var defaultValue = this.props.defaultValue;

        var contentState = defaultValue ? defaultValue.getCurrentContent() : _draftJs.ContentState.createFromText('');
        var updatedEditorState = _draftJs.EditorState.push(this.state.editorState, contentState, 'remove-range');
        this.setEditorState(_draftJs.EditorState.forceSelection(updatedEditorState, contentState.getSelectionBefore()));
    };
示例#11
0
  rehydrate: function (state) {
    this.activity = state.activity
    this.volunteers = state.volunteers
    this.updates = state.updates

    _.forEach(state.activityState.entityMap, function(val, key) {
      val.data.mention = fromJS(val.data.mention)
    })

    var contentState = Draft.convertFromRaw(state.activityState)
    this.activityState = Draft.EditorState.push(this.activityState, Draft.ContentState.createFromBlockArray(contentState.getBlocksAsArray()))

    // Formularz aktualizacji do zadania
    var contentState2 = Draft.convertFromRaw(state.newUpdateState)
    this.newUpdateState = Draft.EditorState.push(this.newUpdateState, Draft.ContentState.createFromBlockArray(contentState2.getBlocksAsArray()))
  }
        const getCell = (i, j) => {
            const cellContentState = cells[i] && cells[i][j]
                ? convertFromRaw(cells[i][j])
                : ContentState.createFromText('');

            return new HTMLGenerator(cellContentState, ['table']).html();
        };
示例#13
0
 it('should correctly get inline styles', () => {
   const { contentBlocks } = convertFromHTML('<h1>aaaaaaaaaa</h1><ul><li>test</li></ul>');
   const contentState = ContentState.createFromBlockArray(contentBlocks);
   let editorState = EditorState.createWithContent(contentState);
   const updatedSelection = editorState.getSelection().merge({
     anchorOffset: 0,
     focusOffset: 10,
   });
   editorState = EditorState.acceptSelection(
     editorState,
     updatedSelection,
   );
   editorState = RichUtils.toggleInlineStyle(
     editorState,
     'BOLD',
   );
   assert.equal(getSelectionInlineStyle(editorState).BOLD, true);
   editorState = RichUtils.toggleInlineStyle(
     editorState,
     'STRIKETHROUGH',
   );
   assert.equal(getSelectionInlineStyle(editorState).STRIKETHROUGH, true);
   editorState = RichUtils.toggleInlineStyle(
     editorState,
     'CODE',
   );
   assert.equal(getSelectionInlineStyle(editorState).CODE, true);
 });
示例#14
0
export function condenseBlocks (editorState, blocks, options) {
  blocks = blocks || editorState.getCurrentContent().getBlocksAsArray()
  let text = List()
  let characterList = List()

  // Gather all the text/characterList and concat them
  blocks.forEach((block) => {
    // Atomic blocks should be ignored (stripped)
    if (block.getType() !== 'atomic') {
      text = text.push(replaceNewlines(block.getText()))
      characterList = characterList.concat(block.getCharacterList())
    }
  })

  // Strip entities?
  if (options.stripEntities) {
    characterList = characterList.map(stripEntityFromCharacterMetadata)
  }

  // Create a new content block
  const contentBlock = new ContentBlock({
    key: genKey(),
    text: text.join(''),
    type: 'unstyled',
    characterList: characterList,
    depth: 0,
  })

  // Update the editor state with the compressed version
  const newContentState = ContentState.createFromBlockArray([contentBlock])
  // Create the new state as an undoable action
  editorState = EditorState.push(editorState, newContentState, 'remove-range')
  // Move the selection to the end
  return EditorState.moveFocusToEnd(editorState)
}
export default (rawContent, plugins) => {
  const compositeDecorator = createCompositeDecorator(plugins);
  const blocks = convertFromRaw(rawContent);
  return EditorState.createWithContent(
    ContentState.createFromBlockArray(blocks),
    compositeDecorator,
  );
};
示例#16
0
文件: block.test.js 项目: boldr/boldr
 it('should clear editor content', () => {
   expect.assertions(1);
   const { contentBlocks } = convertFromHTML('<h1>aaaaaaaaaa</h1><h1>aaaaaaaaaa</h1>');
   const contentState = ContentState.createFromBlockArray(contentBlocks);
   let editorState = EditorState.createWithContent(contentState);
   editorState = clearEditorContent(editorState);
   expect(editorState.getCurrentContent().getPlainText().length).toEqual(0);
 });
示例#17
0
 componentWillMount () {
   this.props.dispatch(openFile(this.props.filename))
   this.setState({
     editorState: this.props.content ? EditorState.createWithContent(
       ContentState.createFromText(this.props.content)
     ) : EditorState.createEmpty()
   })
 }
const convertHTMLToEditorState = (html: string): Object => {
  const blocksFromHTML = convertFromHTML(html)
  const contentState = ContentState.createFromBlockArray(
    blocksFromHTML.contentBlocks,
    blocksFromHTML.entityMap
  )
  return EditorState.createWithContent(contentState)
}
示例#19
0
}) => (
  html,
  DOMBuilder = getSafeBodyFromHTML
) => {
  return ContentState.createFromBlockArray(
    convertFromHTMLtoContentBlocks(html, htmlToStyle, htmlToEntity, textToEntity, htmlToBlock, DOMBuilder)
  );
};
示例#20
0
/**
 * This function merges contentBlocks into existing article
 * @param {*} contentBlocks - draft ContentBlock
 * @param {*} article - Article to merge data
 */
export default function DraftToJSON(contentState: ContentState, srcArticle: LdJsonDocument) {
  const blockMap = contentState.getBlockMap();
  const filteredBlockMap = filterBlockMap(blockMap);
  const article = mkArticleJson(srcArticle.getElementOfType('Article'), filteredBlockMap); // first pass
  const order = getOrderOffset(article);

  // second pass to create links images and socials
  filteredBlockMap.forEach((element, i) => {
    let entity;
    const findEntityOfType = type => (char) => {
      const entityKey = char.getEntity();
      entity = entityKey ? Entity.get(entityKey) : null;
      return !!entity && entity.getType() === type;
    };
    const mkLink = block => (anchorOffset, focusOffset) => {
      const data = entity.getData();
      const url = data.href;
      const name = data.linkTitle || '';
      const linkText = block.getText().substring(anchorOffset, focusOffset);
      article.mentions.push(getMention(name, '', formatMention(url, linkText, order + i, anchorOffset)));
    };
    const mkImage = block => (anchorOffset) => {
      const data = entity.getData();
      const url = data.src;
      const name = data.title || '';
      const desc = data.description || '';
      article.image.push(getImageObject(`${url}?${order + i},${anchorOffset}`, name, desc));
    };

    const mkSocial = block => (anchorOffset) => {
      const data = entity.getData();
      const url = data.src;
      const desc = data.description || '';
      const title = data.title || '';
      article.hasPart.push(getSocialMediaPosting(url, desc, title));
    };

    const mkTicket = block => (anchorOffset) => {
      const data = entity.getData();
      const url = data.src;
      const desc = data.description || '';
      const title = data.title || '';
      const image = data.image || '';
      article.hasPart.push(getTicket(url, image, desc, title));
    };

    element.el.findEntityRanges(findEntityOfType('LINK'), mkLink(element.el));
    element.el.findEntityRanges(findEntityOfType('IMAGE'), mkImage(element.el));
    element.attached.forEach(e => e.findEntityRanges(findEntityOfType('IMAGE'), mkImage(e)));

    element.el.findEntityRanges(findEntityOfType('SOCIAL'), mkSocial(element.el));
    element.attached.forEach(e => e.findEntityRanges(findEntityOfType('SOCIAL'), mkSocial(e)));

    element.el.findEntityRanges(findEntityOfType('TICKET'), mkTicket(element.el));
    element.attached.forEach(e => e.findEntityRanges(findEntityOfType('TICKET'), mkTicket(e)));
  });
  return article;
}
示例#21
0
 const getContentState = () => {
   if (rawId) {
     const raw = Collections.RawDraftContentStates.findOne(rawId);
     const contentBlocks = convertFromRaw(raw);
     const contentState = ContentState.createFromBlockArray(contentBlocks);
     return contentState;
   }
   return undefined;
 };
示例#22
0
  constructor(props) {
    super(props);
    const blocks = convertFromRaw(this.props.content);
    this.state = {editorState: EditorState.createWithContent(
                      ContentState.createFromBlockArray(blocks)
    )};

    this.onChange = (editorState) => this.setState({editorState});
  }
示例#23
0
 componentWillReceiveProps (nextProps) {
   if (nextProps.filename !== this.props.filename) {
     this.props.dispatch(openFile(nextProps.filename))
   }
   this.setState({
     editorState: nextProps.content ? EditorState.createWithContent(
       ContentState.createFromText(nextProps.content)
     ) : EditorState.createEmpty()
   })
 }
 process(element: DOMElement): ContentState {
   this.processBlockElement(element);
   let contentBlocks = [];
   this.blockList.forEach((block) => {
     let {text, characterMeta} = concatFragments(block.textFragments);
     let includeEmptyBlock = false;
     // If the block contains only a soft break then don't discard the block,
     // but discard the soft break.
     if (text === SOFT_BREAK_PLACEHOLDER) {
       includeEmptyBlock = true;
       text = '';
     }
     if (block.tagName === 'pre') {
       ({text, characterMeta} = trimLeadingNewline(text, characterMeta));
     } else {
       ({text, characterMeta} = collapseWhiteSpace(text, characterMeta));
     }
     // Previously we were using a placeholder for soft breaks. Now that we
     // have collapsed whitespace we can change it back to normal line breaks.
     text = text.split(SOFT_BREAK_PLACEHOLDER).join('\n');
     // Discard empty blocks (unless otherwise specified).
     if (text.length || includeEmptyBlock) {
       contentBlocks.push(
         new ContentBlock({
           key: genKey(),
           text: text,
           type: block.type,
           characterList: characterMeta.toList(),
           depth: block.depth,
           data: block.data ? Map(block.data) : Map(),
         }),
       );
     }
   });
   if (!contentBlocks.length) {
     contentBlocks = [EMPTY_BLOCK];
   }
   return ContentState.createFromBlockArray(
     contentBlocks,
     this.contentStateForEntities.getEntityMap(),
   );
 }
示例#25
0
  constructor (props) {
    super(props)

    this.state = {
      editorState: EditorState.createWithContent(
        ContentState.createFromText(this.props.nodeId),
        createHighlightDecorator()
      ),
      suggestions: mentions
    }
  }
 constructor(options: Options = {}) {
   this.options = options;
   this.contentStateForEntities = ContentState.createFromBlockArray([]);
   // This represents the hierarchy as we traverse nested elements; for
   // example [body, ul, li] where we must know li's parent type (ul or ol).
   this.blockStack = [];
   // This is a linear list of blocks that will form the output; for example
   // [p, li, li, blockquote].
   this.blockList = [];
   this.depth = 0;
 }
示例#27
0
 constructor(props) {
   super(props);
   this.state = {
     editorState: EditorState.createWithContent(ContentState.createFromText(props.content))
   };
   this.focus = () => this.refs.editor.focus();
   this.onChange = (editorState) => this.setState({ editorState });
   this.handleKeyCommand = (command) => this.onHandleKeyCommand(command);
   this.toggleBlockType = (type) => this.onToggleBlockType(type);
   this.toggleInlineStyle = (style) => this.onToggleInlineStyle(style);
   this.saveContent = () => this.onSaveContent();
 }
示例#28
0
/**
 * @name getInitialContent
 * @param {Object} ctrl Controller hosting the editor
 * @returns {ContentState} DraftJS ContentState object.
 * @description Gets the initial content state of the editor based on available information.
 * If an editor state is available as saved in the DB, we use that, otherwise we attempt to
 * use available HTML. If none are available, an empty ContentState is created.
 */
function getInitialContent(ctrl) {
    // we have an editor state stored in the DB
    if (typeof ctrl.editorState === 'object') {
        return convertFromRaw(ctrl.editorState);
    }

    // we have only HTML (possibly legacy editor2 or ingested item)
    if (ctrl.value) {
        return fromHTML(ctrl.value);
    }

    return ContentState.createFromText('');
}
示例#29
0
文件: block.test.js 项目: boldr/boldr
test('should add new unstyles block when insertNewUnstyledBlock is called', () => {
  expect.assertions(1);
  const contentBlocks = convertFromHTML('<h1>aaaaaaaaaa</h1>');
  const contentState = ContentState.createFromBlockArray(contentBlocks);
  let editorState = EditorState.createWithContent(contentState);
  const updatedSelection = editorState.getSelection().merge({
    anchorOffset: 0,
    focusOffset: 10,
  });
  editorState = EditorState.acceptSelection(editorState, updatedSelection);
  editorState = insertNewUnstyledBlock(editorState);
  expect(getAllBlocks(editorState).size).toEqual(2);
});
示例#30
0
	constructor(props) {
		super(props);

		this.handleSubmit = this.handleSubmit.bind(this);
		this.onImageDrop = this.onImageDrop.bind(this);
		this.handleImageUpload = this.handleImageUpload.bind(this);

		let pkey = this.props.match.params.pkey;
		let providers = this.props.providers;
		let objectKey = Object.keys(providers).filter((current) => providers[current].id === pkey);
		let provider = providers[objectKey];
		let desc = provider.desc;
		let state;

		if ( desc ) {
			const blocksFromHTML = htmlToDraft(desc);
			state = ContentState.createFromBlockArray(
				blocksFromHTML.contentBlocks,
				blocksFromHTML.entityMap,
			);
		} else {
			const blocksFromHTML = htmlToDraft('<p>Provider Description</p>');
			state = ContentState.createFromBlockArray(
				blocksFromHTML.contentBlocks,
				blocksFromHTML.entityMap,
			);
		}

		this.state = {
			uploadedFileCloudinaryUrl: '',
			editorState: EditorState.createWithContent(
				state,
			),
		}

		this.focus = () => this.refs.editor.focus();
    this.onChange = (editorState) => this.setState({editorState});
	}