application/components/common/rich-editor2/plugins/anchor.js
- import React from "react";
- import Dialog from "material-ui/Dialog";
- import TextField from "material-ui/TextField";
- import CheckBox from "material-ui/Checkbox";
- import FlatButton from "material-ui/FlatButton";
- import RaisedButton from "material-ui/RaisedButton";
- import ToolbarButton from "../common/toolbar-button";
-
- export const SERIALIZER_RULES = [
- {
- deserialize(el, next) {
- if (el.tagName.toLowerCase() == "a") {
- const href = el.getAttribute("href");
- const target = el.getAttribute("target")
- ? el.getAttribute("target")
- : "";
-
- return {
- object: "inline",
- type: "anchor",
- nodes: next(el.childNodes),
- data: {
- href: href,
- target: target,
- },
- };
- }
- },
- serialize(obj, children) {
- if (obj.object == "inline" && obj.type == "anchor") {
- return (
- <a
- href={obj.data.get("href")}
- target={obj.data.get("target")}
- >
- {children}
- </a>
- );
- }
- },
- },
- ];
-
- class AnchorButton extends ToolbarButton {
- handleOnClick(e) {
- return anchorClickHandler.call(this.props.editor, e);
- }
-
- getLabel() {
- return <i className="fa fa-link"></i>;
- }
- }
-
- class AnchorNode extends React.Component {
- constructor(props) {
- super(props);
-
- this.parentEditor = this.props.editor;
- }
-
- render() {
- const { data } = this.props.node;
-
- const handleClick = (e) => {
- e.preventDefault();
-
- // open the modal and store the anchor data
- this.props.editor.setState({
- myAnchorModalOpen: true,
- myAnchorData: data,
- });
- };
- return (
- <a
- {...this.props.attributes}
- href={data.get("href")}
- target={data.get("target")}
- onClick={handleClick}
- >
- {this.props.children}
- </a>
- );
- }
- }
-
- function anchorClickHandler(e, defaultUrl = "") {
- const { editor } = this;
- const { editorContent } = this.state;
- const hasLinks = this.hasInline("anchor");
-
- if (hasLinks) {
- // user highlighted a link and clicked the button, so remove the link
- editor.unwrapInline("anchor");
- } else if (editorContent.selection.isExpanded) {
- // open the modal
- editor.setState({ myAnchorModalOpen: true });
- return;
- }
- }
-
- class AnchorModal extends React.Component {
- constructor(props) {
- super(props);
-
- this.state = {
- url: "",
- newWindow: false,
- };
- }
-
- closeModal() {
- this.props.editor.setState({
- myAnchorModalOpen: false,
- myAnchorData: null,
- });
- this.setState({
- url: "",
- newWindow: false,
- });
- }
-
- handleCancel(e) {
- this.closeModal.call(this);
- }
-
- componentWillReceiveProps(newProps) {
- if (newProps.editor && newProps.editor.state.myAnchorData) {
- this.setState({
- url: newProps.editor.state.myAnchorData.get("href"),
- newWindow:
- newProps.editor.state.myAnchorData.get("target") == "_blank"
- ? true
- : false,
- });
- }
- }
-
- handleSave(e) {
- let useUrl = this.state.url;
- if (useUrl.substring(useUrl.length - 1, useUrl.length) === "\\") {
- useUrl = useUrl.substring(0, useUrl.length - 1);
- }
-
- // remove any existing links, expand the selection then replace the URL
- // if it's set
- this.props.editor
- .focus()
- .moveAnchorToStartOfInline()
- .moveFocusToEndOfInline()
- .unwrapInline("anchor")
- .wrapInline({
- type: "anchor",
- data: {
- href: useUrl,
- target: this.state.newWindow ? "_blank" : "",
- },
- });
- this.props.editor.moveToEnd();
-
- setTimeout(() => {
- this.closeModal.call(this);
- }, 250);
- }
-
- updateUrl(e) {
- this.setState({
- url: e.target.value,
- });
- }
-
- updateTarget(e, checked) {
- this.setState({
- newWindow: checked,
- });
- }
-
- handleKeyPress(e) {
- if (e.key == "Enter") {
- this.handleSave.call(this, e);
- }
- }
-
- render() {
- const buttons = [
- <FlatButton
- label="Cancel"
- onClick={this.handleCancel.bind(this)}
- />,
- <RaisedButton
- label="Save"
- onClick={this.handleSave.bind(this)}
- primary={true}
- />,
- ];
-
- return (
- <Dialog
- modal={true}
- actions={buttons}
- title="Edit Link"
- open={this.props.editor.state.myAnchorModalOpen ? true : false}
- >
- <TextField
- floatingLabelText="URL"
- value={this.state.url}
- onChange={this.updateUrl.bind(this)}
- onKeyPress={this.handleKeyPress.bind(this)}
- fullWidth={true}
- />
- <CheckBox
- label="Open in new window"
- labelPosition="right"
- checked={this.state.newWindow}
- onCheck={this.updateTarget.bind(this)}
- />
- </Dialog>
- );
- }
- }
-
- function AnchorPlugin(options) {
- return {
- renderEditor(props, editor, next) {
- const children = next();
- return (
- <React.Fragment>
- {children}
- <AnchorModal editor={editor} />
- </React.Fragment>
- );
- },
- renderNode(props, editor, next) {
- const { attributes, children } = props;
-
- switch (props.node.type) {
- case "anchor":
- return <AnchorNode {...props} editor={editor} />;
- default:
- return next();
- }
- },
- };
- }
- export { AnchorPlugin, AnchorButton, anchorClickHandler };