Skip to content

Commit

Permalink
Finished extending widget API (issues #65 + #66)
Browse files Browse the repository at this point in the history
  • Loading branch information
rsimon committed Jun 30, 2021
1 parent 2852d0c commit 9cb80ca
Showing 1 changed file with 77 additions and 32 deletions.
109 changes: 77 additions & 32 deletions src/editor/Editor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import { TrashIcon } from '../Icons';
import setPosition from './setPosition';
import i18n from '../i18n';

/** Shorthand **/
const toArray = body =>
Array.isArray(body) ? body : [ body ];


/**
* The popup editor component.
*
Expand All @@ -27,26 +32,27 @@ export default class Editor extends Component {
}

componentWillReceiveProps(next) {
if (this.props.annotation != next.annotation) {
this.setState({ currentAnnotation: next.annotation });
}
this.setState({ currentAnnotation: next.annotation });

if (this.props.modifiedTarget != next.modifiedTarget) {
const { currentAnnotation } = this.state;
if (currentAnnotation)
// Update in case target was changed (move, resize)
if (this.state.currentAnnotation) {
this.updateCurrentAnnotation({ target: this.props.modifiedTarget });
}

// Change editor position if element has moved
this.removeObserver && this.removeObserver();
this.removeObserver = this.initResizeObserver();
// Change editor position if element has moved
this.removeObserver && this.removeObserver();
this.removeObserver = this.initResizeObserver();
}
}
}

componentDidMount() {
// Init observer (triggers setPosition once)
this.removeObserver = this.initResizeObserver();
}

componentWillUnmount() {
// Remove the observer
this.removeObserver && this.removeObserver();
}

Expand All @@ -60,7 +66,7 @@ export default class Editor extends Component {
resizeObserver.observe(this.props.wrapperEl);
return () => resizeObserver.disconnect();
} 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)
setPosition(this.props.wrapperEl, this.element.current, this.props.selectedElement);
}
Expand All @@ -85,7 +91,7 @@ export default class Editor extends Component {
return meta;
}

// Shorthand
/** Shorthand **/
updateCurrentAnnotation = (diff, saveImmediately) => {
this.setState({
currentAnnotation: this.state.currentAnnotation.clone(diff)
Expand All @@ -95,36 +101,38 @@ export default class Editor extends Component {
})
}

// Shorthand
toArray = body =>
Array.isArray(body) ? body : [ body ];

/**
* Appends a body to the current annotation. For convenience: also
* 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) => {
const toAppend = this.toArray(bodyOrBodies).map(b =>
const toAppend = toArray(bodyOrBodies).map(b =>
({ ...b, ...this.creationMeta(b) }));

this.updateCurrentAnnotation({
body: [ ...this.state.currentAnnotation.bodies, ...toAppend ]
}, 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) => {
this.updateCurrentAnnotation({
body: this.state.currentAnnotation.bodies.map(body =>
body === previous ? { ...updated, ...this.creationMeta(updated) } : body)
}, saveImmediately);
}

onRemoveBody = (bodyOrBodies, saveImmediately) => {
const toRemove = this.toArray(bodyOrBodies);

this.updateCurrentAnnotation({
body: this.state.currentAnnotation.bodies.filter(b => !toRemove.includes(b))
}, saveImmediately);
}

/** A convenience shorthand **/
onUpsertBody = (arg1, arg2, saveImmediately) => {
/**
* For convenience: an 'append or update' shorthand.
*/
onUpsertBody = (arg1, arg2, saveImmediately) => {
if (arg1 == null && arg2 != null) {
// Append arg 2 as a new body
this.onAppendBody(arg2, saveImmediately);
Expand All @@ -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) => {
// A list of properties the user is NOT allowed to set
const isForbidden = [ '@context', 'id', 'type', 'body', 'target' ].includes(property);
Expand All @@ -150,18 +194,18 @@ export default class Editor extends Component {
throw new Exception(`Cannot set ${property} - not allowed`);

if (value) {
this.updateCurrentAnnotation({ [property]: value });
this.updateCurrentAnnotation({ [ property ]: value });
} else {
const updated = this.currentAnnotation.clone();
delete updated[property];
delete updated[ property ];
this.setState({ currentAnnotation: updated });
}
};
}

onCancel = () =>
this.props.onCancel(this.props.annotation);

onOk = _ => {
onOk = () => {
// Removes the state payload from all bodies
const undraft = annotation =>
annotation.clone({
Expand All @@ -172,7 +216,7 @@ export default class Editor extends Component {

// Current annotation is either a selection (if it was created from
// 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.isSelection)
onCancel();
Expand All @@ -184,7 +228,7 @@ export default class Editor extends Component {
else
this.props.onAnnotationUpdated(undraft(currentAnnotation), this.props.annotation);
}
};
}

onDelete = () =>
this.props.onAnnotationDeleted(this.props.annotation);
Expand Down Expand Up @@ -229,6 +273,7 @@ export default class Editor extends Component {
onUpdateBody: this.onUpdateBody,
onRemoveBody: this.onRemoveBody,
onUpsertBody: this.onUpsertBody,
onRemoveAndAppend: this.onRemoveAndAppend,
onSetProperty: this.onSetProperty,
onSaveAndClose: this.onOk
})
Expand Down

0 comments on commit 9cb80ca

Please sign in to comment.