Skip to content
Snippets Groups Projects
Verified Commit 46b5896a authored by Loïs Poujade's avatar Loïs Poujade
Browse files

Separate xywh & time fragment selectors

handle both fragment selectors types:
- target: https://ressource.url#xywh=0,0,10,10&t=19,20
- target: https..., selectors: [ FragmentSelector: ..., ]
parent a4867fc0
No related branches found
No related tags found
No related merge requests found
...@@ -8,6 +8,7 @@ function createSubject(args = {}) { ...@@ -8,6 +8,7 @@ function createSubject(args = {}) {
id: 'id', id: 'id',
svg: 'svg', svg: 'svg',
tags: ['tags'], tags: ['tags'],
timing: [1, 3],
xywh: 'xywh', xywh: 'xywh',
...args, ...args,
}); });
...@@ -20,26 +21,31 @@ describe('WebAnnotation', () => { ...@@ -20,26 +21,31 @@ describe('WebAnnotation', () => {
['body', 'canvasId', 'id', 'svg', 'xywh'].forEach((prop) => { ['body', 'canvasId', 'id', 'svg', 'xywh'].forEach((prop) => {
expect(subject[prop]).toBe(prop); expect(subject[prop]).toBe(prop);
}); });
expect(subject.timing).toStrictEqual([1, 3]);
}); });
}); });
describe('target', () => { describe('target', () => {
it('with svg and xywh', () => { it('with svg, xywh and timing', () => {
expect(subject.target()).toEqual({ expect(subject.target()).toEqual({
selector: [ selector: [
{
type: 'SvgSelector',
value: 'svg',
},
{ {
type: 'FragmentSelector', type: 'FragmentSelector',
value: 'xywh=xywh', value: 'xywh=xywh',
}, },
{ {
type: 'SvgSelector', type: 'FragmentSelector',
value: 'svg', value: 't=1,3',
}, },
], ],
source: 'canvasId', source: 'canvasId',
}); });
}); });
it('with svg only', () => { it('with svg only', () => {
subject = createSubject({ xywh: null }); subject = createSubject({ timing: null, xywh: null });
expect(subject.target()).toEqual({ expect(subject.target()).toEqual({
selector: { selector: {
type: 'SvgSelector', type: 'SvgSelector',
...@@ -49,7 +55,7 @@ describe('WebAnnotation', () => { ...@@ -49,7 +55,7 @@ describe('WebAnnotation', () => {
}); });
}); });
it('with xywh only', () => { it('with xywh only', () => {
subject = createSubject({ svg: null }); subject = createSubject({ svg: null, timing: null });
expect(subject.target()).toEqual({ expect(subject.target()).toEqual({
selector: { selector: {
type: 'FragmentSelector', type: 'FragmentSelector',
...@@ -58,8 +64,18 @@ describe('WebAnnotation', () => { ...@@ -58,8 +64,18 @@ describe('WebAnnotation', () => {
source: 'canvasId', source: 'canvasId',
}); });
}); });
it('with no xywh or svg', () => { it('with timing only', () => {
subject = createSubject({ svg: null, xywh: null }); subject = createSubject({ svg: null, xywh: null });
expect(subject.target()).toEqual({
selector: {
type: 'FragmentSelector',
value: 't=1,3',
},
source: 'canvasId',
});
});
it('with no xywh, svg or timing', () => {
subject = createSubject({ svg: null, timing: null, xywh: null });
expect(subject.target()).toBe('canvasId'); expect(subject.target()).toBe('canvasId');
}); });
}); });
......
...@@ -33,8 +33,9 @@ import CursorIcon from './icons/Cursor'; ...@@ -33,8 +33,9 @@ import CursorIcon from './icons/Cursor';
/** Extract time information from annotation target */ /** Extract time information from annotation target */
function timeFromAnnoTarget(annotarget) { function timeFromAnnoTarget(annotarget) {
console.info('TODO proper time extraction from: ', annotarget);
// TODO w3c media fragments: t=,10 t=5, // TODO w3c media fragments: t=,10 t=5,
const r = /t=([0-9]+),([0-9]+)/.exec(annotarget); const r = /t=([0-9.]+),([0-9.]+)/.exec(annotarget);
if (!r || r.length !== 3) { if (!r || r.length !== 3) {
return ['', '']; return ['', ''];
} }
...@@ -43,13 +44,12 @@ function timeFromAnnoTarget(annotarget) { ...@@ -43,13 +44,12 @@ function timeFromAnnoTarget(annotarget) {
/** Extract xywh from annotation target */ /** Extract xywh from annotation target */
function geomFromAnnoTarget(annotarget) { function geomFromAnnoTarget(annotarget) {
console.warn('TODO proper extraction'); console.info('TODO proper xywh extraction from: ', annotarget);
const r = /xywh=((-?[0-9]+,?)+)/.exec(annotarget); const r = /xywh=((-?[0-9]+,?)+)/.exec(annotarget);
console.info('extracted from ', annotarget, r);
if (!r || r.length !== 3) { if (!r || r.length !== 3) {
return ['', '']; return '';
} }
return [r[1], r[2]]; return r[1];
} }
/** */ /** */
...@@ -88,12 +88,12 @@ class AnnotationCreation extends Component { ...@@ -88,12 +88,12 @@ class AnnotationCreation extends Component {
}); });
} else { } else {
annoState.svg = props.annotation.target.selector.value; annoState.svg = props.annotation.target.selector.value;
// eslint-disable-next-line max-len // TODO does this happen ? when ? where are fragments selectors ?
[annoState.tstart, annoState.tend] = timeFromAnnoTarget(props.annotation.target.selector.value);
} }
} else if (typeof props.annotation.target === 'string') {
annoState.xywh = geomFromAnnoTarget(props.annotation.target);
[annoState.tstart, annoState.tend] = timeFromAnnoTarget(props.annotation.target);
} }
//
// start/end time
} }
const toolState = { const toolState = {
...@@ -196,10 +196,7 @@ class AnnotationCreation extends Component { ...@@ -196,10 +196,7 @@ class AnnotationCreation extends Component {
const { const {
annoBody, tags, xywh, svg, tstart, tend, textEditorStateBustingKey, annoBody, tags, xywh, svg, tstart, tend, textEditorStateBustingKey,
} = this.state; } = this.state;
let fsel = xywh; const timing = (tstart && tend) ? [tstart, tend] : null;
if (tstart && tend) {
fsel = `${xywh || ''}&t=${tstart},${tend}`;
}
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({
...@@ -209,7 +206,8 @@ class AnnotationCreation extends Component { ...@@ -209,7 +206,8 @@ class AnnotationCreation extends Component {
manifestId: canvas.options.resource.id, manifestId: canvas.options.resource.id,
svg, svg,
tags, tags,
xywh: fsel, timing,
xywh,
}).toJson(); }).toJson();
if (annotation) { if (annotation) {
storageAdapter.update(anno).then((annoPage) => { storageAdapter.update(anno).then((annoPage) => {
......
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
export default class WebAnnotation { export default class WebAnnotation {
/** */ /** */
constructor({ constructor({
canvasId, id, xywh, body, tags, svg, manifestId, canvasId, id, xywh, timing, body, tags, svg, manifestId,
}) { }) {
this.id = id; this.id = id;
this.canvasId = canvasId; this.canvasId = canvasId;
this.xywh = xywh; this.xywh = xywh;
this.timing = timing;
this.body = body; this.body = body;
this.tags = tags; this.tags = tags;
this.svg = svg; this.svg = svg;
...@@ -48,33 +49,33 @@ export default class WebAnnotation { ...@@ -48,33 +49,33 @@ export default class WebAnnotation {
/** */ /** */
target() { target() {
let target = this.canvasId; if (!this.svg && !this.xywh && !this.timing) {
if (this.svg || this.xywh) { return this.canvasId;
target = { }
const selectors = [];
const target = {
source: this.source(), source: this.source(),
}; };
}
if (this.svg) { if (this.svg) {
target.selector = { selectors.push({
type: 'SvgSelector', type: 'SvgSelector',
value: this.svg, value: this.svg,
}; });
} }
if (this.xywh) { if (this.xywh) {
const fragsel = { selectors.push({
type: 'FragmentSelector', type: 'FragmentSelector',
value: `xywh=${this.xywh}`, value: `xywh=${this.xywh}`,
}; });
if (target.selector) {
// add fragment selector
target.selector = [
fragsel,
target.selector,
];
} else {
target.selector = fragsel;
} }
if (this.timing) {
const [start, end] = this.timing;
selectors.push({
type: 'FragmentSelector',
value: `t=${start},${end}`,
});
} }
target.selector = selectors.length === 1 ? selectors[0] : selectors;
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