mirror of https://github.com/doccano/doccano.git
1 changed files with 0 additions and 195 deletions
Split View
Diff Options
@ -1,195 +0,0 @@ |
|||
<template> |
|||
<div class="highlight-container highlight-container--bottom-labels" @click="open"> |
|||
<entity-item |
|||
v-for="(chunk, i) in chunks" |
|||
:key="i" |
|||
:content="chunk.text" |
|||
:label="chunk.label" |
|||
:color="chunk.color" |
|||
:labels="labels" |
|||
/> |
|||
<v-menu |
|||
v-model="showMenu" |
|||
:position-x="x" |
|||
:position-y="y" |
|||
absolute |
|||
offset-y |
|||
> |
|||
<v-list |
|||
dense |
|||
min-width="150" |
|||
max-height="400" |
|||
class="overflow-y-auto" |
|||
> |
|||
<v-list-item |
|||
v-for="(label, i) in labels" |
|||
:key="i" |
|||
@click="add" |
|||
> |
|||
<v-list-item-content> |
|||
<v-list-item-title v-text="label.name" /> |
|||
</v-list-item-content> |
|||
<v-list-item-action> |
|||
<v-list-item-action-text v-text="label.shortcut" /> |
|||
</v-list-item-action> |
|||
</v-list-item> |
|||
</v-list> |
|||
</v-menu> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import EntityItem from '~/components/molecules/EntityItem' |
|||
|
|||
export default { |
|||
components: { |
|||
EntityItem |
|||
}, |
|||
props: { |
|||
content: { |
|||
type: String, |
|||
default: '', |
|||
required: true |
|||
}, |
|||
labels: { |
|||
type: Array, |
|||
default: () => ([]), |
|||
required: true |
|||
}, |
|||
entities: { |
|||
type: Array, |
|||
default: () => ([]), |
|||
required: true |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
showMenu: false, |
|||
x: 0, |
|||
y: 0, |
|||
start: 0, |
|||
end: 0 |
|||
} |
|||
}, |
|||
computed: { |
|||
sortedEntities() { |
|||
return this.entities.slice().sort((a, b) => a.start_offset - b.start_offset) |
|||
}, |
|||
|
|||
chunks() { |
|||
const chunks = [] |
|||
const entities = this.sortedEntities |
|||
let startOffset = 0 |
|||
for (const entity of entities) { |
|||
// add non-entities to chunks. |
|||
chunks.push({ |
|||
label: null, |
|||
color: null, |
|||
text: this.content.slice(startOffset, entity.start_offset) |
|||
}) |
|||
startOffset = entity.end_offset |
|||
|
|||
// add entities to chunks. |
|||
const label = this.labelObject[entity.label] |
|||
chunks.push({ |
|||
label: label.name, |
|||
color: label.color, |
|||
text: this.content.slice(entity.start_offset, entity.end_offset) |
|||
}) |
|||
} |
|||
// add the rest of text. |
|||
chunks.push({ |
|||
label: null, |
|||
color: null, |
|||
text: this.content.slice(startOffset, this.content.length) |
|||
}) |
|||
return chunks |
|||
}, |
|||
|
|||
labelObject() { |
|||
const obj = {} |
|||
for (const label of this.labels) { |
|||
obj[label.id] = label |
|||
} |
|||
return obj |
|||
} |
|||
}, |
|||
methods: { |
|||
show(e) { |
|||
e.preventDefault() |
|||
this.showMenu = false |
|||
this.x = e.clientX |
|||
this.y = e.clientY |
|||
this.$nextTick(() => { |
|||
this.showMenu = true |
|||
}) |
|||
}, |
|||
add() { |
|||
|
|||
}, |
|||
getSpanInfo() { |
|||
let selection |
|||
// Modern browsers. |
|||
if (window.getSelection) { |
|||
selection = window.getSelection() |
|||
} else if (document.selection) { |
|||
selection = document.selection |
|||
} |
|||
// If nothing is selected. |
|||
if (selection.rangeCount <= 0) { |
|||
return |
|||
} |
|||
const range = selection.getRangeAt(0) |
|||
const preSelectionRange = range.cloneRange() |
|||
preSelectionRange.selectNodeContents(this.$el) |
|||
preSelectionRange.setEnd(range.startContainer, range.startOffset) |
|||
const start = [...preSelectionRange.toString()].length |
|||
const end = start + [...range.toString()].length |
|||
return { start, end } |
|||
}, |
|||
validateSpan(span, entities) { |
|||
if (!span) { |
|||
return false |
|||
} |
|||
if (span.start === span.end) { |
|||
return false |
|||
} |
|||
for (const entity of this.entities) { |
|||
if ((entity.start_offset <= span.start) && (span.start < entity.end_offset)) { |
|||
return false |
|||
} |
|||
if ((entity.start_offset < span.end) && (span.end <= entity.end_offset)) { |
|||
return false |
|||
} |
|||
if ((span.start < entity.start_offset) && (entity.end_offset < span.end)) { |
|||
return false |
|||
} |
|||
} |
|||
return true |
|||
}, |
|||
open(e) { |
|||
const span = this.getSpanInfo() |
|||
const isValid = this.validateSpan(span, this.entities) |
|||
if (isValid) { |
|||
this.show(e) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.highlight-container.highlight-container--bottom-labels { |
|||
align-items: flex-start; |
|||
} |
|||
.highlight-container { |
|||
line-height: 42px!important; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
white-space: pre-wrap; |
|||
cursor: default; |
|||
} |
|||
.highlight-container.highlight-container--bottom-labels .highlight.bottom { |
|||
margin-top: 6px; |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save