Skip to content

Latest commit

 

History

History
195 lines (189 loc) · 9.74 KB

annolet_concept.org

File metadata and controls

195 lines (189 loc) · 9.74 KB

AnnoLet! Web Annotation Tool

The source is written in JavaScript and jQuery 1.7 is used in it. I am trying to make it more scalable and robust, so that it can be easily integrated with other projects.

To run this program call annolet_main() function.


Use of jQuery.noConflict()

To make the program more robust and avoid clash between variables with that of running website jQuery noConflict() is used and normal ‘$’ selector is changed with ‘$j’.

var $j = jQuery.noConflict();

Function annolet_createContainer()

This function creates a continer div which let the users interact with app. When annolet_createContainer is called, it injects CSS stylesheet into <head> element of website to stylize the container and <div id=annolet-container>...</div> whose inner HTML is a list of options inside body.

var annolet_btn;
// function to create annolet controls container
function annolet_createContainer() {
    // appending a CSS stylesheet to head of webpage
    var link = document.createElement('link');
    link.href = "//ba8fbd5823dec19f2a925b874342f02f325c5581.googledrive.com/host/0B0c01D4InsAOflQ0TUhidTJPUTNycmpyR0IwQ2R1RzBnSVE0SVNzLUxPeHcxOEZVM2RISzg/final/control-menu.css?v=" + parseInt(Math.random() * 999); //a random mock version number is added everytime file is called to prevent loading of cached css file by browser.
    link.type = "text/css";
    link.rel = "stylesheet";
    document.getElementsByTagName('head')[0].appendChild(link);

    // appending a div to body of webpage
    var body = document.getElementsByTagName('body')[0];
    var annolet_container = document.createElement('div');
    annolet_container.id = 'annolet-container';
    body.appendChild(annolet_container);
    //injecting html code
    document.getElementById('annolet-container').innerHTML = "<ul class=annolet-tools-menu><span style='border-radius:10px;  color:orange;font-weight:bold;font-family:monospace; font-size:1.3em'>AnnoLet!</span><span style='color:grey;'>|</span><li class=annolet-tools-menu-item id=login-btn>login</li><li class=annolet-tools-menu-item id=addnote_btn onclick='annolet_btn=2;' >annotate</li><li class=annolet-tools-menu-item id=highlight-btn onclick='annolet_btn=1;'>highlight</li><li class=annolet-tools-menu-item id=save-btn>save</li><li class=annolet-tools-menu-item id=exit-btn onclick='annolet_btn=0;'>exit</li></ul>"; //HTML to create a list of options
}

Functions to retrieve and evaluate Xpath of seleceted DOM element

These functions are copied from Mozilla Firebug Opensource Code. Implemented with small changes.

Function anno_getXpath(target)

It returns string containing Xpath of selected element which is passed as an argument called target.

// function to get Xpath to passed element
function anno_getXpathTo(element) {
    if (element.id !== '') {
        return "//*[@id='" + element.id + "']";
    }
    if (element === document.body) {
        return "html/" + element.tagName.toLowerCase();
    } //added 'html/' to generate a valid Xpath even if parent has no ID.
    var ix = 0;
    var siblings = element.parentNode.childNodes;
    for (var i = 0; i < siblings.length; i++) {
        var sibling = siblings[i];
        if (sibling === element) {
            return anno_getXpathTo(element.parentNode) + '/' + element.tagName.toLowerCase() + '[' + (ix + 1) + ']';
        }
        if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {
            ix++;
        }
    }
}

Function anno_getElementByXpath(xpath)

This function returns that element as object whose Xpath is passed as an argument through it.

// function to evaluate element from Xpath
function anno_getElementByXpath(xpath) {
    return document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

Selecting, highlighting and annotating an element

Function annolet_main()

annolet_main() is main function which will on execution calls annolet_createContainer() and monitors document for mouse clicks. On click, clicked element is selected as target which is passed through function annolet_getXpath and returned Xpath is stored in variable xpath. annolet_main() function always check for the current value of annolet_btn whenever user clicks. On the bases of this value, preffered function anno_highlight() for 1 or anno_annotate() for 2 is called.

//main function which will execute other functions
function annolet_main() {
    annolet_createContainer();
    document.onclick = function(event) {
        if (event === undefined) {
            event = window.event;
        } // for IE
        var target = 'target' in event ? event.target : event.srcElement; // for IE
        var root = document.compatMode === 'CSS1Compat' ? document.documentElement : document.body;
        var xpath = anno_getXpathTo(target);        
        if (annolet_btn === 1) {
            anno_highlight(xpath);
        } else if (annolet_btn === 2) {
            console.log('not available'); //for now this function not available
        }
    };
}

Function annolet_pushToStack()

This function will create an object called annolet_obj which will contain username, id, type(annotation or highlighting), content(if annotation is done) and xpath. Everytime user creates annotation or do highlighting, this function will run, so as to assure that all the work done is saved for retreival in future.’type’ is defined to make it easy to build type selective functions in future.

//function to push objects to a stack.
var i = 1; //counter for id
var annolet_stack = []; //object will be pushed to this
function annolet_pushToStack(xpath, anno_content) {
    if (!anno_content) {
        anno_content = null;
    } //initializing anno_content to null if highlighting done.
    var annolet_obj = {
        authorname: 'raghav',
        id: i++,
        type: annolet_btn, //1 for highlight, 2 for annotation.
        content: anno_content, //would be null if highlighting is done only.
        xpath: xpath
    };
    // pushing data to stack
    annolet_stack.push(annolet_obj);
}

Function anno_highlight()

This function takes two arguments as parameters, xpath and function annolet_pushToStack(). Xpath of an element is passed to anno_getElementByXpath(xpath) which returns element in obect form. Then that object is selected using jQuery and using wrapInner() function of jQuery it is wrapped inside <span> with id ‘mark’ and yellow background. Another function that is annolet_pushToStack() creates an object and push it to object array.So it can be saved for future to a server. annolet_pushToStack() will be discussed later.

//function for highlighting element
function anno_highlight(xpath) {
    //if element is already highlighted
    if (anno_getElementByXpath(xpath).id != "mark" || !(anno_getElementByXpath(xpath).id)) {
        //changing background of selected element to yellow.
        $j(anno_getElementByXpath(xpath)).wrapInner("<span id='mark' style='background:yellow;'></span>");
        annolet_pushToStack(xpath);
    } else {
        console.log('highlighted already');
    }
}

Function anno_annotate()

not complete

In this function I will use some functionality of annolet_highlight() function, then another function which will create a div containing textarea. This box will add to fixed div which will slide up. There will be two options in that box, 1.save 2.cancel. On clicking save, the content variable will become equal to the textarea value and then annolet_pushToStack() will be called. Right now there is no method for retrieval of annotations.

function anno_annotate(xpath){
if (anno_getElementByXpath(xpath).id != "mark" || !(anno_getElementByXpath(xpath).id)) {
        //adding orange coloured border around selected part.
        $j(anno_getElementByXpath(xpath)).wrapInner("<span id='mark' style='border:solid 1px orange;'></span>");
        annolet_pushToStack(xpath);
    } else {
        console.log('highlighted already');
    }
}