parent
2852d0c67c
commit
9cb80ca6a4
|
@ -5,6 +5,11 @@ import { TrashIcon } from '../Icons';
|
||||||
import setPosition from './setPosition';
|
import setPosition from './setPosition';
|
||||||
import i18n from '../i18n';
|
import i18n from '../i18n';
|
||||||
|
|
||||||
|
/** Shorthand **/
|
||||||
|
const toArray = body =>
|
||||||
|
Array.isArray(body) ? body : [ body ];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The popup editor component.
|
* The popup editor component.
|
||||||
*
|
*
|
||||||
|
@ -27,26 +32,27 @@ export default class Editor extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(next) {
|
componentWillReceiveProps(next) {
|
||||||
if (this.props.annotation != next.annotation) {
|
this.setState({ currentAnnotation: next.annotation });
|
||||||
this.setState({ currentAnnotation: next.annotation });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.modifiedTarget != next.modifiedTarget) {
|
if (this.props.modifiedTarget != next.modifiedTarget) {
|
||||||
const { currentAnnotation } = this.state;
|
// Update in case target was changed (move, resize)
|
||||||
if (currentAnnotation)
|
if (this.state.currentAnnotation) {
|
||||||
this.updateCurrentAnnotation({ target: this.props.modifiedTarget });
|
this.updateCurrentAnnotation({ target: this.props.modifiedTarget });
|
||||||
}
|
|
||||||
|
|
||||||
// Change editor position if element has moved
|
// Change editor position if element has moved
|
||||||
this.removeObserver && this.removeObserver();
|
this.removeObserver && this.removeObserver();
|
||||||
this.removeObserver = this.initResizeObserver();
|
this.removeObserver = this.initResizeObserver();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
// Init observer (triggers setPosition once)
|
||||||
this.removeObserver = this.initResizeObserver();
|
this.removeObserver = this.initResizeObserver();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
// Remove the observer
|
||||||
this.removeObserver && this.removeObserver();
|
this.removeObserver && this.removeObserver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +66,7 @@ export default class Editor extends Component {
|
||||||
resizeObserver.observe(this.props.wrapperEl);
|
resizeObserver.observe(this.props.wrapperEl);
|
||||||
return () => resizeObserver.disconnect();
|
return () => resizeObserver.disconnect();
|
||||||
} else {
|
} else {
|
||||||
// Fire setPosition *only* for devices that don't support ResizeObserver
|
// Fire setPosition manually *only* for devices that don't support ResizeObserver
|
||||||
if (!this.state.dragged)
|
if (!this.state.dragged)
|
||||||
setPosition(this.props.wrapperEl, this.element.current, this.props.selectedElement);
|
setPosition(this.props.wrapperEl, this.element.current, this.props.selectedElement);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +91,7 @@ export default class Editor extends Component {
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shorthand
|
/** Shorthand **/
|
||||||
updateCurrentAnnotation = (diff, saveImmediately) => {
|
updateCurrentAnnotation = (diff, saveImmediately) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
currentAnnotation: this.state.currentAnnotation.clone(diff)
|
currentAnnotation: this.state.currentAnnotation.clone(diff)
|
||||||
|
@ -95,12 +101,14 @@ export default class Editor extends Component {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shorthand
|
/**
|
||||||
toArray = body =>
|
* Appends a body to the current annotation. For convenience: also
|
||||||
Array.isArray(body) ? body : [ body ];
|
* takes an array of bodies as argument.
|
||||||
|
* @param bodyOrBodies the body or list of bodies to append
|
||||||
|
* @param saveImmediately set to true to save & close immediately
|
||||||
|
*/
|
||||||
onAppendBody = (bodyOrBodies, saveImmediately) => {
|
onAppendBody = (bodyOrBodies, saveImmediately) => {
|
||||||
const toAppend = this.toArray(bodyOrBodies).map(b =>
|
const toAppend = toArray(bodyOrBodies).map(b =>
|
||||||
({ ...b, ...this.creationMeta(b) }));
|
({ ...b, ...this.creationMeta(b) }));
|
||||||
|
|
||||||
this.updateCurrentAnnotation({
|
this.updateCurrentAnnotation({
|
||||||
|
@ -108,6 +116,12 @@ export default class Editor extends Component {
|
||||||
}, saveImmediately);
|
}, saveImmediately);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a previous body with the given body.
|
||||||
|
* @param previous the body to replace
|
||||||
|
* @param updated the body to replace with
|
||||||
|
* @param saveImmediately set to true to save & close immediately
|
||||||
|
*/
|
||||||
onUpdateBody = (previous, updated, saveImmediately) => {
|
onUpdateBody = (previous, updated, saveImmediately) => {
|
||||||
this.updateCurrentAnnotation({
|
this.updateCurrentAnnotation({
|
||||||
body: this.state.currentAnnotation.bodies.map(body =>
|
body: this.state.currentAnnotation.bodies.map(body =>
|
||||||
|
@ -115,16 +129,10 @@ export default class Editor extends Component {
|
||||||
}, saveImmediately);
|
}, saveImmediately);
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemoveBody = (bodyOrBodies, saveImmediately) => {
|
/**
|
||||||
const toRemove = this.toArray(bodyOrBodies);
|
* For convenience: an 'append or update' shorthand.
|
||||||
|
*/
|
||||||
this.updateCurrentAnnotation({
|
onUpsertBody = (arg1, arg2, saveImmediately) => {
|
||||||
body: this.state.currentAnnotation.bodies.filter(b => !toRemove.includes(b))
|
|
||||||
}, saveImmediately);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A convenience shorthand **/
|
|
||||||
onUpsertBody = (arg1, arg2, saveImmediately) => {
|
|
||||||
if (arg1 == null && arg2 != null) {
|
if (arg1 == null && arg2 != null) {
|
||||||
// Append arg 2 as a new body
|
// Append arg 2 as a new body
|
||||||
this.onAppendBody(arg2, saveImmediately);
|
this.onAppendBody(arg2, saveImmediately);
|
||||||
|
@ -142,6 +150,42 @@ export default class Editor extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given body from the current annotation. For
|
||||||
|
* convenience: also takes an array of bodies as argument.
|
||||||
|
* @param bodyOrBodies the body or list of bodies to remove
|
||||||
|
* @param saveImmediately set to true to save & close immediately
|
||||||
|
*/
|
||||||
|
onRemoveBody = (bodyOrBodies, saveImmediately) => {
|
||||||
|
const toRemove = toArray(bodyOrBodies);
|
||||||
|
|
||||||
|
this.updateCurrentAnnotation({
|
||||||
|
body: this.state.currentAnnotation.bodies.filter(b => !toRemove.includes(b))
|
||||||
|
}, saveImmediately);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For convenience: removes and appends one or more bodies
|
||||||
|
* in one go, optionally saving immediately.
|
||||||
|
*/
|
||||||
|
onRemoveAndAppend = (bodyOrBodiesToRemove, bodyOrBodiesToAppend, saveImmediately) => {
|
||||||
|
const toRemove = toArray(bodyOrBodiesToRemove);
|
||||||
|
const toAppend = toArray(bodyOrBodiesToAppend).map(b =>
|
||||||
|
({ ...b, ...this.creationMeta(b) }));
|
||||||
|
|
||||||
|
this.updateCurrentAnnotation({
|
||||||
|
body: [
|
||||||
|
...this.state.currentAnnotation.bodies.filter(b => !toRemove.includes(b)),
|
||||||
|
...toAppend
|
||||||
|
]
|
||||||
|
}, saveImmediately);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the given property value at the top level of the annotation.
|
||||||
|
* @param property property key
|
||||||
|
* @param value property value - set to null to delete the property
|
||||||
|
*/
|
||||||
onSetProperty = (property, value) => {
|
onSetProperty = (property, value) => {
|
||||||
// A list of properties the user is NOT allowed to set
|
// A list of properties the user is NOT allowed to set
|
||||||
const isForbidden = [ '@context', 'id', 'type', 'body', 'target' ].includes(property);
|
const isForbidden = [ '@context', 'id', 'type', 'body', 'target' ].includes(property);
|
||||||
|
@ -150,18 +194,18 @@ export default class Editor extends Component {
|
||||||
throw new Exception(`Cannot set ${property} - not allowed`);
|
throw new Exception(`Cannot set ${property} - not allowed`);
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
this.updateCurrentAnnotation({ [property]: value });
|
this.updateCurrentAnnotation({ [ property ]: value });
|
||||||
} else {
|
} else {
|
||||||
const updated = this.currentAnnotation.clone();
|
const updated = this.currentAnnotation.clone();
|
||||||
delete updated[property];
|
delete updated[ property ];
|
||||||
this.setState({ currentAnnotation: updated });
|
this.setState({ currentAnnotation: updated });
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
onCancel = () =>
|
onCancel = () =>
|
||||||
this.props.onCancel(this.props.annotation);
|
this.props.onCancel(this.props.annotation);
|
||||||
|
|
||||||
onOk = _ => {
|
onOk = () => {
|
||||||
// Removes the state payload from all bodies
|
// Removes the state payload from all bodies
|
||||||
const undraft = annotation =>
|
const undraft = annotation =>
|
||||||
annotation.clone({
|
annotation.clone({
|
||||||
|
@ -172,7 +216,7 @@ export default class Editor extends Component {
|
||||||
|
|
||||||
// Current annotation is either a selection (if it was created from
|
// Current annotation is either a selection (if it was created from
|
||||||
// scratch just now) or an annotation (if it existed already and was
|
// scratch just now) or an annotation (if it existed already and was
|
||||||
// opened for editing)
|
// selected for editing)
|
||||||
if (currentAnnotation.bodies.length === 0 && !this.props.allowEmpty) {
|
if (currentAnnotation.bodies.length === 0 && !this.props.allowEmpty) {
|
||||||
if (currentAnnotation.isSelection)
|
if (currentAnnotation.isSelection)
|
||||||
onCancel();
|
onCancel();
|
||||||
|
@ -184,7 +228,7 @@ export default class Editor extends Component {
|
||||||
else
|
else
|
||||||
this.props.onAnnotationUpdated(undraft(currentAnnotation), this.props.annotation);
|
this.props.onAnnotationUpdated(undraft(currentAnnotation), this.props.annotation);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
onDelete = () =>
|
onDelete = () =>
|
||||||
this.props.onAnnotationDeleted(this.props.annotation);
|
this.props.onAnnotationDeleted(this.props.annotation);
|
||||||
|
@ -229,6 +273,7 @@ export default class Editor extends Component {
|
||||||
onUpdateBody: this.onUpdateBody,
|
onUpdateBody: this.onUpdateBody,
|
||||||
onRemoveBody: this.onRemoveBody,
|
onRemoveBody: this.onRemoveBody,
|
||||||
onUpsertBody: this.onUpsertBody,
|
onUpsertBody: this.onUpsertBody,
|
||||||
|
onRemoveAndAppend: this.onRemoveAndAppend,
|
||||||
onSetProperty: this.onSetProperty,
|
onSetProperty: this.onSetProperty,
|
||||||
onSaveAndClose: this.onOk
|
onSaveAndClose: this.onOk
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue