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.
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();
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
}
These functions are copied from Mozilla Firebug Opensource Code. Implemented with small changes.
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++;
}
}
}
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;
}
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
}
};
}
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);
}
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');
}
}
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');
}
}