Skip to content
Snippets Groups Projects
Commit 9c55503f authored by Robert Casties's avatar Robert Casties
Browse files

handle multiple bodies and target selectors.

multiple bodies for text and tags.
multiple selectors for alternate fragment and svg selectors.
parent c7bedeb3
Branches
No related tags found
No related merge requests found
...@@ -7,6 +7,7 @@ function createSubject(args = {}) { ...@@ -7,6 +7,7 @@ function createSubject(args = {}) {
canvasId: 'canvasId', canvasId: 'canvasId',
id: 'id', id: 'id',
svg: 'svg', svg: 'svg',
tags: ['tags'],
xywh: 'xywh', xywh: 'xywh',
...args, ...args,
}); });
...@@ -22,7 +23,23 @@ describe('WebAnnotation', () => { ...@@ -22,7 +23,23 @@ describe('WebAnnotation', () => {
}); });
}); });
describe('target', () => { describe('target', () => {
it('with svg', () => { it('with svg and xywh', () => {
expect(subject.target()).toEqual({
id: 'canvasId',
selector: [
{
type: 'FragmentSelector',
value: 'xywh=xywh',
},
{
type: 'SvgSelector',
value: 'svg',
},
],
});
});
it('with svg only', () => {
subject = createSubject({ xywh: null });
expect(subject.target()).toEqual({ expect(subject.target()).toEqual({
id: 'canvasId', id: 'canvasId',
selector: { selector: {
...@@ -40,6 +57,36 @@ describe('WebAnnotation', () => { ...@@ -40,6 +57,36 @@ describe('WebAnnotation', () => {
expect(subject.target()).toBe('canvasId'); expect(subject.target()).toBe('canvasId');
}); });
}); });
describe('body', () => {
it('with text and tags', () => {
expect(subject.createBody()).toEqual([
{
type: 'TextualBody',
value: 'body',
},
{
purpose: 'tagging',
type: 'TextualBody',
value: 'tags',
},
]);
});
it('with text only', () => {
subject = createSubject({ tags: null });
expect(subject.createBody()).toEqual({
type: 'TextualBody',
value: 'body',
});
});
it('with tags only', () => {
subject = createSubject({ body: null });
expect(subject.createBody()).toEqual({
purpose: 'tagging',
type: 'TextualBody',
value: 'tags',
});
});
});
describe('toJson', () => { describe('toJson', () => {
it('generates a WebAnnotation', () => { it('generates a WebAnnotation', () => {
expect(subject.toJson().type).toBe('Annotation'); expect(subject.toJson().type).toBe('Annotation');
......
...@@ -9,9 +9,6 @@ import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup'; ...@@ -9,9 +9,6 @@ import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup';
import RectangleIcon from '@material-ui/icons/CheckBoxOutlineBlank'; import RectangleIcon from '@material-ui/icons/CheckBoxOutlineBlank';
import CircleIcon from '@material-ui/icons/RadioButtonUnchecked'; import CircleIcon from '@material-ui/icons/RadioButtonUnchecked';
import PolygonIcon from '@material-ui/icons/Timeline'; import PolygonIcon from '@material-ui/icons/Timeline';
import GestureIcon from '@material-ui/icons/Gesture';
import ClosedPolygonIcon from '@material-ui/icons/ChangeHistory';
import OpenPolygonIcon from '@material-ui/icons/ShowChart';
import FormatColorFillIcon from '@material-ui/icons/FormatColorFill'; import FormatColorFillIcon from '@material-ui/icons/FormatColorFill';
import StrokeColorIcon from '@material-ui/icons/BorderColor'; import StrokeColorIcon from '@material-ui/icons/BorderColor';
import LineWeightIcon from '@material-ui/icons/LineWeight'; import LineWeightIcon from '@material-ui/icons/LineWeight';
...@@ -38,13 +35,33 @@ class AnnotationCreation extends Component { ...@@ -38,13 +35,33 @@ class AnnotationCreation extends Component {
super(props); super(props);
const annoState = {}; const annoState = {};
if (props.annotation) { if (props.annotation) {
if (Array.isArray(props.annotation.body)) {
annoState.tags = [];
props.annotation.body.forEach((body) => {
if (body.purpose === 'tagging') {
annoState.tags.push(body.value);
} else {
annoState.annoBody = body.value;
}
});
} else {
annoState.annoBody = props.annotation.body.value; annoState.annoBody = props.annotation.body.value;
}
if (Array.isArray(props.annotation.target.selector)) {
props.annotation.target.selector.forEach((selector) => {
if (selector.type === 'SvgSelector') {
annoState.svg = selector.value;
} else if (selector.type === 'FragmentSelector') {
annoState.xywh = selector.value.replace('xywh=', '');
}
});
} else {
annoState.svg = props.annotation.target.selector.value; annoState.svg = props.annotation.target.selector.value;
} }
}
this.state = { this.state = {
activeTool: 'cursor', activeTool: 'cursor',
annoBody: '', annoBody: '',
closedMode: 'closed',
colorPopoverOpen: false, colorPopoverOpen: false,
currentColorType: false, currentColorType: false,
fillColor: null, fillColor: null,
...@@ -62,7 +79,6 @@ class AnnotationCreation extends Component { ...@@ -62,7 +79,6 @@ class AnnotationCreation extends Component {
this.updateBody = this.updateBody.bind(this); this.updateBody = this.updateBody.bind(this);
this.updateGeometry = this.updateGeometry.bind(this); this.updateGeometry = this.updateGeometry.bind(this);
this.changeTool = this.changeTool.bind(this); this.changeTool = this.changeTool.bind(this);
this.changeClosedMode = this.changeClosedMode.bind(this);
this.openChooseColor = this.openChooseColor.bind(this); this.openChooseColor = this.openChooseColor.bind(this);
this.openChooseLineWeight = this.openChooseLineWeight.bind(this); this.openChooseLineWeight = this.openChooseLineWeight.bind(this);
this.handleLineWeightSelect = this.handleLineWeightSelect.bind(this); this.handleLineWeightSelect = this.handleLineWeightSelect.bind(this);
...@@ -128,7 +144,9 @@ class AnnotationCreation extends Component { ...@@ -128,7 +144,9 @@ class AnnotationCreation extends Component {
const { const {
annotation, canvases, closeCompanionWindow, receiveAnnotation, config, annotation, canvases, closeCompanionWindow, receiveAnnotation, config,
} = this.props; } = this.props;
const { annoBody, xywh, svg } = this.state; const {
annoBody, tags, xywh, svg,
} = this.state;
canvases.forEach((canvas) => { canvases.forEach((canvas) => {
const storageAdapter = config.annotation.adapter(canvas.id); const storageAdapter = config.annotation.adapter(canvas.id);
const anno = new WebAnnotation({ const anno = new WebAnnotation({
...@@ -136,6 +154,7 @@ class AnnotationCreation extends Component { ...@@ -136,6 +154,7 @@ class AnnotationCreation extends Component {
canvasId: canvas.id, canvasId: canvas.id,
id: (annotation && annotation.id) || `${uuid()}`, id: (annotation && annotation.id) || `${uuid()}`,
svg, svg,
tags,
xywh, xywh,
}).toJson(); }).toJson();
if (annotation) { if (annotation) {
...@@ -161,13 +180,6 @@ class AnnotationCreation extends Component { ...@@ -161,13 +180,6 @@ class AnnotationCreation extends Component {
}); });
} }
/** */
changeClosedMode(e) {
this.setState({
closedMode: e.currentTarget.value,
});
}
/** */ /** */
updateBody(annoBody) { updateBody(annoBody) {
this.setState({ annoBody }); this.setState({ annoBody });
...@@ -188,7 +200,7 @@ class AnnotationCreation extends Component { ...@@ -188,7 +200,7 @@ class AnnotationCreation extends Component {
const { const {
activeTool, colorPopoverOpen, currentColorType, fillColor, popoverAnchorEl, strokeColor, activeTool, colorPopoverOpen, currentColorType, fillColor, popoverAnchorEl, strokeColor,
popoverLineWeightAnchorEl, lineWeightPopoverOpen, strokeWidth, closedMode, annoBody, svg, popoverLineWeightAnchorEl, lineWeightPopoverOpen, strokeWidth, annoBody, svg,
} = this.state; } = this.state;
return ( return (
<CompanionWindow <CompanionWindow
...@@ -201,7 +213,6 @@ class AnnotationCreation extends Component { ...@@ -201,7 +213,6 @@ class AnnotationCreation extends Component {
fillColor={fillColor} fillColor={fillColor}
strokeColor={strokeColor} strokeColor={strokeColor}
strokeWidth={strokeWidth} strokeWidth={strokeWidth}
closed={closedMode === 'closed'}
svg={svg} svg={svg}
updateGeometry={this.updateGeometry} updateGeometry={this.updateGeometry}
windowId={windowId} windowId={windowId}
...@@ -248,9 +259,6 @@ class AnnotationCreation extends Component { ...@@ -248,9 +259,6 @@ class AnnotationCreation extends Component {
<ToggleButton value="polygon" aria-label="add a polygon"> <ToggleButton value="polygon" aria-label="add a polygon">
<PolygonIcon /> <PolygonIcon />
</ToggleButton> </ToggleButton>
<ToggleButton value="freehand" aria-label="free hand polygon">
<GestureIcon />
</ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>
</Paper> </Paper>
</Grid> </Grid>
...@@ -291,27 +299,6 @@ class AnnotationCreation extends Component { ...@@ -291,27 +299,6 @@ class AnnotationCreation extends Component {
<ArrowDropDownIcon /> <ArrowDropDownIcon />
</ToggleButton> </ToggleButton>
</ToggleButtonGroup> </ToggleButtonGroup>
<Divider flexItem orientation="vertical" className={classes.divider} />
{ /* close / open polygon mode only for freehand drawing mode. */
activeTool === 'freehand'
? (
<ToggleButtonGroup
size="small"
value={closedMode}
onChange={this.changeClosedMode}
>
<ToggleButton value="closed">
<ClosedPolygonIcon />
</ToggleButton>
<ToggleButton value="open">
<OpenPolygonIcon />
</ToggleButton>
</ToggleButtonGroup>
)
: null
}
</Grid> </Grid>
</Grid> </Grid>
<Grid container> <Grid container>
......
...@@ -2,23 +2,20 @@ ...@@ -2,23 +2,20 @@
export default class WebAnnotation { export default class WebAnnotation {
/** */ /** */
constructor({ constructor({
canvasId, id, xywh, body, svg, canvasId, id, xywh, body, tags, svg,
}) { }) {
this.id = id; this.id = id;
this.canvasId = canvasId; this.canvasId = canvasId;
this.xywh = xywh; this.xywh = xywh;
this.body = body; this.body = body;
this.tags = tags;
this.svg = svg; this.svg = svg;
} }
/** */ /** */
toJson() { toJson() {
return { return {
body: { body: this.createBody(),
language: 'en',
type: 'TextualBody',
value: this.body,
},
id: this.id, id: this.id,
motivation: 'commenting', motivation: 'commenting',
target: this.target(), target: this.target(),
...@@ -26,20 +23,53 @@ export default class WebAnnotation { ...@@ -26,20 +23,53 @@ export default class WebAnnotation {
}; };
} }
/** */
createBody() {
let bodies = [];
if (this.body) {
bodies.push({
type: 'TextualBody',
value: this.body,
});
}
if (this.tags) {
bodies = bodies.concat(this.tags.map((tag) => ({
purpose: 'tagging',
type: 'TextualBody',
value: tag,
})));
}
if (bodies.length === 1) {
return bodies[0];
}
return bodies;
}
/** */ /** */
target() { target() {
let target = this.canvasId; let target = this.canvasId;
if (this.svg) { if (this.svg) {
target = {}; target = {
target.id = this.canvasId; id: this.canvasId, // should be source, see #25
target.selector = { selector: {
type: 'SvgSelector', type: 'SvgSelector',
value: this.svg, value: this.svg,
},
}; };
return target;
} }
if (this.xywh) { if (this.xywh) {
target += `#xywh=${this.xywh}`; if (target.selector) {
// add fragment selector
target.selector = [
{
type: 'FragmentSelector',
value: `xywh=${this.xywh}`,
},
target.selector,
];
} else {
target = `${this.canvasId}#xywh=${this.xywh}`;
}
} }
return target; return target;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment