Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Annotator release 0.0.7

  • Loading branch information...
commit 0ed245afee8fbe5c7115201344a65bbdce913d26 1 parent 8100135
Nick Stenning nickstenning authored
1  pkg/annotator.min.css
View
@@ -0,0 +1 @@
+.annot-wrapper{position:relative;}.annot-adder a{display:block;width:22px;height:22px;background:transparent url(img/note.png) no-repeat left top;}.annot-adder{position:absolute;display:none;margin:-25px 0 0 3px;}.annot-highlighter{background:rgba(255,255,10,0.3);}.annot-highlighter .hover{border:2px solid #f00;}.annot-editor{position:absolute;width:15em;height:auto;opacity:.95;}.annot-editor textarea{background:#fdf5d8;border:1px solid #e1be94;-moz-border-radius:.3em;-webkit-border-radius:.3em;margin:0;padding:.4em;width:100%;height:100%;}.annot-viewer{position:absolute;width:15em;height:auto;opacity:.95;background:#fdf5d8;border:1px solid #e1be94;-moz-border-radius:.3em;-webkit-border-radius:.3em;margin:2px 0 0 2px;padding:.2em .4em .4em .4em;line-height:16px;}.annot-viewer p{color:#333;font-family:helvetica;font-size:75%;margin:.25em 0 0;}.annot-viewer p+p{border-top:1px solid #E1BE94;padding-top:.25em;}.annot-controls{display:none;float:right;}.annot-viewer:hover .annot-controls{display:block;}.annot-controls a{width:16px;height:16px;display:inline-block;text-indent:-9999em;}.annot-controls a.edit{background:transparent url(img/edit.png) no-repeat top left;}.annot-controls a.del{background:transparent url(img/delete.png) no-repeat top left;}
1  pkg/annotator.min.js
View
@@ -0,0 +1 @@
+(function(a){a.plugin=function(c,b){a.fn[c]=function(e){var d=Array.prototype.slice.call(arguments,1);return this.each(function(){var f=a.data(this,c);if(f){e&&f[e].apply(f,d)}else{if(typeof b==="function"){f=new b(e,this)}else{function g(){}g.prototype=b;f=new g();f.init(e,this)}a.data(this,c,f)}})}}})(jQuery);(function(){var a=false,b=/xyz/.test(function(){xyz})?(/\b_super\b/):(/.*/);this.Class=function(){};Class.extend=function(g){var f=this.prototype;a=true;var e=new this();a=false;for(var d in g){e[d]=typeof g[d]=="function"&&typeof f[d]=="function"&&b.test(g[d])?(function(h,i){return function(){var k=this._super;this._super=f[h];var j=i.apply(this,arguments);this._super=k;return j}})(d,g[d]):g[d]}function c(){if(!a&&this.init){this.init.apply(this,arguments)}}c.prototype=e;c.constructor=c;c.extend=arguments.callee;return c}})();(function($){$.toJSON=function(o){if(typeof(JSON)=="object"&&JSON.stringify){return JSON.stringify(o)}var type=typeof(o);if(o===null){return"null"}if(type=="undefined"){return undefined}if(type=="number"||type=="boolean"){return o+""}if(type=="string"){return $.quoteString(o)}if(type=="object"){if(typeof o.toJSON=="function"){return $.toJSON(o.toJSON())}if(o.constructor===Date){var month=o.getUTCMonth()+1;if(month<10){month="0"+month}var day=o.getUTCDate();if(day<10){day="0"+day}var year=o.getUTCFullYear();var hours=o.getUTCHours();if(hours<10){hours="0"+hours}var minutes=o.getUTCMinutes();if(minutes<10){minutes="0"+minutes}var seconds=o.getUTCSeconds();if(seconds<10){seconds="0"+seconds}var milli=o.getUTCMilliseconds();if(milli<100){milli="0"+milli}if(milli<10){milli="0"+milli}return'"'+year+"-"+month+"-"+day+"T"+hours+":"+minutes+":"+seconds+"."+milli+'Z"'}if(o.constructor===Array){var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i])||"null")}return"["+ret.join(",")+"]"}var pairs=[];for(var k in o){var name;var type=typeof k;if(type=="number"){name='"'+k+'"'}else{if(type=="string"){name=$.quoteString(k)}else{continue}}if(typeof o[k]=="function"){continue}var val=$.toJSON(o[k]);pairs.push(name+":"+val)}return"{"+pairs.join(", ")+"}"}};$.evalJSON=function(src){if(typeof(JSON)=="object"&&JSON.parse){return JSON.parse(src)}return eval("("+src+")")};$.secureEvalJSON=function(src){if(typeof(JSON)=="object"&&JSON.parse){return JSON.parse(src)}var filtered=src;filtered=filtered.replace(/\\["\\\/bfnrtu]/g,"@");filtered=filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]");filtered=filtered.replace(/(?:^|:|,)(?:\s*\[)+/g,"");if(/^[\],:{}\s]*$/.test(filtered)){return eval("("+src+")")}else{throw new SyntaxError("Error parsing JSON, source is not valid.")}};$.quoteString=function(string){if(string.match(_escapeable)){return'"'+string.replace(_escapeable,function(a){var c=_meta[a];if(typeof c==="string"){return c}c=a.charCodeAt();return"\\u00"+Math.floor(c/16).toString(16)+(c%16).toString(16)})+'"'}return'"'+string+'"'};var _escapeable=/["\\\x00-\x1f\x7f-\x9f]/g;var _meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"}})(jQuery);(function(a){this.DelegatorClass=Class.extend({events:{},init:function(){var b=this;a.each(this.events,function(e,d){var c=e.split(" ");b.addDelegatedEvent(c.slice(0,-1).join(" "),c.slice(-1)[0],d)})},addDelegatedEvent:function(e,b,d){var c=this;this.element=this.element||document.body;if(typeof(e)==="string"&&e.replace(/\s+/g,"")===""){e=this.element}a(this.element).bind(b,function(g){for(var f=g.target;f!==c.element.parentNode;f=f.parentNode){if(f===e||a(f).is(e)){return c[d].apply(c,arguments)}}return null})}});a.extend({inject:function(b,d,c){a.each(b,function(e,f){d=c(d,f,e)});return d},flatten:function(b){return a.inject(b,[],function(d,c){return d.concat(a.isArray(c)?a.flatten(c):c)})}});a.fn.textNodes=function(){function b(c){if(c.nodeType!==Node.TEXT_NODE){return a(c).contents().map(function(){return b(this)}).get()}else{return c}}return this.map(function(){return a.flatten(b(this))})};a.fn.xpath=function(b){return this.map(function(){var e="";for(var d=this;d&&d.nodeType==Node.ELEMENT_NODE&&d!==b;d=d.parentNode){var c=a(d.parentNode).children(d.tagName).index(d)+1;c>1?(c="["+c+"]"):(c="");e="/"+d.tagName.toLowerCase()+c+e}return e}).get()}})(jQuery);jQuery.fn.extend({everyTime:function(a,b,c,d){return this.each(function(){jQuery.timer.add(this,a,b,c,d)})},oneTime:function(a,b,c){return this.each(function(){jQuery.timer.add(this,a,b,c,1)})},stopTime:function(a,b){return this.each(function(){jQuery.timer.remove(this,a,b)})}});jQuery.extend({timer:{global:[],guid:1,dataKey:"jQuery.timer",regex:/^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,powers:{ms:1,cs:10,ds:100,s:1000,das:10000,hs:100000,ks:1000000},timeParse:function(c){if(c==undefined||c==null){return null}var a=this.regex.exec(jQuery.trim(c.toString()));if(a[2]){var b=parseFloat(a[1]);var d=this.powers[a[2]]||1;return b*d}else{return c}},add:function(d,b,c,f,h){var a=0;if(jQuery.isFunction(c)){if(!h){h=f}f=c;c=b}b=jQuery.timer.timeParse(b);if(typeof b!="number"||isNaN(b)||b<0){return}if(typeof h!="number"||isNaN(h)||h<0){h=0}h=h||0;var g=jQuery.data(d,this.dataKey)||jQuery.data(d,this.dataKey,{});if(!g[c]){g[c]={}}f.timerID=f.timerID||this.guid++;var e=function(){if((++a>h&&h!==0)||f.call(d,a)===false){jQuery.timer.remove(d,c,f)}};e.timerID=f.timerID;if(!g[c][f.timerID]){g[c][f.timerID]=window.setInterval(e,b)}this.global.push(d)},remove:function(c,b,d){var e=jQuery.data(c,this.dataKey),a;if(e){if(!b){for(b in e){this.remove(c,b,d)}}else{if(e[b]){if(d){if(d.timerID){window.clearInterval(e[b][d.timerID]);delete e[b][d.timerID]}}else{for(var d in e[b]){window.clearInterval(e[b][d]);delete e[b][d]}}for(a in e[b]){break}if(!a){a=null;delete e[b]}}}for(a in e){break}if(!a){jQuery.removeData(c,this.dataKey)}}}}});jQuery(window).bind("unload",function(){jQuery.each(jQuery.timer.global,function(a,b){jQuery.timer.remove(b)})});(function(a){this.Annotator=DelegatorClass.extend({events:{"-adder mousedown":"adderMousedown","-highlighter mouseover":"highlightMouseover","-highlighter mouseout":"startViewerHideTimer","-viewer mouseover":"viewerMouseover","-viewer mouseout":"startViewerHideTimer","-controls .edit click":"controlEditClick","-controls .del click":"controlDeleteClick"},init:function(b,c){var d=this;this.options=a.extend({classPrefix:"annot",adder:"<div><a href='#'></a></div>",editor:"<div><textarea></textarea></div>",highlighter:"<span></span>",viewer:"<div></div>"},b);this.element=c;this.dom={};a(this.element).wrapInner('<div class="'+this.options.classPrefix+'-wrapper" />');this.wrapper=a(this.element).find("."+this.options.classPrefix+"-wrapper").get(0);this.addDelegatedEvent(this.element,"mouseup","checkForEndSelection");this.addDelegatedEvent(this.element,"mousedown","checkForStartSelection");a.each(this.events,function(f,e){if(f.substr(0,1)==="-"){d.events["."+d.options.classPrefix+f]=e;delete d.events[f]}});this._super();a.each(["adder","editor","highlighter","viewer"],function(e,f){d.dom[f]=a(d.options[f]).attr({"class":d.options.classPrefix+"-"+f}).appendTo(d.wrapper).hide()})},checkForStartSelection:function(b){this.startViewerHideTimer();this.mouseIsDown=true},checkForEndSelection:function(b){this.mouseIsDown=false;if(this.ignoreMouseup){this.ignoreMouseup=false;return}this.getSelection();if(b&&this.selection&&this.selection.rangeCount>0&&!this.selection.isCollapsed){this.dom.adder.css(this._mousePosition(b)).show()}else{this.dom.adder.hide()}},getSelection:function(){this.selection=window.getSelection();this.selectedRanges=[];for(var b=0;b<this.selection.rangeCount;b+=1){this.selectedRanges.push(this.selection.getRangeAt(b))}},createAnnotation:function(b){var c=this;b=b||{};b.highlights=b.highlights||[];b.ranges=a.map(b.ranges||this.selectedRanges,function(e){var d,f;if("commonAncestorContainer" in e){d=c.normRange(e);f=c.serializeRange(d)}else{if(("start" in e)&&(typeof e.start=="string")){d=c.deserializeRange(e);f=e}else{d=e;f=c.serializeRange(d)}}b.highlights=b.highlights.concat(c.highlightRange(d));return f});a(b.highlights).data("annotation",b);a(this.element).trigger("annotationCreated",[b]);return b},deleteAnnotation:function(b){a.each(b.highlights,function(){a(this).replaceWith(a(this)[0].childNodes)});a(this.element).trigger("annotationDeleted",[b])},updateAnnotation:function(b,c){a.extend(b,c);a(this.element).trigger("annotationUpdated",[b])},loadAnnotations:function(c){var d=this,b=[];a.each(c,function(){b.push(d.createAnnotation(this))});return b},normRange:function(b){var d={},c={};a.each(["start","end"],function(e,h){var f,g=b[h+"Container"],i=b[h+"Offset"];if(g.nodeType===Node.ELEMENT_NODE){f=g.childNodes[i];g=f||g.childNodes[i-1];while(g.nodeType!==Node.TEXT_NODE){g=g.firstChild}i=f?0:g.nodeValue.length}d[h]=g;d[h+"Offset"]=i});c.start=(d.startOffset>0)?d.start.splitText(d.startOffset):d.start;if(d.start===d.end){if((d.endOffset-d.startOffset)<c.start.nodeValue.length){c.start.splitText(d.endOffset-d.startOffset)}c.end=c.start}else{if(d.endOffset<d.end.nodeValue.length){d.end.splitText(d.endOffset)}c.end=d.end}c.commonAncestor=b.commonAncestorContainer;while(c.commonAncestor.nodeType!==Node.ELEMENT_NODE){c.commonAncestor=c.commonAncestor.parentNode}return c},serializeRange:function(d){var f=this;var b=function(j,k){var h=a(j).parents(":not(."+f.options.classPrefix+"-highlighter)").eq(0),g=h.xpath(f.wrapper)[0],i=h.textNodes(),l=a.inject(i.slice(0,i.index(j)),0,function(n,m){return n+m.nodeValue.length});return k?[g,l+j.nodeValue.length]:[g,l]},e=b(d.start),c=b(d.end,true);return{start:e[0],end:c[0],startOffset:e[1],endOffset:c[1]}},deserializeRange:function(f){var e=function(j){return document.evaluate(j,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue};var i=a(this.wrapper).xpath()[0],g=f.start.split("/"),h=f.end.split("/"),d=[],b={};for(var c=0;c<g.length;c+=1){if(g[c]===h[c]){d.push(g[c])}else{break}}b.commonAncestorContainer=e(i+d.join("/"));a.each(["start","end"],function(){var k=this,j=0;a(e(i+f[this])).textNodes().each(function(){if(j+this.nodeValue.length>=f[k+"Offset"]){b[k+"Container"]=this;b[k+"Offset"]=f[k+"Offset"]-j;return false}else{j+=this.nodeValue.length;return true}})});return this.normRange(b)},highlightRange:function(c){var e=this;var d=a(c.commonAncestor).textNodes();var b=[];d.slice(d.index(c.start),d.index(c.end)+1).each(function(){var f=e.dom.highlighter.clone().show();b.push(a(this).wrap(f).parent().get(0))});return b},showEditor:function(c,b){var d=this;if(b){this.dom.editor.find("textarea").val(b.text)}this.dom.editor.css(this._mousePosition(c)).show().find("textarea").focus().bind("keydown",function(f){if(f.keyCode==27){a(this).val("").unbind().parent().hide()}else{if(f.keyCode==13&&!f.shiftKey){a(this).unbind().parent().hide();if(b){d.updateAnnotation(b,{text:a(this).val()})}else{d.createAnnotation({text:a(this).val()})}a(this).val("")}}}).bind("blur",function(f){a(this).val("").unbind().parent().hide()});this.ignoreMouseup=true},startViewerHideTimer:function(b){a(this).oneTime(250,"viewerHide",function(){this.dom.viewer.hide()})},highlightMouseover:function(d){a(this).stopTime("viewerHide");if(this.mouseIsDown){return false}var c=a(d.target).parents("."+this.options.classPrefix+"-highlighter").andSelf();var b='<span class="'+this.options.classPrefix+'-controls"><a href="#" class="edit" alt="Edit" title="Edit this annotation">Edit</a><a href="#" class="del" alt="X" title="Delete this annotation">Delete</a></span>';var f=this.dom.viewer.clone().empty();a.each(c,function(e,g){a("<p>"+a(g).data("annotation").text+b+"</p>").appendTo(f).data("annotation",a(g).data("annotation"))});f.css(this._mousePosition(d)).replaceAll(this.dom.viewer).show();this.dom.viewer=f},adderMousedown:function(b){this.dom.adder.hide();this.showEditor(b);return false},viewerMouseover:function(b){a(this).stopTime("viewerHide")},controlEditClick:function(c){var b=a(c.target).parents("p"),d=this._fakePositionFromElement(this.dom.viewer);this.dom.viewer.hide();this.showEditor(d,b.data("annotation"))},controlDeleteClick:function(c){var b=a(c.target).parents("p");this.deleteAnnotation(b.data("annotation"));b.remove();if(!this.dom.viewer.is(":parent")){this.dom.viewer.hide()}},_mousePosition:function(b){return{top:b.pageY-a(this.wrapper).offset().top,left:b.pageX-a(this.wrapper).offset().left}},_fakePositionFromElement:function(b){return{pageY:a(b).offset().top,pageX:a(b).offset().left}}});a.plugin("annotator",Annotator)})(jQuery);(function(a){this.AnnotationStore=DelegatorClass.extend({events:{annotationCreated:"annotationCreated",annotationDeleted:"annotationDeleted",annotationUpdated:"annotationUpdated"},init:function(b,c){this.options=a.extend({prefix:"/store",annotator:a(c).data("annotator"),annotationData:{},loadFromSearch:false,urls:{create:"/annotations",read:"/annotations/:id",update:"/annotations/:id",destroy:"/annotations/:id",search:"/search"}},b);if(!this.options.annotator){a(c).annotator();this.options.annotator=a(c).data("annotator")}this.element=c;this.annotations=[];if(this.options.loadFromSearch){this.loadAnnotationsFromSearch(this.options.loadFromSearch)}else{this.loadAnnotations()}this._super()},annotationCreated:function(d,b){var c=this;if(a.inArray(b,this.annotations)===-1){this.registerAnnotation(b);a.ajax({url:this._urlFor("create"),data:this._dataFor(b),dataType:"jsonp",type:"POST",success:function(e){if(!("id" in e)){console.warn("Warning: No ID returned from server for annotation ",b)}c.updateAnnotation(b,e)},error:function(){c.handleBackendError.apply(c,arguments)}})}else{c.updateAnnotation(b,{})}},annotationDeleted:function(d,b){var c=this;if(a.inArray(b,this.annotations)!==-1){a.ajax({url:this._urlFor("destroy",b.id),type:"DELETE",success:function(){c.unregisterAnnotation(b)},error:function(){c.handleBackendError.apply(c,arguments)}})}},annotationUpdated:function(d,b){var c=this;if(a.inArray(b,this.annotations)!==-1){a.ajax({url:this._urlFor("update",b.id),type:"POST",data:this._dataFor(b),dataType:"jsonp",success:function(){c.updateAnnotation(b)},error:function(){c.handleBackendError.apply(c,arguments)}})}},registerAnnotation:function(b){this.annotations.push(b)},unregisterAnnotation:function(b){this.annotations.splice(this.annotations.indexOf(b),1)},updateAnnotation:function(b,c){if(a.inArray(b,this.annotations)===-1){console.error("Trying to update unregistered annotation!")}else{a.extend(b,c)}a(b.highlights).data("annotation",b)},loadAnnotations:function(){var b=this;a.getJSON(this._urlFor("read"),null,function(c,d){if(d==="success"&&a.isArray(c)){b.annotations=c;b.options.annotator.loadAnnotations(b.annotations)}else{throw ('Annotation could not be loaded. [XHR returned "'+d+'"]')}})},loadAnnotationsFromSearch:function(c){var b=this;a.getJSON(this._urlFor("search"),c,function(d,e){if(e==="success"&&"results" in d&&a.isArray(d.results)){b.annotations=d.results;b.options.annotator.loadAnnotations(b.annotations)}else{throw ('Annotation could not be loaded. [XHR returned "'+e+'"]')}})},handleBackendError:function(b,d,c){alert("The annotation store backend encountered an error! Your changes may not have been saved. Refresh the page or see the console for more details.");console.error("AJAX error - { status: ",d,", error: ",c," }");console.error("AJAX error - XMLHTTPRequest object: ",b)},_urlFor:function(c,d){var b=this.options.prefix?this.options.prefix:"/";return b+this.options.urls[c].replace(/:id/,d||"")},_dataFor:function(b){var d=b.highlights;delete b.highlights;a.extend(b,this.options.annotationData);var c={json:a.toJSON(b)};b.highlights=d;return c}});a.plugin("annotationStore",AnnotationStore)})(jQuery);
BIN  pkg/img/delete.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  pkg/img/edit.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  pkg/img/note.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Please sign in to comment.
Something went wrong with that request. Please try again.