diff --git a/CHANGES.md b/CHANGES.md index 0f1c17f..71b95b2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,7 @@ ## Changelog ## +- [1.2.6]: + - [Bugfix]: Fix for activity completion for view event. + - [Chore]: Some minor changes to reduce moodle validation errors. - [1.2.5]: - [Bugfix]: Added LICENSE.md - [Bugfix]: In print mode now the background of the grading form is also greyed out. diff --git a/amd/build/annotations.min.js b/amd/build/annotations.min.js index f35605f..77f1c06 100644 --- a/amd/build/annotations.min.js +++ b/amd/build/annotations.min.js @@ -1,2 +1,2 @@ -define ("mod_margic/annotations",["exports","jquery","./highlighting"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var e=function(a,e,f,g){var k=!1,l=[],m=!1;(0,b.default)(".annotation-form div.col-md-3").removeClass("col-md-3");(0,b.default)(".annotation-form div.col-md-9").removeClass("col-md-9");(0,b.default)(".annotation-form div.form-group").removeClass("form-group");(0,b.default)(".annotation-form div.row").removeClass("row");(0,b.default)(document).on("click","#id_cancel",function(a){a.preventDefault();(0,c.removeAllTempHighlights)();j();k=!1});(0,b.default)("textarea").keypress(function(a){if(13==a.which){(0,b.default)(this).parents(":eq(2)").submit();a.preventDefault()}});(0,b.default)(document).on("mouseup",".originaltext",function(){var a=window.getSelection().getRangeAt(0);if(""!==a.cloneContents().textContent&&e){(0,c.removeAllTempHighlights)();j();m=d(this);var f=this.id.replace(/entry-/,"");(0,b.default)(".annotation-form-"+f+" input[name=\"startcontainer\"]").val(m.target[0].selector[0].startContainer);(0,b.default)(".annotation-form-"+f+" input[name=\"endcontainer\"]").val(m.target[0].selector[0].endContainer);(0,b.default)(".annotation-form-"+f+" input[name=\"startoffset\"]").val(m.target[0].selector[0].startOffset);(0,b.default)(".annotation-form-"+f+" input[name=\"endoffset\"]").val(m.target[0].selector[0].endOffset);(0,b.default)(".annotation-form-"+f+" input[name=\"start\"]").val(m.target[0].selector[1].start);(0,b.default)(".annotation-form-"+f+" input[name=\"end\"]").val(m.target[0].selector[1].end);(0,b.default)(".annotation-form-"+f+" input[name=\"exact\"]").val(m.target[0].selector[2].exact);(0,b.default)(".annotation-form-"+f+" input[name=\"prefix\"]").val(m.target[0].selector[2].prefix);(0,b.default)(".annotation-form-"+f+" input[name=\"suffix\"]").val(m.target[0].selector[2].suffix);(0,b.default)(".annotation-form-"+f+" select").val(1);(0,b.default)("#annotationpreview-temp-"+f).html(m.target[0].selector[2].exact.replaceAll("<","<").replaceAll(">",">"));(0,b.default)(".annotationarea-"+f+" .annotation-form").show();(0,b.default)(".annotation-form-"+f+" #id_text").focus()}});b.default.ajax({url:"./annotations.php",data:{id:a,getannotations:1},success:function success(a){l=JSON.parse(a);h();(0,b.default)(".annotated").mouseenter(function(){var a=this.id.replace("annotated-","");(0,b.default)(".annotation-box-"+a).addClass("hovered");(0,b.default)(".annotated-"+a).css("background-color","lightblue")});(0,b.default)(".annotated").mouseleave(function(){var a=this.id.replace("annotated-","");(0,b.default)(".annotation-box-"+a).removeClass("hovered");(0,b.default)(".annotated-"+a).css("background-color",(0,b.default)(".annotated-"+a).css("textDecorationColor"))});(0,b.default)(document).on("mouseover",".annotated_temp",function(){(0,b.default)(".annotated_temp").addClass("hovered")});(0,b.default)(document).on("mouseleave",".annotated_temp",function(){(0,b.default)(".annotated_temp").removeClass("hovered")});(0,b.default)(document).on("click",".annotated",function(){var a=this.id.replace("annotated-","");i(a)});(0,b.default)(document).on("click",".edit-annotation",function(){var a=this.id.replace("edit-annotation-","");i(a)});(0,b.default)(document).on("mouseover",".hoverannotation",function(){var a=this.id.replace("hoverannotation-","");(0,b.default)(".annotated-"+a).css("background-color","lightblue")});(0,b.default)(document).on("mouseleave",".hoverannotation",function(){var a=this.id.replace("hoverannotation-","");(0,b.default)(".annotated-"+a).css("background-color",(0,b.default)(".annotated-"+a).css("textDecorationColor"))});if(0!=g){(0,b.default)(".annotated-"+g).attr("tabindex",-1);(0,b.default)(".annotated-"+g).focus()}},complete:function complete(){(0,b.default)("#overlay").hide()},error:function error(){alert("Error fetching annotations")}});function h(){for(var a=0,d=Object.values(l);a",">"));(0,b.default)("#annotationpreview-temp-"+d).css("border-color","#"+l[a].color);(0,b.default)(".annotationarea-"+d+" .annotation-form").insertBefore(".annotation-box-"+a);(0,b.default)(".annotationarea-"+d+" .annotation-form").show();(0,b.default)(".annotationarea-"+d+" #id_text").focus()}else{(0,b.default)(".annotation-box-"+a).focus()}}function j(){(0,b.default)(".annotation-form").hide();(0,b.default)(".annotation-form input[name^=\"annotationid\"]").val(null);(0,b.default)(".annotation-form input[name^=\"startcontainer\"]").val(-1);(0,b.default)(".annotation-form input[name^=\"endcontainer\"]").val(-1);(0,b.default)(".annotation-form input[name^=\"startoffset\"]").val(-1);(0,b.default)(".annotation-form input[name^=\"endoffset\"]").val(-1);(0,b.default)(".annotation-form textarea[name^=\"text\"]").val("");(0,b.default)(".annotation-box").not(".annotation-form").show()}};a.init=e;function d(a){var b=[window.getSelection().getRangeAt(0)];if(b.collapsed){return null}var d=b.map(function(b){return(0,c.describe)(a,b)}),e=d.map(function(a){return{selector:a}}),f={target:e};(0,c.anchor)(f,a);return f}}); +define ("mod_margic/annotations",["exports","jquery","./highlighting"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var e=function(a,e,f,g){var k=!1,l=[],m=!1;(0,b.default)(".annotation-form div.col-md-3").removeClass("col-md-3");(0,b.default)(".annotation-form div.col-md-9").removeClass("col-md-9");(0,b.default)(".annotation-form div.form-group").removeClass("form-group");(0,b.default)(".annotation-form div.row").removeClass("row");(0,b.default)(document).on("click","#id_cancel",function(a){a.preventDefault();(0,c.removeAllTempHighlights)();j();k=!1});(0,b.default)("textarea").keypress(function(a){if(13==a.which){(0,b.default)(this).parents(":eq(2)").submit();a.preventDefault()}});(0,b.default)(document).on("mouseup",".originaltext",function(){var a=window.getSelection().getRangeAt(0);if(""!==a.cloneContents().textContent&&e){(0,c.removeAllTempHighlights)();j();m=d(this);var f=this.id.replace(/entry-/,"");(0,b.default)(".annotation-form-"+f+" input[name=\"startcontainer\"]").val(m.target[0].selector[0].startContainer);(0,b.default)(".annotation-form-"+f+" input[name=\"endcontainer\"]").val(m.target[0].selector[0].endContainer);(0,b.default)(".annotation-form-"+f+" input[name=\"startoffset\"]").val(m.target[0].selector[0].startOffset);(0,b.default)(".annotation-form-"+f+" input[name=\"endoffset\"]").val(m.target[0].selector[0].endOffset);(0,b.default)(".annotation-form-"+f+" input[name=\"start\"]").val(m.target[0].selector[1].start);(0,b.default)(".annotation-form-"+f+" input[name=\"end\"]").val(m.target[0].selector[1].end);(0,b.default)(".annotation-form-"+f+" input[name=\"exact\"]").val(m.target[0].selector[2].exact);(0,b.default)(".annotation-form-"+f+" input[name=\"prefix\"]").val(m.target[0].selector[2].prefix);(0,b.default)(".annotation-form-"+f+" input[name=\"suffix\"]").val(m.target[0].selector[2].suffix);(0,b.default)(".annotation-form-"+f+" select").val(1);(0,b.default)("#annotationpreview-temp-"+f).html(m.target[0].selector[2].exact.replaceAll("<","<").replaceAll(">",">"));(0,b.default)(".annotationarea-"+f+" .annotation-form").show();(0,b.default)(".annotation-form-"+f+" #id_text").focus()}});b.default.ajax({url:"./annotations.php",data:{id:a,getannotations:1},success:function success(a){l=JSON.parse(a);h();(0,b.default)(".annotated").mouseenter(function(){var a=this.id.replace("annotated-","");(0,b.default)(".annotation-box-"+a).addClass("hovered");(0,b.default)(".annotated-"+a).css("background-color","lightblue")});(0,b.default)(".annotated").mouseleave(function(){var a=this.id.replace("annotated-","");(0,b.default)(".annotation-box-"+a).removeClass("hovered");(0,b.default)(".annotated-"+a).css("background-color",(0,b.default)(".annotated-"+a).css("textDecorationColor"))});(0,b.default)(document).on("mouseover",".annotated_temp",function(){(0,b.default)(".annotated_temp").addClass("hovered")});(0,b.default)(document).on("mouseleave",".annotated_temp",function(){(0,b.default)(".annotated_temp").removeClass("hovered")});(0,b.default)(document).on("click",".annotated",function(){var a=this.id.replace("annotated-","");i(a)});(0,b.default)(document).on("click",".edit-annotation",function(){var a=this.id.replace("edit-annotation-","");i(a)});(0,b.default)(document).on("mouseover",".hoverannotation",function(){var a=this.id.replace("hoverannotation-","");(0,b.default)(".annotated-"+a).css("background-color","lightblue")});(0,b.default)(document).on("mouseleave",".hoverannotation",function(){var a=this.id.replace("hoverannotation-","");(0,b.default)(".annotated-"+a).css("background-color",(0,b.default)(".annotated-"+a).css("textDecorationColor"))});if(0!=g){(0,b.default)(".annotated-"+g).attr("tabindex",-1);(0,b.default)(".annotated-"+g).focus()}},complete:function complete(){(0,b.default)("#overlay").hide()},error:function error(){}});function h(){for(var a=0,d=Object.values(l);a",">"));(0,b.default)("#annotationpreview-temp-"+d).css("border-color","#"+l[a].color);(0,b.default)(".annotationarea-"+d+" .annotation-form").insertBefore(".annotation-box-"+a);(0,b.default)(".annotationarea-"+d+" .annotation-form").show();(0,b.default)(".annotationarea-"+d+" #id_text").focus()}else{(0,b.default)(".annotation-box-"+a).focus()}}function j(){(0,b.default)(".annotation-form").hide();(0,b.default)(".annotation-form input[name^=\"annotationid\"]").val(null);(0,b.default)(".annotation-form input[name^=\"startcontainer\"]").val(-1);(0,b.default)(".annotation-form input[name^=\"endcontainer\"]").val(-1);(0,b.default)(".annotation-form input[name^=\"startoffset\"]").val(-1);(0,b.default)(".annotation-form input[name^=\"endoffset\"]").val(-1);(0,b.default)(".annotation-form textarea[name^=\"text\"]").val("");(0,b.default)(".annotation-box").not(".annotation-form").show()}};a.init=e;function d(a){var b=[window.getSelection().getRangeAt(0)];if(b.collapsed){return null}var d=b.map(function(b){return(0,c.describe)(a,b)}),e=d.map(function(a){return{selector:a}}),f={target:e};(0,c.anchor)(f,a);return f}}); //# sourceMappingURL=annotations.min.js.map diff --git a/amd/build/annotations.min.js.map b/amd/build/annotations.min.js.map index cb23fb8..59bbca9 100644 --- a/amd/build/annotations.min.js.map +++ b/amd/build/annotations.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/annotations.js"],"names":["init","cmid","canmakeannotations","myuserid","focusannotation","edited","annotations","newannotation","removeClass","document","on","e","preventDefault","resetForms","keypress","which","parents","submit","selectedrange","window","getSelection","getRangeAt","cloneContents","textContent","createAnnotation","entry","id","replace","val","target","selector","startContainer","endContainer","startOffset","endOffset","start","end","exact","prefix","suffix","html","replaceAll","show","focus","$","ajax","url","data","success","response","JSON","parse","recreateAnnotations","mouseenter","addClass","css","mouseleave","editAnnotation","attr","complete","hide","error","alert","Object","values","annotation","rangeSelectors","type","startcontainer","parseInt","startoffset","endcontainer","endoffset","map","selectors","annotationid","userid","text","color","insertBefore","not","root","ranges","collapsed","range"],"mappings":"mKAuBA,uDAGO,GAAMA,CAAAA,CAAI,CAAG,SAACC,CAAD,CAAOC,CAAP,CAA2BC,CAA3B,CAAqCC,CAArC,CAAyD,IAErEC,CAAAA,CAAM,GAF+D,CAGrEC,CAAW,GAH0D,CAKrEC,CAAa,GALwD,CAQzE,cAAE,+BAAF,EAAmCC,WAAnC,CAA+C,UAA/C,EACA,cAAE,+BAAF,EAAmCA,WAAnC,CAA+C,UAA/C,EACA,cAAE,iCAAF,EAAqCA,WAArC,CAAiD,YAAjD,EACA,cAAE,0BAAF,EAA8BA,WAA9B,CAA0C,KAA1C,EAGA,cAAEC,QAAF,EAAYC,EAAZ,CAAe,OAAf,CAAwB,YAAxB,CAAsC,SAASC,CAAT,CAAY,CAC9CA,CAAC,CAACC,cAAF,GAEA,gCAEAC,CAAU,GAEVR,CAAM,GACT,CARD,EAWA,cAAE,UAAF,EAAcS,QAAd,CAAuB,SAASH,CAAT,CAAY,CAC/B,GAAe,EAAX,EAAAA,CAAC,CAACI,KAAN,CAAmB,CACf,cAAE,IAAF,EAAQC,OAAR,CAAgB,QAAhB,EAA0BC,MAA1B,GACAN,CAAC,CAACC,cAAF,EACH,CACJ,CALD,EAQA,cAAEH,QAAF,EAAYC,EAAZ,CAAe,SAAf,CAA0B,eAA1B,CAA2C,UAAW,CAClD,GAAIQ,CAAAA,CAAa,CAAGC,MAAM,CAACC,YAAP,GAAsBC,UAAtB,CAAiC,CAAjC,CAApB,CAEA,GAAkD,EAA9C,GAAAH,CAAa,CAACI,aAAd,GAA8BC,WAA9B,EAAoDrB,CAAxD,CAA4E,CAExE,gCAEAW,CAAU,GAGVN,CAAa,CAAGiB,CAAgB,CAAC,IAAD,CAAhC,CAEA,GAAIC,CAAAA,CAAK,CAAG,KAAKC,EAAL,CAAQC,OAAR,CAAgB,QAAhB,CAA0B,EAA1B,CAAZ,CAGA,cAAE,oBAAsBF,CAAtB,CAA8B,iCAAhC,EAAiEG,GAAjE,CACIrB,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCC,cADxC,EAEA,cAAE,oBAAsBN,CAAtB,CAA8B,+BAAhC,EAA+DG,GAA/D,CACIrB,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCE,YADxC,EAEA,cAAE,oBAAsBP,CAAtB,CAA8B,8BAAhC,EAA8DG,GAA9D,CACIrB,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCG,WADxC,EAEA,cAAE,oBAAsBR,CAAtB,CAA8B,4BAAhC,EAA4DG,GAA5D,CACIrB,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCI,SADxC,EAIA,cAAE,oBAAsBT,CAAtB,CAA8B,wBAAhC,EAAwDG,GAAxD,CACIrB,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCK,KADxC,EAEA,cAAE,oBAAsBV,CAAtB,CAA8B,sBAAhC,EAAsDG,GAAtD,CACIrB,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCM,GADxC,EAIA,cAAE,oBAAsBX,CAAtB,CAA8B,wBAAhC,EAAwDG,GAAxD,CACIrB,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCO,KADxC,EAEA,cAAE,oBAAsBZ,CAAtB,CAA8B,yBAAhC,EAAyDG,GAAzD,CACIrB,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCQ,MADxC,EAEA,cAAE,oBAAsBb,CAAtB,CAA8B,yBAAhC,EAAyDG,GAAzD,CACIrB,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCS,MADxC,EAGA,cAAE,oBAAsBd,CAAtB,CAA8B,SAAhC,EAA2CG,GAA3C,CAA+C,CAA/C,EAGA,cAAE,2BAA6BH,CAA/B,EAAsCe,IAAtC,CACIjC,CAAa,CAACsB,MAAd,CAAqB,CAArB,EAAwBC,QAAxB,CAAiC,CAAjC,EAAoCO,KAApC,CAA0CI,UAA1C,CAAqD,GAArD,CAA0D,MAA1D,EAAkEA,UAAlE,CAA6E,GAA7E,CAAkF,MAAlF,CADJ,EAGA,cAAE,mBAAqBhB,CAArB,CAA6B,mBAA/B,EAAoDiB,IAApD,GACA,cAAE,oBAAsBjB,CAAtB,CAA8B,WAAhC,EAA6CkB,KAA7C,EACH,CACJ,CA/CD,EAkDAC,UAAEC,IAAF,CAAO,CACHC,GAAG,CAAE,mBADF,CAEHC,IAAI,CAAE,CAAC,GAAM9C,CAAP,CAAa,eAAkB,CAA/B,CAFH,CAGH+C,OAAO,CAAE,iBAASC,CAAT,CAAmB,CACxB3C,CAAW,CAAG4C,IAAI,CAACC,KAAL,CAAWF,CAAX,CAAd,CACAG,CAAmB,GAGnB,cAAE,YAAF,EAAgBC,UAAhB,CAA2B,UAAW,CAClC,GAAI3B,CAAAA,CAAE,CAAG,KAAKA,EAAL,CAAQC,OAAR,CAAgB,YAAhB,CAA8B,EAA9B,CAAT,CACA,cAAE,mBAAqBD,CAAvB,EAA2B4B,QAA3B,CAAoC,SAApC,EACA,cAAE,cAAgB5B,CAAlB,EAAsB6B,GAAtB,CAA0B,kBAA1B,CAA8C,WAA9C,CACH,CAJD,EAMA,cAAE,YAAF,EAAgBC,UAAhB,CAA2B,UAAW,CAClC,GAAI9B,CAAAA,CAAE,CAAG,KAAKA,EAAL,CAAQC,OAAR,CAAgB,YAAhB,CAA8B,EAA9B,CAAT,CACA,cAAE,mBAAqBD,CAAvB,EAA2BlB,WAA3B,CAAuC,SAAvC,EACA,cAAE,cAAgBkB,CAAlB,EAAsB6B,GAAtB,CAA0B,kBAA1B,CAA8C,cAAE,cAAgB7B,CAAlB,EAAsB6B,GAAtB,CAA0B,qBAA1B,CAA9C,CACH,CAJD,EAOA,cAAE9C,QAAF,EAAYC,EAAZ,CAAe,WAAf,CAA4B,iBAA5B,CAA+C,UAAW,CACtD,cAAE,iBAAF,EAAqB4C,QAArB,CAA8B,SAA9B,CACH,CAFD,EAIA,cAAE7C,QAAF,EAAYC,EAAZ,CAAe,YAAf,CAA6B,iBAA7B,CAAgD,UAAW,CACvD,cAAE,iBAAF,EAAqBF,WAArB,CAAiC,SAAjC,CACH,CAFD,EAKA,cAAEC,QAAF,EAAYC,EAAZ,CAAe,OAAf,CAAwB,YAAxB,CAAsC,UAAW,CAC7C,GAAIgB,CAAAA,CAAE,CAAG,KAAKA,EAAL,CAAQC,OAAR,CAAgB,YAAhB,CAA8B,EAA9B,CAAT,CACA8B,CAAc,CAAC/B,CAAD,CACjB,CAHD,EAMA,cAAEjB,QAAF,EAAYC,EAAZ,CAAe,OAAf,CAAwB,kBAAxB,CAA4C,UAAW,CACnD,GAAIgB,CAAAA,CAAE,CAAG,KAAKA,EAAL,CAAQC,OAAR,CAAgB,kBAAhB,CAAoC,EAApC,CAAT,CACA8B,CAAc,CAAC/B,CAAD,CACjB,CAHD,EAMA,cAAEjB,QAAF,EAAYC,EAAZ,CAAe,WAAf,CAA4B,kBAA5B,CAAgD,UAAW,CACvD,GAAIgB,CAAAA,CAAE,CAAG,KAAKA,EAAL,CAAQC,OAAR,CAAgB,kBAAhB,CAAoC,EAApC,CAAT,CACA,cAAE,cAAgBD,CAAlB,EAAsB6B,GAAtB,CAA0B,kBAA1B,CAA8C,WAA9C,CACH,CAHD,EAKA,cAAE9C,QAAF,EAAYC,EAAZ,CAAe,YAAf,CAA6B,kBAA7B,CAAiD,UAAW,CACxD,GAAIgB,CAAAA,CAAE,CAAG,KAAKA,EAAL,CAAQC,OAAR,CAAgB,kBAAhB,CAAoC,EAApC,CAAT,CACA,cAAE,cAAgBD,CAAlB,EAAsB6B,GAAtB,CAA0B,kBAA1B,CAA8C,cAAE,cAAgB7B,CAAlB,EAAsB6B,GAAtB,CAA0B,qBAA1B,CAA9C,CACH,CAHD,EAOA,GAAuB,CAAnB,EAAAnD,CAAJ,CAA0B,CACtB,cAAE,cAAgBA,CAAlB,EAAmCsD,IAAnC,CAAwC,UAAxC,CAAoD,CAAC,CAArD,EACA,cAAE,cAAgBtD,CAAlB,EAAmCuC,KAAnC,EACH,CAEJ,CA3DE,CA4DHgB,QAAQ,CAAE,mBAAW,CACjB,cAAE,UAAF,EAAcC,IAAd,EACH,CA9DE,CA+DHC,KAAK,CAAE,gBAAW,CACdC,KAAK,CAAC,4BAAD,CACR,CAjEE,CAAP,EAwEA,QAASV,CAAAA,CAAT,EAA+B,CAE3B,cAAuBW,MAAM,CAACC,MAAP,CAAc1D,CAAd,CAAvB,gBAAmD,IAA1C2D,CAAAA,CAAU,KAAgC,CAEzCC,CAAc,CAAG,CAAC,CACpB,CAACC,IAAI,CAAE,eAAP,CAAwBpC,cAAc,CAAEkC,CAAU,CAACG,cAAnD,CAAmEnC,WAAW,CAAEoC,QAAQ,CAACJ,CAAU,CAACK,WAAZ,CAAxF,CACAtC,YAAY,CAAEiC,CAAU,CAACM,YADzB,CACuCrC,SAAS,CAAEmC,QAAQ,CAACJ,CAAU,CAACO,SAAZ,CAD1D,CADoB,CAGpB,CAACL,IAAI,CAAE,sBAAP,CAA+BhC,KAAK,CAAEkC,QAAQ,CAACJ,CAAU,CAAC9B,KAAZ,CAA9C,CAAkEC,GAAG,CAAEiC,QAAQ,CAACJ,CAAU,CAAC7B,GAAZ,CAA/E,CAHoB,CAIpB,CAAC+B,IAAI,CAAE,mBAAP,CAA4B9B,KAAK,CAAE4B,CAAU,CAAC5B,KAA9C,CAAqDC,MAAM,CAAE2B,CAAU,CAAC3B,MAAxE,CAAgFC,MAAM,CAAE0B,CAAU,CAAC1B,MAAnG,CAJoB,CAAD,CAFwB,CASzCV,CAAM,CAAGqC,CAAc,CAACO,GAAf,CAAmB,SAAAC,CAAS,QAAK,CAC5C5C,QAAQ,CAAE4C,CADkC,CAAL,CAA5B,CATgC,CAmB/C,aALsB,CAClBT,UAAU,CAAEA,CADM,CAElBpC,MAAM,CAAEA,CAFU,CAKtB,CAAsB,cAAE,UAAYoC,CAAU,CAACxC,KAAzB,EAAgC,CAAhC,CAAtB,CACH,CACJ,CAOD,QAASgC,CAAAA,CAAT,CAAwBkB,CAAxB,CAAsC,CAElC,GAAItE,CAAM,EAAIsE,CAAd,CAA4B,CACxB,gCACA9D,CAAU,GACVR,CAAM,GACT,CAJD,IAIO,IAAIH,CAAkB,EAAIC,CAAQ,EAAIG,CAAW,CAACqE,CAAD,CAAX,CAA0BC,MAAhE,CAAwE,CAC3E,gCACA/D,CAAU,GAEVR,CAAM,CAAGsE,CAAT,CAEA,GAAIlD,CAAAA,CAAK,CAAGnB,CAAW,CAACqE,CAAD,CAAX,CAA0BlD,KAAtC,CAEA,cAAE,mBAAqBkD,CAAvB,EAAqCf,IAArC,GAEA,cAAE,oBAAsBnC,CAAtB,CAA8B,iCAAhC,EAAiEG,GAAjE,CAAqEtB,CAAW,CAACqE,CAAD,CAAX,CAA0BP,cAA/F,EACA,cAAE,oBAAsB3C,CAAtB,CAA8B,+BAAhC,EAA+DG,GAA/D,CAAmEtB,CAAW,CAACqE,CAAD,CAAX,CAA0BJ,YAA7F,EACA,cAAE,oBAAsB9C,CAAtB,CAA8B,8BAAhC,EAA8DG,GAA9D,CAAkEtB,CAAW,CAACqE,CAAD,CAAX,CAA0BL,WAA5F,EACA,cAAE,oBAAsB7C,CAAtB,CAA8B,4BAAhC,EAA4DG,GAA5D,CAAgEtB,CAAW,CAACqE,CAAD,CAAX,CAA0BH,SAA1F,EACA,cAAE,oBAAsB/C,CAAtB,CAA8B,wBAAhC,EAAwDG,GAAxD,CAA4DtB,CAAW,CAACqE,CAAD,CAAX,CAA0BxC,KAAtF,EACA,cAAE,oBAAsBV,CAAtB,CAA8B,sBAAhC,EAAsDG,GAAtD,CAA0DtB,CAAW,CAACqE,CAAD,CAAX,CAA0BvC,GAApF,EACA,cAAE,oBAAsBX,CAAtB,CAA8B,wBAAhC,EAAwDG,GAAxD,CAA4DtB,CAAW,CAACqE,CAAD,CAAX,CAA0BtC,KAAtF,EACA,cAAE,oBAAsBZ,CAAtB,CAA8B,yBAAhC,EAAyDG,GAAzD,CAA6DtB,CAAW,CAACqE,CAAD,CAAX,CAA0BrC,MAAvF,EACA,cAAE,oBAAsBb,CAAtB,CAA8B,yBAAhC,EAAyDG,GAAzD,CAA6DtB,CAAW,CAACqE,CAAD,CAAX,CAA0BpC,MAAvF,EAEA,cAAE,oBAAsBd,CAAtB,CAA8B,+BAAhC,EAA+DG,GAA/D,CAAmE+C,CAAnE,EAEA,cAAE,oBAAsBlD,CAAtB,CAA8B,0BAAhC,EAA0DG,GAA1D,CAA8DtB,CAAW,CAACqE,CAAD,CAAX,CAA0BE,IAAxF,EAEA,cAAE,oBAAsBpD,CAAtB,CAA8B,SAAhC,EAA2CG,GAA3C,CAA+CtB,CAAW,CAACqE,CAAD,CAAX,CAA0BR,IAAzE,EAGA,cAAE,2BAA6B1C,CAA/B,EAAsCe,IAAtC,CACIlC,CAAW,CAACqE,CAAD,CAAX,CAA0BtC,KAA1B,CAAgCI,UAAhC,CAA2C,GAA3C,CAAgD,MAAhD,EAAwDA,UAAxD,CAAmE,GAAnE,CAAwE,MAAxE,CADJ,EAEA,cAAE,2BAA6BhB,CAA/B,EAAsC8B,GAAtC,CAA0C,cAA1C,CAA0D,IAAMjD,CAAW,CAACqE,CAAD,CAAX,CAA0BG,KAA1F,EAEA,cAAE,mBAAqBrD,CAArB,CAA6B,mBAA/B,EAAoDsD,YAApD,CAAiE,mBAAqBJ,CAAtF,EACA,cAAE,mBAAqBlD,CAArB,CAA6B,mBAA/B,EAAoDiB,IAApD,GACA,cAAE,mBAAqBjB,CAArB,CAA6B,WAA/B,EAA4CkB,KAA5C,EACH,CAlCM,IAkCA,CACH,cAAE,mBAAqBgC,CAAvB,EAAqChC,KAArC,EACH,CACJ,CAKD,QAAS9B,CAAAA,CAAT,EAAsB,CAClB,cAAE,kBAAF,EAAsB+C,IAAtB,GAEA,cAAE,gDAAF,EAAkDhC,GAAlD,CAAsD,IAAtD,EAEA,cAAE,kDAAF,EAAoDA,GAApD,CAAwD,CAAC,CAAzD,EACA,cAAE,gDAAF,EAAkDA,GAAlD,CAAsD,CAAC,CAAvD,EACA,cAAE,+CAAF,EAAiDA,GAAjD,CAAqD,CAAC,CAAtD,EACA,cAAE,6CAAF,EAA+CA,GAA/C,CAAmD,CAAC,CAApD,EAEA,cAAE,2CAAF,EAA6CA,GAA7C,CAAiD,EAAjD,EAEA,cAAE,iBAAF,EAAqBoD,GAArB,CAAyB,kBAAzB,EAA6CtC,IAA7C,EACH,CACJ,CAvPM,C,SAgQP,QAASlB,CAAAA,CAAT,CAA0ByD,CAA1B,CAAgC,CAC5B,GAAMC,CAAAA,CAAM,CAAG,CAAC/D,MAAM,CAACC,YAAP,GAAsBC,UAAtB,CAAiC,CAAjC,CAAD,CAAf,CAEA,GAAI6D,CAAM,CAACC,SAAX,CAAsB,CAClB,MAAO,KACV,CAL2B,GAOtBjB,CAAAA,CAAc,CAAGgB,CAAM,CAACT,GAAP,CAAW,SAAAW,CAAK,QAAI,eAASH,CAAT,CAAeG,CAAf,CAAJ,CAAhB,CAPK,CAStBvD,CAAM,CAAGqC,CAAc,CAACO,GAAf,CAAmB,SAAAC,CAAS,QAAK,CAC9C5C,QAAQ,CAAE4C,CADoC,CAAL,CAA5B,CATa,CActBT,CAAU,CAAG,CACjBpC,MAAM,CAANA,CADiB,CAdS,CAkB5B,aAAOoC,CAAP,CAAmBgB,CAAnB,EAEA,MAAOhB,CAAAA,CACV,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Module for the annotation functions of the margic.\n *\n * @module mod_margic/annotations\n * @copyright 2022 coactum GmbH\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport {removeAllTempHighlights, anchor, describe} from './highlighting';\n\nexport const init = (cmid, canmakeannotations, myuserid, focusannotation) => {\n\n var edited = false;\n var annotations = Array();\n\n var newannotation = false;\n\n // Remove col-mds from moodle form.\n $('.annotation-form div.col-md-3').removeClass('col-md-3');\n $('.annotation-form div.col-md-9').removeClass('col-md-9');\n $('.annotation-form div.form-group').removeClass('form-group');\n $('.annotation-form div.row').removeClass('row');\n\n // Onclick listener if form is canceled.\n $(document).on('click', '#id_cancel', function(e) {\n e.preventDefault();\n\n removeAllTempHighlights(); // Remove other temporary highlights.\n\n resetForms(); // Remove old form contents.\n\n edited = false;\n });\n\n // Listen for return key pressed to submit annotation form.\n $('textarea').keypress(function(e) {\n if (e.which == 13) {\n $(this).parents(':eq(2)').submit();\n e.preventDefault();\n }\n });\n\n // If user selects text for new annotation\n $(document).on('mouseup', '.originaltext', function() {\n var selectedrange = window.getSelection().getRangeAt(0);\n\n if (selectedrange.cloneContents().textContent !== '' && canmakeannotations) {\n\n removeAllTempHighlights(); // Remove other temporary highlights.\n\n resetForms(); // Reset the annotation forms.\n\n // Create new annotation.\n newannotation = createAnnotation(this);\n\n var entry = this.id.replace(/entry-/, '');\n\n // RangeSelector.\n $('.annotation-form-' + entry + ' input[name=\"startcontainer\"]').val(\n newannotation.target[0].selector[0].startContainer);\n $('.annotation-form-' + entry + ' input[name=\"endcontainer\"]').val(\n newannotation.target[0].selector[0].endContainer);\n $('.annotation-form-' + entry + ' input[name=\"startoffset\"]').val(\n newannotation.target[0].selector[0].startOffset);\n $('.annotation-form-' + entry + ' input[name=\"endoffset\"]').val(\n newannotation.target[0].selector[0].endOffset);\n\n // TextPositionSelector.\n $('.annotation-form-' + entry + ' input[name=\"start\"]').val(\n newannotation.target[0].selector[1].start);\n $('.annotation-form-' + entry + ' input[name=\"end\"]').val(\n newannotation.target[0].selector[1].end);\n\n // TextQuoteSelector.\n $('.annotation-form-' + entry + ' input[name=\"exact\"]').val(\n newannotation.target[0].selector[2].exact);\n $('.annotation-form-' + entry + ' input[name=\"prefix\"]').val(\n newannotation.target[0].selector[2].prefix);\n $('.annotation-form-' + entry + ' input[name=\"suffix\"]').val(\n newannotation.target[0].selector[2].suffix);\n\n $('.annotation-form-' + entry + ' select').val(1);\n\n // Prevent JavaScript injection (if annotated text in original entry is JavaScript code in script tags).\n $('#annotationpreview-temp-' + entry).html(\n newannotation.target[0].selector[2].exact.replaceAll('<', '<').replaceAll('>', '>'));\n\n $('.annotationarea-' + entry + ' .annotation-form').show();\n $('.annotation-form-' + entry + ' #id_text').focus();\n }\n });\n\n // Fetch and recreate annotations.\n $.ajax({\n url: './annotations.php',\n data: {'id': cmid, 'getannotations': 1},\n success: function(response) {\n annotations = JSON.parse(response);\n recreateAnnotations();\n\n // Highlight annotation and all annotated text if annotated text is hovered\n $('.annotated').mouseenter(function() {\n var id = this.id.replace('annotated-', '');\n $('.annotation-box-' + id).addClass('hovered');\n $('.annotated-' + id).css(\"background-color\", 'lightblue');\n });\n\n $('.annotated').mouseleave(function() {\n var id = this.id.replace('annotated-', '');\n $('.annotation-box-' + id).removeClass('hovered');\n $('.annotated-' + id).css(\"background-color\", $('.annotated-' + id).css('textDecorationColor'));\n });\n\n // Highlight whole temp annotation if part of temp annotation is hovered\n $(document).on('mouseover', '.annotated_temp', function() {\n $('.annotated_temp').addClass('hovered');\n });\n\n $(document).on('mouseleave', '.annotated_temp', function() {\n $('.annotated_temp').removeClass('hovered');\n });\n\n // Onclick listener for editing annotation.\n $(document).on('click', '.annotated', function() {\n var id = this.id.replace('annotated-', '');\n editAnnotation(id);\n });\n\n // Onclick listener for editing annotation.\n $(document).on('click', '.edit-annotation', function() {\n var id = this.id.replace('edit-annotation-', '');\n editAnnotation(id);\n });\n\n // Highlight annotation if hoverannotation button is hovered\n $(document).on('mouseover', '.hoverannotation', function() {\n var id = this.id.replace('hoverannotation-', '');\n $('.annotated-' + id).css(\"background-color\", 'lightblue');\n });\n\n $(document).on('mouseleave', '.hoverannotation', function() {\n var id = this.id.replace('hoverannotation-', '');\n $('.annotated-' + id).css(\"background-color\", $('.annotated-' + id).css('textDecorationColor'));\n });\n\n\n // Focus annotation if needed.\n if (focusannotation != 0) {\n $('.annotated-' + focusannotation).attr('tabindex', -1);\n $('.annotated-' + focusannotation).focus();\n }\n\n },\n complete: function() {\n $('#overlay').hide();\n },\n error: function() {\n alert('Error fetching annotations');\n }\n });\n\n /**\n * Recreate annotations.\n *\n */\n function recreateAnnotations() {\n\n for (let annotation of Object.values(annotations)) {\n\n const rangeSelectors = [[\n {type: \"RangeSelector\", startContainer: annotation.startcontainer, startOffset: parseInt(annotation.startoffset),\n endContainer: annotation.endcontainer, endOffset: parseInt(annotation.endoffset)},\n {type: \"TextPositionSelector\", start: parseInt(annotation.start), end: parseInt(annotation.end)},\n {type: \"TextQuoteSelector\", exact: annotation.exact, prefix: annotation.prefix, suffix: annotation.suffix}\n ]];\n\n const target = rangeSelectors.map(selectors => ({\n selector: selectors,\n }));\n\n /** @type {AnnotationData} */\n const newannotation = {\n annotation: annotation,\n target: target,\n };\n\n anchor(newannotation, $(\"#entry-\" + annotation.entry)[0]);\n }\n }\n\n /**\n * Edit annotation.\n *\n * @param {int} annotationid\n */\n function editAnnotation(annotationid) {\n\n if (edited == annotationid) {\n removeAllTempHighlights(); // Remove other temporary highlights.\n resetForms(); // Remove old form contents.\n edited = false;\n } else if (canmakeannotations && myuserid == annotations[annotationid].userid) {\n removeAllTempHighlights(); // Remove other temporary highlights.\n resetForms(); // Remove old form contents.\n\n edited = annotationid;\n\n var entry = annotations[annotationid].entry;\n\n $('.annotation-box-' + annotationid).hide(); // Hide edited annotation-box.\n\n $('.annotation-form-' + entry + ' input[name=\"startcontainer\"]').val(annotations[annotationid].startcontainer);\n $('.annotation-form-' + entry + ' input[name=\"endcontainer\"]').val(annotations[annotationid].endcontainer);\n $('.annotation-form-' + entry + ' input[name=\"startoffset\"]').val(annotations[annotationid].startoffset);\n $('.annotation-form-' + entry + ' input[name=\"endoffset\"]').val(annotations[annotationid].endoffset);\n $('.annotation-form-' + entry + ' input[name=\"start\"]').val(annotations[annotationid].start);\n $('.annotation-form-' + entry + ' input[name=\"end\"]').val(annotations[annotationid].end);\n $('.annotation-form-' + entry + ' input[name=\"exact\"]').val(annotations[annotationid].exact);\n $('.annotation-form-' + entry + ' input[name=\"prefix\"]').val(annotations[annotationid].prefix);\n $('.annotation-form-' + entry + ' input[name=\"suffix\"]').val(annotations[annotationid].suffix);\n\n $('.annotation-form-' + entry + ' input[name=\"annotationid\"]').val(annotationid);\n\n $('.annotation-form-' + entry + ' textarea[name=\"text\"]').val(annotations[annotationid].text);\n\n $('.annotation-form-' + entry + ' select').val(annotations[annotationid].type);\n\n // Prevent JavaScript injection (if annotated text in original entry is JavaScript code in script tags).\n $('#annotationpreview-temp-' + entry).html(\n annotations[annotationid].exact.replaceAll('<', '<').replaceAll('>', '>'));\n $('#annotationpreview-temp-' + entry).css('border-color', '#' + annotations[annotationid].color);\n\n $('.annotationarea-' + entry + ' .annotation-form').insertBefore('.annotation-box-' + annotationid);\n $('.annotationarea-' + entry + ' .annotation-form').show();\n $('.annotationarea-' + entry + ' #id_text').focus();\n } else {\n $('.annotation-box-' + annotationid).focus();\n }\n }\n\n /**\n * Reset all annotation forms\n */\n function resetForms() {\n $('.annotation-form').hide();\n\n $('.annotation-form input[name^=\"annotationid\"]').val(null);\n\n $('.annotation-form input[name^=\"startcontainer\"]').val(-1);\n $('.annotation-form input[name^=\"endcontainer\"]').val(-1);\n $('.annotation-form input[name^=\"startoffset\"]').val(-1);\n $('.annotation-form input[name^=\"endoffset\"]').val(-1);\n\n $('.annotation-form textarea[name^=\"text\"]').val('');\n\n $('.annotation-box').not('.annotation-form').show(); // To show again edited annotation.\n }\n};\n\n/**\n * Create a new annotation that is associated with the selected region of\n * the current document.\n *\n * @param {object} root - The root element\n * @return {object} - The new annotation\n */\nfunction createAnnotation(root) {\n const ranges = [window.getSelection().getRangeAt(0)];\n\n if (ranges.collapsed) {\n return null;\n }\n\n const rangeSelectors = ranges.map(range => describe(root, range));\n\n const target = rangeSelectors.map(selectors => ({\n selector: selectors,\n }));\n\n /** @type {AnnotationData} */\n const annotation = {\n target,\n };\n\n anchor(annotation, root);\n\n return annotation;\n}"],"file":"annotations.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/annotations.js"],"names":["init","cmid","canmakeannotations","myuserid","focusannotation","edited","annotations","newannotation","removeClass","document","on","e","preventDefault","resetForms","keypress","which","parents","submit","selectedrange","window","getSelection","getRangeAt","cloneContents","textContent","createAnnotation","entry","id","replace","val","target","selector","startContainer","endContainer","startOffset","endOffset","start","end","exact","prefix","suffix","html","replaceAll","show","focus","$","ajax","url","data","success","response","JSON","parse","recreateAnnotations","mouseenter","addClass","css","mouseleave","editAnnotation","attr","complete","hide","error","Object","values","annotation","rangeSelectors","type","startcontainer","parseInt","startoffset","endcontainer","endoffset","map","selectors","annotationid","userid","text","color","insertBefore","not","root","ranges","collapsed","range"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Module for the annotation functions of the margic.\n *\n * @module mod_margic/annotations\n * @copyright 2022 coactum GmbH\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport {removeAllTempHighlights, anchor, describe} from './highlighting';\n\nexport const init = (cmid, canmakeannotations, myuserid, focusannotation) => {\n\n var edited = false;\n var annotations = Array();\n\n var newannotation = false;\n\n // Remove col-mds from moodle form.\n $('.annotation-form div.col-md-3').removeClass('col-md-3');\n $('.annotation-form div.col-md-9').removeClass('col-md-9');\n $('.annotation-form div.form-group').removeClass('form-group');\n $('.annotation-form div.row').removeClass('row');\n\n // Onclick listener if form is canceled.\n $(document).on('click', '#id_cancel', function(e) {\n e.preventDefault();\n\n removeAllTempHighlights(); // Remove other temporary highlights.\n\n resetForms(); // Remove old form contents.\n\n edited = false;\n });\n\n // Listen for return key pressed to submit annotation form.\n $('textarea').keypress(function(e) {\n if (e.which == 13) {\n $(this).parents(':eq(2)').submit();\n e.preventDefault();\n }\n });\n\n // If user selects text for new annotation\n $(document).on('mouseup', '.originaltext', function() {\n var selectedrange = window.getSelection().getRangeAt(0);\n\n if (selectedrange.cloneContents().textContent !== '' && canmakeannotations) {\n\n removeAllTempHighlights(); // Remove other temporary highlights.\n\n resetForms(); // Reset the annotation forms.\n\n // Create new annotation.\n newannotation = createAnnotation(this);\n\n var entry = this.id.replace(/entry-/, '');\n\n // RangeSelector.\n $('.annotation-form-' + entry + ' input[name=\"startcontainer\"]').val(\n newannotation.target[0].selector[0].startContainer);\n $('.annotation-form-' + entry + ' input[name=\"endcontainer\"]').val(\n newannotation.target[0].selector[0].endContainer);\n $('.annotation-form-' + entry + ' input[name=\"startoffset\"]').val(\n newannotation.target[0].selector[0].startOffset);\n $('.annotation-form-' + entry + ' input[name=\"endoffset\"]').val(\n newannotation.target[0].selector[0].endOffset);\n\n // TextPositionSelector.\n $('.annotation-form-' + entry + ' input[name=\"start\"]').val(\n newannotation.target[0].selector[1].start);\n $('.annotation-form-' + entry + ' input[name=\"end\"]').val(\n newannotation.target[0].selector[1].end);\n\n // TextQuoteSelector.\n $('.annotation-form-' + entry + ' input[name=\"exact\"]').val(\n newannotation.target[0].selector[2].exact);\n $('.annotation-form-' + entry + ' input[name=\"prefix\"]').val(\n newannotation.target[0].selector[2].prefix);\n $('.annotation-form-' + entry + ' input[name=\"suffix\"]').val(\n newannotation.target[0].selector[2].suffix);\n\n $('.annotation-form-' + entry + ' select').val(1);\n\n // Prevent JavaScript injection (if annotated text in original entry is JavaScript code in script tags).\n $('#annotationpreview-temp-' + entry).html(\n newannotation.target[0].selector[2].exact.replaceAll('<', '<').replaceAll('>', '>'));\n\n $('.annotationarea-' + entry + ' .annotation-form').show();\n $('.annotation-form-' + entry + ' #id_text').focus();\n }\n });\n\n // Fetch and recreate annotations.\n $.ajax({\n url: './annotations.php',\n data: {'id': cmid, 'getannotations': 1},\n success: function(response) {\n annotations = JSON.parse(response);\n recreateAnnotations();\n\n // Highlight annotation and all annotated text if annotated text is hovered\n $('.annotated').mouseenter(function() {\n var id = this.id.replace('annotated-', '');\n $('.annotation-box-' + id).addClass('hovered');\n $('.annotated-' + id).css(\"background-color\", 'lightblue');\n });\n\n $('.annotated').mouseleave(function() {\n var id = this.id.replace('annotated-', '');\n $('.annotation-box-' + id).removeClass('hovered');\n $('.annotated-' + id).css(\"background-color\", $('.annotated-' + id).css('textDecorationColor'));\n });\n\n // Highlight whole temp annotation if part of temp annotation is hovered\n $(document).on('mouseover', '.annotated_temp', function() {\n $('.annotated_temp').addClass('hovered');\n });\n\n $(document).on('mouseleave', '.annotated_temp', function() {\n $('.annotated_temp').removeClass('hovered');\n });\n\n // Onclick listener for editing annotation.\n $(document).on('click', '.annotated', function() {\n var id = this.id.replace('annotated-', '');\n editAnnotation(id);\n });\n\n // Onclick listener for editing annotation.\n $(document).on('click', '.edit-annotation', function() {\n var id = this.id.replace('edit-annotation-', '');\n editAnnotation(id);\n });\n\n // Highlight annotation if hoverannotation button is hovered\n $(document).on('mouseover', '.hoverannotation', function() {\n var id = this.id.replace('hoverannotation-', '');\n $('.annotated-' + id).css(\"background-color\", 'lightblue');\n });\n\n $(document).on('mouseleave', '.hoverannotation', function() {\n var id = this.id.replace('hoverannotation-', '');\n $('.annotated-' + id).css(\"background-color\", $('.annotated-' + id).css('textDecorationColor'));\n });\n\n\n // Focus annotation if needed.\n if (focusannotation != 0) {\n $('.annotated-' + focusannotation).attr('tabindex', -1);\n $('.annotated-' + focusannotation).focus();\n }\n\n },\n complete: function() {\n $('#overlay').hide();\n },\n error: function() {\n // alert('Error fetching annotations');\n }\n });\n\n /**\n * Recreate annotations.\n *\n */\n function recreateAnnotations() {\n\n for (let annotation of Object.values(annotations)) {\n\n const rangeSelectors = [[\n {type: \"RangeSelector\", startContainer: annotation.startcontainer, startOffset: parseInt(annotation.startoffset),\n endContainer: annotation.endcontainer, endOffset: parseInt(annotation.endoffset)},\n {type: \"TextPositionSelector\", start: parseInt(annotation.start), end: parseInt(annotation.end)},\n {type: \"TextQuoteSelector\", exact: annotation.exact, prefix: annotation.prefix, suffix: annotation.suffix}\n ]];\n\n const target = rangeSelectors.map(selectors => ({\n selector: selectors,\n }));\n\n /** @type {AnnotationData} */\n const newannotation = {\n annotation: annotation,\n target: target,\n };\n\n anchor(newannotation, $(\"#entry-\" + annotation.entry)[0]);\n }\n }\n\n /**\n * Edit annotation.\n *\n * @param {int} annotationid\n */\n function editAnnotation(annotationid) {\n\n if (edited == annotationid) {\n removeAllTempHighlights(); // Remove other temporary highlights.\n resetForms(); // Remove old form contents.\n edited = false;\n } else if (canmakeannotations && myuserid == annotations[annotationid].userid) {\n removeAllTempHighlights(); // Remove other temporary highlights.\n resetForms(); // Remove old form contents.\n\n edited = annotationid;\n\n var entry = annotations[annotationid].entry;\n\n $('.annotation-box-' + annotationid).hide(); // Hide edited annotation-box.\n\n $('.annotation-form-' + entry + ' input[name=\"startcontainer\"]').val(annotations[annotationid].startcontainer);\n $('.annotation-form-' + entry + ' input[name=\"endcontainer\"]').val(annotations[annotationid].endcontainer);\n $('.annotation-form-' + entry + ' input[name=\"startoffset\"]').val(annotations[annotationid].startoffset);\n $('.annotation-form-' + entry + ' input[name=\"endoffset\"]').val(annotations[annotationid].endoffset);\n $('.annotation-form-' + entry + ' input[name=\"start\"]').val(annotations[annotationid].start);\n $('.annotation-form-' + entry + ' input[name=\"end\"]').val(annotations[annotationid].end);\n $('.annotation-form-' + entry + ' input[name=\"exact\"]').val(annotations[annotationid].exact);\n $('.annotation-form-' + entry + ' input[name=\"prefix\"]').val(annotations[annotationid].prefix);\n $('.annotation-form-' + entry + ' input[name=\"suffix\"]').val(annotations[annotationid].suffix);\n\n $('.annotation-form-' + entry + ' input[name=\"annotationid\"]').val(annotationid);\n\n $('.annotation-form-' + entry + ' textarea[name=\"text\"]').val(annotations[annotationid].text);\n\n $('.annotation-form-' + entry + ' select').val(annotations[annotationid].type);\n\n // Prevent JavaScript injection (if annotated text in original entry is JavaScript code in script tags).\n $('#annotationpreview-temp-' + entry).html(\n annotations[annotationid].exact.replaceAll('<', '<').replaceAll('>', '>'));\n $('#annotationpreview-temp-' + entry).css('border-color', '#' + annotations[annotationid].color);\n\n $('.annotationarea-' + entry + ' .annotation-form').insertBefore('.annotation-box-' + annotationid);\n $('.annotationarea-' + entry + ' .annotation-form').show();\n $('.annotationarea-' + entry + ' #id_text').focus();\n } else {\n $('.annotation-box-' + annotationid).focus();\n }\n }\n\n /**\n * Reset all annotation forms\n */\n function resetForms() {\n $('.annotation-form').hide();\n\n $('.annotation-form input[name^=\"annotationid\"]').val(null);\n\n $('.annotation-form input[name^=\"startcontainer\"]').val(-1);\n $('.annotation-form input[name^=\"endcontainer\"]').val(-1);\n $('.annotation-form input[name^=\"startoffset\"]').val(-1);\n $('.annotation-form input[name^=\"endoffset\"]').val(-1);\n\n $('.annotation-form textarea[name^=\"text\"]').val('');\n\n $('.annotation-box').not('.annotation-form').show(); // To show again edited annotation.\n }\n};\n\n/**\n * Create a new annotation that is associated with the selected region of\n * the current document.\n *\n * @param {object} root - The root element\n * @return {object} - The new annotation\n */\nfunction createAnnotation(root) {\n const ranges = [window.getSelection().getRangeAt(0)];\n\n if (ranges.collapsed) {\n return null;\n }\n\n const rangeSelectors = ranges.map(range => describe(root, range));\n\n const target = rangeSelectors.map(selectors => ({\n selector: selectors,\n }));\n\n /** @type {AnnotationData} */\n const annotation = {\n target,\n };\n\n anchor(annotation, root);\n\n return annotation;\n}"],"file":"annotations.min.js"} \ No newline at end of file diff --git a/amd/build/highlighting.min.js b/amd/build/highlighting.min.js index b982351..4dca152 100644 --- a/amd/build/highlighting.min.js +++ b/amd/build/highlighting.min.js @@ -1,2 +1,2 @@ -define ("mod_margic/highlighting",["exports","jquery","./types","./text-range"],function(a,b,c,d){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.describe=function(a,b){for(var d=[c.RangeAnchor,c.TextPositionAnchor,c.TextQuoteAnchor],e=[],f=0,g=d,h;f=a.length)return{done:!0};return{done:!1,value:a[b++]}},e:function e(a){throw a},f:c}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var d,e=!0,g=!1,h;return{s:function s(){d=a[Symbol.iterator]()},n:function n(){var a=d.next();e=a.done;return a},e:function e(a){g=!0;h=a},f:function f(){try{if(!e&&null!=d.return)d.return()}finally{if(g)throw h}}}}function f(a,b){if(!a)return;if("string"==typeof a)return g(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return g(a,b)}function g(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c=a.comparePoint(b,0)&&0<=a.comparePoint(b,e)}catch(a){return!1}}function l(a){var b=1=a.length)return{done:!0};return{done:!1,value:a[b++]}},e:function e(a){throw a},f:c}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var d,e=!0,g=!1,h;return{s:function s(){d=a[Symbol.iterator]()},n:function n(){var a=d.next();e=a.done;return a},e:function e(a){g=!0;h=a},f:function f(){try{if(!e&&null!=d.return)d.return()}finally{if(g)throw h}}}}function f(a,b){if(!a)return;if("string"==typeof a)return g(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return g(a,b)}function g(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c=a.comparePoint(b,0)&&0<=a.comparePoint(b,e)}catch(a){return!1}}function l(a){var b=1 {\n\n // Only annotations with an associated quote can currently be anchored.\n // This is because the quote is used to verify anchoring with other selector\n // types.\n if (\n !target.selector ||\n !target.selector.some(s => s.type === 'TextQuoteSelector')\n ) {\n return {annotation, target};\n }\n\n /** @type {Anchor} */\n let anchor;\n try {\n const range = htmlAnchor(root, target.selector);\n // Convert the `Range` to a `TextRange` which can be converted back to\n // a `Range` later. The `TextRange` representation allows for highlights\n // to be inserted during anchoring other annotations without \"breaking\"\n // this anchor.\n\n\n const textRange = TextRange.fromRange(range);\n\n anchor = {annotation, target, range: textRange};\n\n } catch (err) {\n\n anchor = {annotation, target};\n }\n\n return anchor;\n };\n\n /**\n * Highlight the text range that `anchor` refers to.\n *\n * @param {Anchor} anchor\n */\n const highlight = anchor => {\n\n const range = resolveAnchor(anchor);\n\n if (!range) {\n return;\n }\n\n let highlights = [];\n\n if (annotation.annotation) {\n highlights = highlightRange(range, annotation.annotation.id, 'annotated', annotation.annotation.color);\n } else {\n highlights = highlightRange(range, false, 'annotated_temp');\n }\n\n highlights.forEach(h => {\n h._annotation = anchor.annotation;\n });\n anchor.highlights = highlights;\n\n };\n\n // Remove existing anchors for this annotation.\n // this.detach(annotation, false /* notify */); // To be replaced by own method\n\n // Resolve selectors to ranges and insert highlights.\n if (!annotation.target) {\n annotation.target = [];\n }\n const anchors = annotation.target.map(locate);\n\n for (let anchor of anchors) {\n\n highlight(anchor);\n }\n\n // Set flag indicating whether anchoring succeeded. For each target,\n // anchoring is successful either if there are no selectors (ie. this is a\n // Page Note) or we successfully resolved the selectors to a range.\n annotation.$orphan =\n anchors.length > 0 &&\n anchors.every(anchor => anchor.target.selector && !anchor.range);\n\n return anchors;\n}\n\n/**\n * Resolve an anchor's associated document region to a concrete `Range`.\n *\n * This may fail if anchoring failed or if the document has been mutated since\n * the anchor was created in a way that invalidates the anchor.\n *\n * @param {Anchor} anchor\n * @return {Range|null}\n */\nfunction resolveAnchor(anchor) {\n\n if (!anchor.range) {\n return null;\n }\n try {\n return anchor.range.toRange();\n } catch {\n return null;\n }\n}\n\n/**\n * Wraps the DOM Nodes within the provided range with a highlight\n * element of the specified class and returns the highlight Elements.\n *\n * Modified for handling annotations.\n *\n * @param {Range} range - Range to be highlighted\n * @param {int} annotationid - ID of annotation\n * @param {string} cssClass - A CSS class to use for the highlight\n * @param {string} color - Color of the highlighting\n * @return {HighlightElement[]} - Elements wrapping text in `normedRange` to add a highlight effect\n */\n function highlightRange(range, annotationid = false, cssClass = 'annotated', color = 'FFFF00') {\n\n const textNodes = wholeTextNodesInRange(range);\n\n // Group text nodes into spans of adjacent nodes. If a group of text nodes are\n // adjacent, we only need to create one highlight element for the group.\n let textNodeSpans = [];\n let prevNode = null;\n let currentSpan = null;\n\n textNodes.forEach(node => {\n if (prevNode && prevNode.nextSibling === node) {\n currentSpan.push(node);\n } else {\n currentSpan = [node];\n textNodeSpans.push(currentSpan);\n }\n prevNode = node;\n });\n\n // Filter out text node spans that consist only of white space. This avoids\n // inserting highlight elements in places that can only contain a restricted\n // subset of nodes such as table rows and lists.\n const whitespace = /^\\s*$/;\n textNodeSpans = textNodeSpans.filter(span =>\n // Check for at least one text node with non-space content.\n span.some(node => !whitespace.test(node.nodeValue))\n );\n\n // Wrap each text node span with a `` element.\n const highlights = /** @type {HighlightElement[]} */ ([]);\n\n textNodeSpans.forEach(nodes => {\n const highlightEl = document.createElement('margic-highlight');\n highlightEl.className = cssClass;\n\n if (annotationid) {\n highlightEl.className += ' ' + cssClass + '-' + annotationid;\n highlightEl.style = \"text-decoration:underline; text-decoration-color: #\" + color;\n highlightEl.id = cssClass + '-' + annotationid;\n highlightEl.style.backgroundColor = '#' + color;\n }\n\n const parent = /** @type {Node} */ (nodes[0].parentNode);\n parent.replaceChild(highlightEl, nodes[0]);\n nodes.forEach(node => highlightEl.appendChild(node));\n\n highlights.push(highlightEl);\n\n });\n\n return highlights;\n}\n\n/**\n * Return text nodes which are entirely inside `range`.\n *\n * If a range starts or ends part-way through a text node, the node is split\n * and the part inside the range is returned.\n *\n * @param {Range} range\n * @return {Text[]}\n */\n function wholeTextNodesInRange(range) {\n if (range.collapsed) {\n // Exit early for an empty range to avoid an edge case that breaks the algorithm\n // below. Splitting a text node at the start of an empty range can leave the\n // range ending in the left part rather than the right part.\n return [];\n }\n\n /** @type {Node|null} */\n let root = range.commonAncestorContainer;\n if (root.nodeType !== Node.ELEMENT_NODE) {\n // If the common ancestor is not an element, set it to the parent element to\n // ensure that the loop below visits any text nodes generated by splitting\n // the common ancestor.\n //\n // Note that `parentElement` may be `null`.\n root = root.parentElement;\n }\n\n if (!root) {\n // If there is no root element then we won't be able to insert highlights,\n // so exit here.\n return [];\n }\n\n const textNodes = [];\n const nodeIter = /** @type {Document} */ (\n root.ownerDocument\n ).createNodeIterator(\n root,\n NodeFilter.SHOW_TEXT // Only return `Text` nodes.\n );\n let node;\n while ((node = nodeIter.nextNode())) {\n if (!isNodeInRange(range, node)) {\n continue;\n }\n let text = /** @type {Text} */ (node);\n\n if (text === range.startContainer && range.startOffset > 0) {\n // Split `text` where the range starts. The split will create a new `Text`\n // node which will be in the range and will be visited in the next loop iteration.\n text.splitText(range.startOffset);\n continue;\n }\n\n if (text === range.endContainer && range.endOffset < text.data.length) {\n // Split `text` where the range ends, leaving it as the part in the range.\n text.splitText(range.endOffset);\n }\n\n textNodes.push(text);\n }\n\n return textNodes;\n}\n\n/**\n * Returns true if any part of `node` lies within `range`.\n *\n * @param {Range} range\n * @param {Node} node\n * @return {bool} - If node is in range\n */\nfunction isNodeInRange(range, node) {\n try {\n const length = node.nodeValue?.length ?? node.childNodes.length;\n return (\n // Check start of node is before end of range.\n range.comparePoint(node, 0) <= 0 &&\n // Check end of node is after start of range.\n range.comparePoint(node, length) >= 0\n );\n } catch (e) {\n // `comparePoint` may fail if the `range` and `node` do not share a common\n // ancestor or `node` is a doctype.\n return false;\n }\n}\n\n/**\n * @param {RangeAnchor|TextPositionAnchor|TextQuoteAnchor} anchor\n * @param {Object} [options]\n * @return {obj} - range\n */\n function querySelector(anchor, options = {}) {\n\n return anchor.toRange(options);\n}\n\n/**\n * Anchor a set of selectors.\n *\n * This function converts a set of selectors into a document range.\n * It encapsulates the core anchoring algorithm, using the selectors alone or\n * in combination to establish the best anchor within the document.\n *\n * @param {Element} root - The root element of the anchoring context.\n * @param {Selector[]} selectors - The selectors to try.\n * @param {Object} [options]\n * @return {object} the query selector\n */\n function htmlAnchor(root, selectors, options = {}) {\n let position = null;\n let quote = null;\n let range = null;\n\n // Collect all the selectors\n for (let selector of selectors) {\n switch (selector.type) {\n case 'TextPositionSelector':\n position = selector;\n options.hint = position.start; // TextQuoteAnchor hint\n break;\n case 'TextQuoteSelector':\n quote = selector;\n break;\n case 'RangeSelector':\n range = selector;\n break;\n }\n }\n\n /**\n * Assert the quote matches the stored quote, if applicable\n * @param {Range} range\n * @return {Range} range\n */\n const maybeAssertQuote = range => {\n\n if (quote?.exact && range.toString() !== quote.exact) {\n throw new Error('quote mismatch');\n } else {\n return range;\n }\n };\n\n let queryselector = false;\n\n try {\n if (range) {\n\n let anchor = RangeAnchor.fromSelector(root, range);\n\n queryselector = querySelector(anchor, options);\n\n if (queryselector) {\n return queryselector;\n } else {\n return maybeAssertQuote;\n }\n }\n } catch (error) {\n try {\n if (position) {\n\n let anchor = TextPositionAnchor.fromSelector(root, position);\n\n queryselector = querySelector(anchor, options);\n if (queryselector) {\n return queryselector;\n } else {\n return maybeAssertQuote;\n }\n }\n } catch (error) {\n try {\n if (quote) {\n\n let anchor = TextQuoteAnchor.fromSelector(root, quote);\n\n queryselector = querySelector(anchor, options);\n\n return queryselector;\n }\n } catch (error) {\n return false;\n }\n }\n }\n}\n\n/**\n * Remove all temporary highlights under a given root element.\n */\n export function removeAllTempHighlights() {\n const highlights = Array.from($('body')[0].querySelectorAll('.annotated_temp'));\n if (highlights !== undefined && highlights.length != 0) {\n removeHighlights(highlights);\n }\n}\n\n/**\n * Remove highlights from a range previously highlighted with `highlightRange`.\n *\n * @param {HighlightElement[]} highlights - The highlight elements returned by `highlightRange`\n */\n function removeHighlights(highlights) {\n\n for (var i = 0; i < highlights.length; i++) {\n if (highlights[i].parentNode) {\n const children = Array.from(highlights[i].childNodes);\n replaceWith(highlights[i], children);\n }\n }\n}\n\n/**\n * Replace a child `node` with `replacements`.\n *\n * nb. This is like `ChildNode.replaceWith` but it works in older browsers.\n *\n * @param {ChildNode} node\n * @param {Node[]} replacements\n */\nfunction replaceWith(node, replacements) {\n const parent = /** @type {Node} */ (node.parentNode);\n\n replacements.forEach(r => parent.insertBefore(r, node));\n node.remove();\n}"],"file":"highlighting.min.js"} \ No newline at end of file +{"version":3,"sources":["../src/highlighting.js"],"names":["root","range","types","RangeAnchor","TextPositionAnchor","TextQuoteAnchor","result","type","anchor","fromRange","push","toSelector","error","annotation","highlight","resolveAnchor","highlights","highlightRange","id","color","forEach","h","_annotation","target","anchors","map","locate","selector","some","s","htmlAnchor","textRange","TextRange","err","$orphan","length","every","toRange","annotationid","cssClass","textNodes","wholeTextNodesInRange","textNodeSpans","prevNode","currentSpan","node","nextSibling","filter","span","test","nodeValue","nodes","highlightEl","document","createElement","className","style","backgroundColor","parent","parentNode","replaceChild","appendChild","collapsed","commonAncestorContainer","nodeType","Node","ELEMENT_NODE","parentElement","nodeIter","ownerDocument","createNodeIterator","NodeFilter","SHOW_TEXT","nextNode","isNodeInRange","text","startContainer","startOffset","splitText","endContainer","endOffset","data","childNodes","comparePoint","e","querySelector","options","selectors","position","quote","hint","start","maybeAssertQuote","exact","toString","Error","queryselector","fromSelector","removeAllTempHighlights","Array","from","querySelectorAll","removeHighlights","i","children","replaceWith","replacements","r","insertBefore","remove"],"mappings":"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","sourcesContent":["/**\n * Functions for the highlighting and anchoring of annotations.\n *\n * This code originaly is from the Hypothesis project (https://github.com/hypothesis/client)\n * which is released under the 2-Clause BSD License (https://opensource.org/licenses/BSD-2-Clause),\n * sometimes referred to as the \"Simplified BSD License\".\n */\n\nimport $ from 'jquery';\nimport {RangeAnchor, TextPositionAnchor, TextQuoteAnchor} from './types';\nimport {TextRange} from './text-range';\n\n/**\n * Get anchors for new annnotation.\n *\n * @param {Element} root\n * @param {Range} range\n * @return {object} - Array with the anchors.\n */\nexport function describe(root, range) {\n const types = [RangeAnchor, TextPositionAnchor, TextQuoteAnchor];\n const result = [];\n\n for (let type of types) {\n try {\n const anchor = type.fromRange(root, range);\n\n result.push(anchor.toSelector());\n } catch (error) {\n continue;\n }\n }\n return result;\n}\n\n/**\n * Anchor an annotation's selectors in the document.\n *\n * _Anchoring_ resolves a set of selectors to a concrete region of the document\n * which is then highlighted.\n *\n * Any existing anchors associated with `annotation` will be removed before\n * re-anchoring the annotation.\n *\n * @param {AnnotationData} annotation\n * @param {obj} root\n * @return {obj} achor object\n */\n export function anchor(annotation, root) {\n /**\n * Resolve an annotation's selectors to a concrete range.\n *\n * @param {Target} target\n * @return {obj}\n */\n const locate = target => {\n\n // Only annotations with an associated quote can currently be anchored.\n // This is because the quote is used to verify anchoring with other selector\n // types.\n if (\n !target.selector ||\n !target.selector.some(s => s.type === 'TextQuoteSelector')\n ) {\n return {annotation, target};\n }\n\n /** @type {Anchor} */\n let anchor;\n try {\n const range = htmlAnchor(root, target.selector);\n // Convert the `Range` to a `TextRange` which can be converted back to\n // a `Range` later. The `TextRange` representation allows for highlights\n // to be inserted during anchoring other annotations without \"breaking\"\n // this anchor.\n\n\n const textRange = TextRange.fromRange(range);\n\n anchor = {annotation, target, range: textRange};\n\n } catch (err) {\n\n anchor = {annotation, target};\n }\n\n return anchor;\n };\n\n /**\n * Highlight the text range that `anchor` refers to.\n *\n * @param {Anchor} anchor\n */\n const highlight = anchor => {\n\n const range = resolveAnchor(anchor);\n\n if (!range) {\n return;\n }\n\n let highlights = [];\n\n if (annotation.annotation) {\n highlights = highlightRange(range, annotation.annotation.id, 'annotated', annotation.annotation.color);\n } else {\n highlights = highlightRange(range, false, 'annotated_temp');\n }\n\n highlights.forEach(h => {\n h._annotation = anchor.annotation;\n });\n anchor.highlights = highlights;\n\n };\n\n // Remove existing anchors for this annotation.\n // this.detach(annotation, false /* notify */); // To be replaced by own method\n\n // Resolve selectors to ranges and insert highlights.\n if (!annotation.target) {\n annotation.target = [];\n }\n const anchors = annotation.target.map(locate);\n\n for (let anchor of anchors) {\n\n highlight(anchor);\n }\n\n // Set flag indicating whether anchoring succeeded. For each target,\n // anchoring is successful either if there are no selectors (ie. this is a\n // Page Note) or we successfully resolved the selectors to a range.\n annotation.$orphan =\n anchors.length > 0 &&\n anchors.every(anchor => anchor.target.selector && !anchor.range);\n\n return anchors;\n}\n\n/**\n * Resolve an anchor's associated document region to a concrete `Range`.\n *\n * This may fail if anchoring failed or if the document has been mutated since\n * the anchor was created in a way that invalidates the anchor.\n *\n * @param {Anchor} anchor\n * @return {Range|null}\n */\nfunction resolveAnchor(anchor) {\n\n if (!anchor.range) {\n return null;\n }\n try {\n return anchor.range.toRange();\n } catch {\n return null;\n }\n}\n\n/**\n * Wraps the DOM Nodes within the provided range with a highlight\n * element of the specified class and returns the highlight Elements.\n *\n * Modified for handling annotations.\n *\n * @param {Range} range - Range to be highlighted\n * @param {int} annotationid - ID of annotation\n * @param {string} cssClass - A CSS class to use for the highlight\n * @param {string} color - Color of the highlighting\n * @return {HighlightElement[]} - Elements wrapping text in `normedRange` to add a highlight effect\n */\n function highlightRange(range, annotationid = false, cssClass = 'annotated', color = 'FFFF00') {\n\n const textNodes = wholeTextNodesInRange(range);\n\n // Group text nodes into spans of adjacent nodes. If a group of text nodes are\n // adjacent, we only need to create one highlight element for the group.\n let textNodeSpans = [];\n let prevNode = null;\n let currentSpan = null;\n\n textNodes.forEach(node => {\n if (prevNode && prevNode.nextSibling === node) {\n currentSpan.push(node);\n } else {\n currentSpan = [node];\n textNodeSpans.push(currentSpan);\n }\n prevNode = node;\n });\n\n // Filter out text node spans that consist only of white space. This avoids\n // inserting highlight elements in places that can only contain a restricted\n // subset of nodes such as table rows and lists.\n const whitespace = /^\\s*$/;\n textNodeSpans = textNodeSpans.filter(span =>\n // Check for at least one text node with non-space content.\n span.some(node => !whitespace.test(node.nodeValue))\n );\n\n // Wrap each text node span with a `` element.\n const highlights = /** @type {HighlightElement[]} */ ([]);\n\n textNodeSpans.forEach(nodes => {\n const highlightEl = document.createElement('margic-highlight');\n highlightEl.className = cssClass;\n\n if (annotationid) {\n highlightEl.className += ' ' + cssClass + '-' + annotationid;\n highlightEl.style = \"text-decoration:underline; text-decoration-color: #\" + color;\n highlightEl.id = cssClass + '-' + annotationid;\n highlightEl.style.backgroundColor = '#' + color;\n }\n\n const parent = /** @type {Node} */ (nodes[0].parentNode);\n parent.replaceChild(highlightEl, nodes[0]);\n nodes.forEach(node => highlightEl.appendChild(node));\n\n highlights.push(highlightEl);\n\n });\n\n return highlights;\n}\n\n/**\n * Return text nodes which are entirely inside `range`.\n *\n * If a range starts or ends part-way through a text node, the node is split\n * and the part inside the range is returned.\n *\n * @param {Range} range\n * @return {Text[]}\n */\n function wholeTextNodesInRange(range) {\n if (range.collapsed) {\n // Exit early for an empty range to avoid an edge case that breaks the algorithm\n // below. Splitting a text node at the start of an empty range can leave the\n // range ending in the left part rather than the right part.\n return [];\n }\n\n /** @type {Node|null} */\n let root = range.commonAncestorContainer;\n if (root.nodeType !== Node.ELEMENT_NODE) {\n // If the common ancestor is not an element, set it to the parent element to\n // ensure that the loop below visits any text nodes generated by splitting\n // the common ancestor.\n //\n // Note that `parentElement` may be `null`.\n root = root.parentElement;\n }\n\n if (!root) {\n // If there is no root element then we won't be able to insert highlights,\n // so exit here.\n return [];\n }\n\n const textNodes = [];\n const nodeIter = /** @type {Document} */ (\n root.ownerDocument\n ).createNodeIterator(\n root,\n NodeFilter.SHOW_TEXT // Only return `Text` nodes.\n );\n let node;\n while ((node = nodeIter.nextNode())) {\n if (!isNodeInRange(range, node)) {\n continue;\n }\n let text = /** @type {Text} */ (node);\n\n if (text === range.startContainer && range.startOffset > 0) {\n // Split `text` where the range starts. The split will create a new `Text`\n // node which will be in the range and will be visited in the next loop iteration.\n text.splitText(range.startOffset);\n continue;\n }\n\n if (text === range.endContainer && range.endOffset < text.data.length) {\n // Split `text` where the range ends, leaving it as the part in the range.\n text.splitText(range.endOffset);\n }\n\n textNodes.push(text);\n }\n\n return textNodes;\n}\n\n/**\n * Returns true if any part of `node` lies within `range`.\n *\n * @param {Range} range\n * @param {Node} node\n * @return {bool} - If node is in range\n */\nfunction isNodeInRange(range, node) {\n try {\n const length = node.nodeValue?.length ?? node.childNodes.length;\n return (\n // Check start of node is before end of range.\n range.comparePoint(node, 0) <= 0 &&\n // Check end of node is after start of range.\n range.comparePoint(node, length) >= 0\n );\n } catch (e) {\n // `comparePoint` may fail if the `range` and `node` do not share a common\n // ancestor or `node` is a doctype.\n return false;\n }\n}\n\n/**\n * @param {RangeAnchor|TextPositionAnchor|TextQuoteAnchor} anchor\n * @param {Object} [options]\n * @return {obj} - range\n */\n function querySelector(anchor, options = {}) {\n\n return anchor.toRange(options);\n}\n\n/**\n * Anchor a set of selectors.\n *\n * This function converts a set of selectors into a document range.\n * It encapsulates the core anchoring algorithm, using the selectors alone or\n * in combination to establish the best anchor within the document.\n *\n * @param {Element} root - The root element of the anchoring context.\n * @param {Selector[]} selectors - The selectors to try.\n * @param {Object} [options]\n * @return {object} the query selector\n */\n function htmlAnchor(root, selectors, options = {}) {\n let position = null;\n let quote = null;\n let range = null;\n\n // Collect all the selectors\n for (let selector of selectors) {\n switch (selector.type) {\n case 'TextPositionSelector':\n position = selector;\n options.hint = position.start; // TextQuoteAnchor hint\n break;\n case 'TextQuoteSelector':\n quote = selector;\n break;\n case 'RangeSelector':\n range = selector;\n break;\n }\n }\n\n /**\n * Assert the quote matches the stored quote, if applicable\n * @param {Range} range\n * @return {Range} range\n */\n const maybeAssertQuote = range => {\n\n if (quote?.exact && range.toString() !== quote.exact) {\n throw new Error('quote mismatch');\n } else {\n return range;\n }\n };\n\n let queryselector = false;\n\n try {\n if (range) {\n\n let anchor = RangeAnchor.fromSelector(root, range);\n\n queryselector = querySelector(anchor, options);\n\n if (queryselector) {\n return queryselector;\n } else {\n return maybeAssertQuote;\n }\n }\n } catch (error) {\n try {\n if (position) {\n\n let anchor = TextPositionAnchor.fromSelector(root, position);\n\n queryselector = querySelector(anchor, options);\n if (queryselector) {\n return queryselector;\n } else {\n return maybeAssertQuote;\n }\n }\n } catch (error) {\n try {\n if (quote) {\n\n let anchor = TextQuoteAnchor.fromSelector(root, quote);\n\n queryselector = querySelector(anchor, options);\n\n return queryselector;\n }\n } catch (error) {\n return false;\n }\n }\n }\n return false;\n}\n\n/**\n * Remove all temporary highlights under a given root element.\n */\n export function removeAllTempHighlights() {\n const highlights = Array.from($('body')[0].querySelectorAll('.annotated_temp'));\n if (highlights !== undefined && highlights.length != 0) {\n removeHighlights(highlights);\n }\n}\n\n/**\n * Remove highlights from a range previously highlighted with `highlightRange`.\n *\n * @param {HighlightElement[]} highlights - The highlight elements returned by `highlightRange`\n */\n function removeHighlights(highlights) {\n\n for (var i = 0; i < highlights.length; i++) {\n if (highlights[i].parentNode) {\n const children = Array.from(highlights[i].childNodes);\n replaceWith(highlights[i], children);\n }\n }\n}\n\n/**\n * Replace a child `node` with `replacements`.\n *\n * nb. This is like `ChildNode.replaceWith` but it works in older browsers.\n *\n * @param {ChildNode} node\n * @param {Node[]} replacements\n */\nfunction replaceWith(node, replacements) {\n const parent = /** @type {Node} */ (node.parentNode);\n\n replacements.forEach(r => parent.insertBefore(r, node));\n node.remove();\n}"],"file":"highlighting.min.js"} \ No newline at end of file diff --git a/amd/src/annotations.js b/amd/src/annotations.js index d5f39e3..b63695e 100644 --- a/amd/src/annotations.js +++ b/amd/src/annotations.js @@ -171,7 +171,7 @@ export const init = (cmid, canmakeannotations, myuserid, focusannotation) => { $('#overlay').hide(); }, error: function() { - alert('Error fetching annotations'); + // alert('Error fetching annotations'); } }); diff --git a/amd/src/highlighting.js b/amd/src/highlighting.js index 516093b..a129b8d 100644 --- a/amd/src/highlighting.js +++ b/amd/src/highlighting.js @@ -415,6 +415,7 @@ function isNodeInRange(range, node) { } } } + return false; } /** diff --git a/templates/margic_childentry.mustache b/templates/margic_childentry.mustache index e72d196..664e9d2 100644 --- a/templates/margic_childentry.mustache +++ b/templates/margic_childentry.mustache @@ -20,6 +20,10 @@ Template for single child entry. + Example context (json): + { + } + }}
diff --git a/templates/margic_entry.mustache b/templates/margic_entry.mustache index 123c42d..faf13e3 100644 --- a/templates/margic_entry.mustache +++ b/templates/margic_entry.mustache @@ -19,6 +19,10 @@ @template margic/margic_entry Template for single entry. + + Example context (json): + { + } }} {{#needsclasses}} diff --git a/templates/margic_error_summary.mustache b/templates/margic_error_summary.mustache index b075e64..8fb7291 100644 --- a/templates/margic_error_summary.mustache +++ b/templates/margic_error_summary.mustache @@ -19,6 +19,10 @@ @template margic/margic_error_summary Annotations summary. + + Example context (json): + { + } }}
diff --git a/templates/margic_view.mustache b/templates/margic_view.mustache index cef7a6c..f6c7102 100644 --- a/templates/margic_view.mustache +++ b/templates/margic_view.mustache @@ -19,6 +19,10 @@ @template margic/margic_view Overview. + + Example context (json): + { + } }}