import Vue from 'vue';
Vue.use(require('vue-shortkey'));
import annotationMixin from './mixin.js';
import HTTP from './http.js';
Vue.component('annotator', {
template: '
\
{{ r.word }}\
',
props: {
'labels': Array, // [{id: Integer, color: String, text: String}]
'text': String,
'entityPositions': Array, //[{'startOffset': 10, 'endOffset': 15, 'label_id': 1}]
},
data() {
return {
startOffset: 0,
endOffset: 0,
}
},
methods: {
setSelectedRange: function (e) {
if (window.getSelection) {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(this.$el);
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
var end = start + range.toString().length;
} else if (document.selection && document.selection.type != 'Control') {
var selectedTextRange = document.selection.createRange();
var preSelectionTextRange = document.body.createTextRange();
preSelectionTextRange.moveToElementText(this.$el);
preSelectionTextRange.setEndPoint('EndToStart', selectedTextRange);
var start = preSelectionTextRange.text.length;
var end = start + selectedTextRange.text.length;
}
this.startOffset = start;
this.endOffset = end;
console.log(start, end);
},
validRange: function () {
if (this.startOffset == this.endOffset) {
return false
} else if (this.startOffset > this.text.length || this.endOffset > this.text.length) {
return false
} else if (this.startOffset < 0 || this.endOffset < 0) {
return false
} else {
return true
}
},
resetRange: function () {
this.startOffset = 0;
this.endOffset = 0
},
addLabel: function (label_id) {
if (this.validRange()) {
var label = {
start_offset: this.startOffset,
end_offset: this.endOffset,
label_id: label_id
};
this.entityPositions.push(label);
return label
}
},
deleteLabel: function (index) {
this.$emit('delete-label', index);
this.entityPositions.splice(index, 1)
},
getBackgroundColor: function (label_id) {
for (var item of this.labels) {
if (item.id == label_id) {
return item.background_color
}
}
},
getTextColor: function (label_id) {
for (var item of this.labels) {
if (item.id == label_id) {
return item.text_color
}
}
}
},
watch: {
entityPositions: function () {
this.resetRange()
}
},
computed: {
sortedEntityPositions: function () {
return this.entityPositions.sort((a, b) => a.start_offset - b.start_offset)
},
chunks: function () {
var res = [];
var left = 0;
var i = 0;
for (let i in this.sortedEntityPositions) {
var e = this.sortedEntityPositions[i];
var text = this.text.slice(left, e['start_offset']);
res.push({
'word': text,
'color': '',
'background': ''
});
var text = this.text.slice(e['start_offset'], e['end_offset']);
res.push({
'word': text,
'color': this.getTextColor(e.label.id),
'background': this.getBackgroundColor(e.label.id),
'index': i
});
left = e['end_offset'];
}
var text = this.text.slice(left, this.text.length);
res.push({
'word': text,
'color': '',
'background': ''
});
console.log(res);
console.log(this.labels);
console.log(this.entityPositions);
return res
}
}
})
var vm = new Vue({
el: '#mail-app',
delimiters: ['[[', ']]'],
mixins: [annotationMixin],
methods: {
annotate: function (label_id) {
var payload = this.$refs.annotator.addLabel(label_id);
var doc_id = this.items[this.cur].id;
HTTP.post(`docs/${doc_id}/annotations/`, payload).then(response => {
this.items[this.cur]['labels'].push(response.data);
});
this.updateProgress()
}
}
});