// Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. function Annotation(type, id, begin, end) { this.type = type; this.id = id; this.begin = begin; this.end = end; }; Annotation.prototype.length = function() { return this.end - this.begin; }; function AnnotationEditor(parentElement, tokens, annotations) { this.parentElement = parentElement; this.annotations = new Array(); this.tokens = tokens; // Render tokens for (var i = 0, token; token = this.tokens[i++];) { this.parentElement.append("" + token + ""); } // Insert annotation after annotation for (var i = 0, annotation; annotation = annotations[i++];) { this.addAnnotation(annotation); } }; // Annotation Model: // - All annotation indexes are token indexes // - Annotations can contain other annotations. // - Annotations which cross each other or intersect with each other are not allowed // for example A B C D E . AnnotationEditor.prototype.addAnnotation = function(annotation) { // TODO: Do crossing annotation detection and fail if they do! (return false or fail harder!) // Note: // If an annotation span with the same bounds already exist the new annotation // span is placed inside the existing one $(".token").slice(annotation.begin, annotation.end).wrapAll(""); this.annotations.push(annotation); }; AnnotationEditor.prototype.removeAnnotation = function(annotationId) { $("#" + annotationId).unwrap(); }; // Selection handling and navigation depends highly // on the annotation task. There is no default way of // doing it which fits all tasks. // Therefore we should implement a few default tools which // can be registered if required. // Registers a previous and forward key shortcuts to navigate based on span types. // Multiple span types can be passed in and optionally a function to choose a // span to select in case it is ambiguous. AnnotationEditor.prototype.setNavigationBySpanTypeKeys = function(spanType, previousKey, nextKey) { }; // Registers a previous and forward key shortcuts to navigate with the help of a span locator function. AnnotationEditor.prototype.setNavigationByFunctionKeys = function(previousKey, nextKey, spanLocator){ }; // If a user clicks with a mouse on something he expects a reaction // It should be possible to register a function which helps dealing with // such a selection in a default way // e.g. user wants to select a few tokens // e.g. user wants to select a named entity annotation // He likely wants to do both in the same AnnotationEditor instance. // Span type priority could help with this (also for navigation)