diff --git a/amd/build/append_fourm_post.min.js b/amd/build/append_fourm_post.min.js index 7b9da09b..01949eb2 100644 --- a/amd/build/append_fourm_post.min.js +++ b/amd/build/append_fourm_post.min.js @@ -1,3 +1,3 @@ -define("tiny_cursive/append_fourm_post",["jquery","core/ajax","core/str","core/templates","./replay","./analytic_button","./replay_button","./analytic_events"],(function($,AJAX,str,templates,Replay,analyticButton,replayButton,AnalyticEvents){const replayInstances={};window.video_playback=function(mid,filepath){if(""!==filepath){const replay=new Replay("content"+mid,filepath,10,!1,"player_"+mid);replayInstances[mid]=replay}else templates.render("tiny_cursive/no_submission").then((html=>($("#content"+mid).html(html),!0))).catch((e=>window.console.error(e)));return!1};var usersTable={init:function(scoreSetting,showcomment,hasApiKey){str.get_strings([{key:"field_require",component:"tiny_cursive"}]).done((function(){usersTable.getToken(scoreSetting,showcomment,hasApiKey)}))},getToken:function(scoreSetting,showcomment,hasApiKey){$("#page-mod-forum-discuss").find("article").get().forEach((function(entry){var replyButton=$('a[data-region="post-action"][title="Reply"]');replyButton.length>0&&replyButton.on("click",(function(event){if($("#body").hasClass("teacher_admin"))return!0;event.preventDefault();var urlParts=$(this).attr("href").split("#"),baseUrl=urlParts[0],hash=urlParts.length>1?"#"+urlParts[1]:"";baseUrl.indexOf("setformat=")>-1?baseUrl=baseUrl.replace(/setformat=\d/,"setformat=1"):baseUrl.indexOf("?")>-1?baseUrl+="&setformat=1":baseUrl+="?setformat=1";var finalUrl=baseUrl+hash;window.location.href=finalUrl}));var ids=$("#"+entry.id).data("post-id"),cmid=M.cfg.contextInstanceId;let args={id:ids,modulename:"forum",cmid:cmid},com=AJAX.call([{methodname:"cursive_get_forum_comment_link",args:args}]);return com[0].done((function(json){var data=JSON.parse(json),filepath="";if(data.data.filename&&(filepath=data.data.filename),filepath){let analyticButtonDiv=document.createElement("div");hasApiKey?analyticButtonDiv.append(analyticButton(data.data.effort_ratio,ids)):$(analyticButtonDiv).html(replayButton(ids)),analyticButtonDiv.classList.add("text-center","my-2"),analyticButtonDiv.dataset.region="analytic-div"+ids,$("#"+entry.id).find("#post-content-"+ids).prepend(analyticButtonDiv);let myEvents=new AnalyticEvents;var context={tabledata:data.data,formattime:myEvents.formatedTime(data.data),page:scoreSetting,userid:ids,apikey:hasApiKey};let authIcon=myEvents.authorshipStatus(data.data.first_file,data.data.score,scoreSetting);myEvents.createModal(ids,context,"",replayInstances,authIcon),myEvents.analytics(ids,templates,context,"",replayInstances,authIcon),myEvents.checkDiff(ids,data.data.file_id,"",replayInstances),myEvents.replyWriting(ids,filepath,"",replayInstances)}})),com.usercomment}))}};return usersTable})); +define("tiny_cursive/append_fourm_post",["jquery","core/ajax","core/str","core/templates","./replay","./analytic_button","./replay_button","./analytic_events"],(function($,AJAX,str,templates,Replay,analyticButton,replayButton,AnalyticEvents){const replayInstances={};window.video_playback=function(mid,filepath){if(""!==filepath){const replay=new Replay("content"+mid,filepath,10,!1,"player_"+mid);replayInstances[mid]=replay}else templates.render("tiny_cursive/no_submission").then((html=>($("#content"+mid).html(html),!0))).catch((e=>window.console.error(e)));return!1};var usersTable={init:function(scoreSetting,showcomment,hasApiKey){str.get_strings([{key:"field_require",component:"tiny_cursive"}]).done((function(){usersTable.getToken(scoreSetting,showcomment,hasApiKey)}))},getToken:function(scoreSetting,showcomment,hasApiKey){$("#page-mod-forum-discuss").find("article").get().forEach((function(entry){var replyButton=$('a[data-region="post-action"][title="Reply"]');replyButton.length>0&&replyButton.on("click",(function(event){if(!$("#body").hasClass("teacher_admin")){event.preventDefault();var urlParts=$(this).attr("href").split("#"),baseUrl=urlParts[0],hash=urlParts.length>1?"#"+urlParts[1]:"";baseUrl.indexOf("setformat=")>-1?baseUrl=baseUrl.replace(/setformat=\d/,"setformat=1"):baseUrl.indexOf("?")>-1?baseUrl+="&setformat=1":baseUrl+="?setformat=1";var finalUrl=baseUrl+hash;window.location.href=finalUrl}}));var ids=$("#"+entry.id).data("post-id"),cmid=M.cfg.contextInstanceId;let args={id:ids,modulename:"forum",cmid:cmid},com=AJAX.call([{methodname:"cursive_get_forum_comment_link",args:args}]);return com[0].done((function(json){var data=JSON.parse(json),filepath="";if(data.data.filename&&(filepath=data.data.filename),filepath){let analyticButtonDiv=document.createElement("div");hasApiKey?analyticButtonDiv.append(analyticButton(data.data.effort_ratio,ids)):$(analyticButtonDiv).html(replayButton(ids)),analyticButtonDiv.classList.add("text-center","my-2"),analyticButtonDiv.dataset.region="analytic-div"+ids,$("#"+entry.id).find("#post-content-"+ids).prepend(analyticButtonDiv);let myEvents=new AnalyticEvents;var context={tabledata:data.data,formattime:myEvents.formatedTime(data.data),page:scoreSetting,userid:ids,apikey:hasApiKey};let authIcon=myEvents.authorshipStatus(data.data.first_file,data.data.score,scoreSetting);myEvents.createModal(ids,context,"",replayInstances,authIcon),myEvents.analytics(ids,templates,context,"",replayInstances,authIcon),myEvents.checkDiff(ids,data.data.file_id,"",replayInstances),myEvents.replyWriting(ids,filepath,"",replayInstances)}})),com.usercomment}))}};return usersTable})); //# sourceMappingURL=append_fourm_post.min.js.map \ No newline at end of file diff --git a/amd/build/append_fourm_post.min.js.map b/amd/build/append_fourm_post.min.js.map index bada2509..b46b3aa6 100644 --- a/amd/build/append_fourm_post.min.js.map +++ b/amd/build/append_fourm_post.min.js.map @@ -1 +1 @@ -{"version":3,"file":"append_fourm_post.min.js","sources":["../src/append_fourm_post.js"],"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 tiny_cursive/append_fourm_post\n * @category TinyMCE Editor\n * @copyright CTI \n * @author kuldeep singh \n */\n\ndefine([\"jquery\", \"core/ajax\", \"core/str\", \"core/templates\", \"./replay\", \"./analytic_button\",\n \"./replay_button\", \"./analytic_events\"], function(\n $,\n AJAX,\n str,\n templates,\n Replay,\n analyticButton,\n replayButton,\n AnalyticEvents\n) {\n const replayInstances = {};\n // eslint-disable-next-line camelcase\n window.video_playback = function(mid, filepath) {\n if (filepath !== '') {\n const replay = new Replay(\n 'content' + mid,\n filepath,\n 10,\n false,\n 'player_' + mid\n );\n replayInstances[mid] = replay;\n } else {\n templates.render('tiny_cursive/no_submission').then(html => {\n $('#content' + mid).html(html);\n return true;\n }).catch(e => window.console.error(e));\n }\n return false;\n\n };\n\n var usersTable = {\n init: function(scoreSetting, showcomment, hasApiKey) {\n str\n .get_strings([\n {key: \"field_require\", component: \"tiny_cursive\"},\n ])\n .done(function() {\n usersTable.getToken(scoreSetting, showcomment, hasApiKey);\n });\n },\n getToken: function(scoreSetting, showcomment, hasApiKey) {\n $('#page-mod-forum-discuss').find(\"article\").get().forEach(function(entry) {\n var replyButton = $('a[data-region=\"post-action\"][title=\"Reply\"]');\n if (replyButton.length > 0) {\n replyButton.on('click', function(event) {\n var isTeacher = $('#body').hasClass('teacher_admin');\n if (isTeacher) {\n return true;\n }\n event.preventDefault();\n var url = $(this).attr('href');\n\n var urlParts = url.split('#');\n var baseUrl = urlParts[0];\n var hash = urlParts.length > 1 ? '#' + urlParts[1] : '';\n\n if (baseUrl.indexOf('setformat=') > -1) {\n baseUrl = baseUrl.replace(/setformat=\\d/, 'setformat=1');\n } else if (baseUrl.indexOf('?') > -1) {\n baseUrl += '&setformat=1';\n } else {\n baseUrl += '?setformat=1';\n }\n var finalUrl = baseUrl + hash;\n\n window.location.href = finalUrl;\n });\n }\n\n var ids = $(\"#\" + entry.id).data(\"post-id\");\n var cmid = M.cfg.contextInstanceId;\n\n let args = {id: ids, modulename: \"forum\", cmid: cmid};\n let methodname = 'cursive_get_forum_comment_link';\n let com = AJAX.call([{methodname, args}]);\n com[0].done(function(json) {\n var data = JSON.parse(json);\n\n var filepath = '';\n if (data.data.filename) {\n filepath = data.data.filename;\n }\n if (filepath) {\n\n let analyticButtonDiv = document.createElement('div');\n\n if (!hasApiKey) {\n $(analyticButtonDiv).html(replayButton(ids));\n } else {\n analyticButtonDiv.append(analyticButton(data.data.effort_ratio, ids));\n }\n\n analyticButtonDiv.classList.add('text-center', 'my-2');\n analyticButtonDiv.dataset.region = \"analytic-div\" + ids;\n\n $(\"#\" + entry.id).find('#post-content-' + ids).prepend(analyticButtonDiv);\n\n let myEvents = new AnalyticEvents();\n var context = {\n tabledata: data.data,\n formattime: myEvents.formatedTime(data.data),\n page: scoreSetting,\n userid: ids,\n apikey: hasApiKey\n };\n\n let authIcon = myEvents.authorshipStatus(data.data.first_file, data.data.score, scoreSetting);\n myEvents.createModal(ids, context, '', replayInstances, authIcon);\n myEvents.analytics(ids, templates, context, '', replayInstances, authIcon);\n myEvents.checkDiff(ids, data.data.file_id, '', replayInstances);\n myEvents.replyWriting(ids, filepath, '', replayInstances);\n }\n\n });\n return com.usercomment;\n });\n },\n };\n return usersTable;\n\n\n});"],"names":["define","$","AJAX","str","templates","Replay","analyticButton","replayButton","AnalyticEvents","replayInstances","window","video_playback","mid","filepath","replay","render","then","html","catch","e","console","error","usersTable","init","scoreSetting","showcomment","hasApiKey","get_strings","key","component","done","getToken","find","get","forEach","entry","replyButton","length","on","event","hasClass","preventDefault","urlParts","this","attr","split","baseUrl","hash","indexOf","replace","finalUrl","location","href","ids","id","data","cmid","M","cfg","contextInstanceId","args","modulename","com","call","methodname","json","JSON","parse","filename","analyticButtonDiv","document","createElement","append","effort_ratio","classList","add","dataset","region","prepend","myEvents","context","tabledata","formattime","formatedTime","page","userid","apikey","authIcon","authorshipStatus","first_file","score","createModal","analytics","checkDiff","file_id","replyWriting","usercomment"],"mappings":"AAsBAA,wCAAO,CAAC,SAAU,YAAa,WAAY,iBAAkB,WAAY,oBACrE,kBAAmB,sBAAsB,SACzCC,EACAC,KACAC,IACAC,UACAC,OACAC,eACAC,aACAC,sBAEMC,gBAAkB,GAExBC,OAAOC,eAAiB,SAASC,IAAKC,aACjB,KAAbA,SAAiB,OACXC,OAAS,IAAIT,OACf,UAAYO,IACZC,SACA,IACA,EACA,UAAYD,KAEhBH,gBAAgBG,KAAOE,YAEvBV,UAAUW,OAAO,8BAA8BC,MAAKC,OAChDhB,EAAE,WAAaW,KAAKK,KAAKA,OAClB,KACRC,OAAMC,GAAKT,OAAOU,QAAQC,MAAMF,YAEhC,OAIPG,WAAa,CACbC,KAAM,SAASC,aAAcC,YAAaC,WACtCvB,IACKwB,YAAY,CACT,CAACC,IAAK,gBAAiBC,UAAW,kBAErCC,MAAK,WACFR,WAAWS,SAASP,aAAcC,YAAaC,eAG3DK,SAAU,SAASP,aAAcC,YAAaC,WAC1CzB,EAAE,2BAA2B+B,KAAK,WAAWC,MAAMC,SAAQ,SAASC,WAC5DC,YAAcnC,EAAE,+CAChBmC,YAAYC,OAAS,GACrBD,YAAYE,GAAG,SAAS,SAASC,UACbtC,EAAE,SAASuC,SAAS,wBAEzB,EAEXD,MAAME,qBAGFC,SAFMzC,EAAE0C,MAAMC,KAAK,QAEJC,MAAM,KACrBC,QAAUJ,SAAS,GACnBK,KAAOL,SAASL,OAAS,EAAI,IAAMK,SAAS,GAAK,GAEjDI,QAAQE,QAAQ,eAAiB,EACjCF,QAAUA,QAAQG,QAAQ,eAAgB,eACnCH,QAAQE,QAAQ,MAAQ,EAC/BF,SAAW,eAEXA,SAAW,mBAEXI,SAAWJ,QAAUC,KAEzBrC,OAAOyC,SAASC,KAAOF,gBAI3BG,IAAMpD,EAAE,IAAMkC,MAAMmB,IAAIC,KAAK,WAC7BC,KAAOC,EAAEC,IAAIC,sBAEbC,KAAO,CAACN,GAAID,IAAKQ,WAAY,QAASL,KAAMA,MAE5CM,IAAM5D,KAAK6D,KAAK,CAAC,CAACC,WADL,iCACiBJ,KAAAA,eAClCE,IAAI,GAAGhC,MAAK,SAASmC,UACbV,KAAOW,KAAKC,MAAMF,MAElBpD,SAAW,MACX0C,KAAKA,KAAKa,WACVvD,SAAW0C,KAAKA,KAAKa,UAErBvD,SAAU,KAENwD,kBAAoBC,SAASC,cAAc,OAE1C7C,UAGD2C,kBAAkBG,OAAOlE,eAAeiD,KAAKA,KAAKkB,aAAcpB,MAFhEpD,EAAEoE,mBAAmBpD,KAAKV,aAAa8C,MAK3CgB,kBAAkBK,UAAUC,IAAI,cAAe,QAC/CN,kBAAkBO,QAAQC,OAAS,eAAiBxB,IAEpDpD,EAAE,IAAMkC,MAAMmB,IAAItB,KAAK,iBAAmBqB,KAAKyB,QAAQT,uBAEnDU,SAAW,IAAIvE,mBACfwE,QAAU,CACVC,UAAW1B,KAAKA,KAChB2B,WAAYH,SAASI,aAAa5B,KAAKA,MACvC6B,KAAM5D,aACN6D,OAAQhC,IACRiC,OAAQ5D,eAGR6D,SAAWR,SAASS,iBAAiBjC,KAAKA,KAAKkC,WAAYlC,KAAKA,KAAKmC,MAAOlE,cAChFuD,SAASY,YAAYtC,IAAK2B,QAAS,GAAIvE,gBAAiB8E,UACxDR,SAASa,UAAUvC,IAAKjD,UAAW4E,QAAS,GAAIvE,gBAAiB8E,UACjER,SAASc,UAAUxC,IAAKE,KAAKA,KAAKuC,QAAS,GAAIrF,iBAC/CsE,SAASgB,aAAa1C,IAAKxC,SAAU,GAAIJ,qBAI1CqD,IAAIkC,wBAIhB1E"} \ No newline at end of file +{"version":3,"file":"append_fourm_post.min.js","sources":["../src/append_fourm_post.js"],"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 tiny_cursive/append_fourm_post\n * @category TinyMCE Editor\n * @copyright CTI \n * @author kuldeep singh \n */\n\ndefine([\"jquery\", \"core/ajax\", \"core/str\", \"core/templates\", \"./replay\", \"./analytic_button\",\n \"./replay_button\", \"./analytic_events\"], function(\n $,\n AJAX,\n str,\n templates,\n Replay,\n analyticButton,\n replayButton,\n AnalyticEvents\n) {\n const replayInstances = {};\n // eslint-disable-next-line camelcase\n window.video_playback = function(mid, filepath) {\n if (filepath !== '') {\n const replay = new Replay(\n 'content' + mid,\n filepath,\n 10,\n false,\n 'player_' + mid\n );\n replayInstances[mid] = replay;\n } else {\n templates.render('tiny_cursive/no_submission').then(html => {\n $('#content' + mid).html(html);\n return true;\n }).catch(e => window.console.error(e));\n }\n return false;\n\n };\n\n var usersTable = {\n init: function(scoreSetting, showcomment, hasApiKey) {\n str\n .get_strings([\n {key: \"field_require\", component: \"tiny_cursive\"},\n ])\n .done(function() {\n usersTable.getToken(scoreSetting, showcomment, hasApiKey);\n });\n },\n getToken: function(scoreSetting, showcomment, hasApiKey) {\n $('#page-mod-forum-discuss').find(\"article\").get().forEach(function(entry) {\n var replyButton = $('a[data-region=\"post-action\"][title=\"Reply\"]');\n if (replyButton.length > 0) {\n replyButton.on('click', function(event) {\n var isTeacher = $('#body').hasClass('teacher_admin');\n if (!isTeacher) {\n event.preventDefault();\n var url = $(this).attr('href');\n\n var urlParts = url.split('#');\n var baseUrl = urlParts[0];\n var hash = urlParts.length > 1 ? '#' + urlParts[1] : '';\n\n if (baseUrl.indexOf('setformat=') > -1) {\n baseUrl = baseUrl.replace(/setformat=\\d/, 'setformat=1');\n } else if (baseUrl.indexOf('?') > -1) {\n baseUrl += '&setformat=1';\n } else {\n baseUrl += '?setformat=1';\n }\n var finalUrl = baseUrl + hash;\n\n window.location.href = finalUrl;\n }\n\n });\n }\n\n var ids = $(\"#\" + entry.id).data(\"post-id\");\n var cmid = M.cfg.contextInstanceId;\n\n let args = {id: ids, modulename: \"forum\", cmid: cmid};\n let methodname = 'cursive_get_forum_comment_link';\n let com = AJAX.call([{methodname, args}]);\n com[0].done(function(json) {\n var data = JSON.parse(json);\n\n var filepath = '';\n if (data.data.filename) {\n filepath = data.data.filename;\n }\n if (filepath) {\n\n let analyticButtonDiv = document.createElement('div');\n\n if (!hasApiKey) {\n $(analyticButtonDiv).html(replayButton(ids));\n } else {\n analyticButtonDiv.append(analyticButton(data.data.effort_ratio, ids));\n }\n\n analyticButtonDiv.classList.add('text-center', 'my-2');\n analyticButtonDiv.dataset.region = \"analytic-div\" + ids;\n\n $(\"#\" + entry.id).find('#post-content-' + ids).prepend(analyticButtonDiv);\n\n let myEvents = new AnalyticEvents();\n var context = {\n tabledata: data.data,\n formattime: myEvents.formatedTime(data.data),\n page: scoreSetting,\n userid: ids,\n apikey: hasApiKey\n };\n\n let authIcon = myEvents.authorshipStatus(data.data.first_file, data.data.score, scoreSetting);\n myEvents.createModal(ids, context, '', replayInstances, authIcon);\n myEvents.analytics(ids, templates, context, '', replayInstances, authIcon);\n myEvents.checkDiff(ids, data.data.file_id, '', replayInstances);\n myEvents.replyWriting(ids, filepath, '', replayInstances);\n }\n\n });\n return com.usercomment;\n });\n },\n };\n return usersTable;\n\n\n});"],"names":["define","$","AJAX","str","templates","Replay","analyticButton","replayButton","AnalyticEvents","replayInstances","window","video_playback","mid","filepath","replay","render","then","html","catch","e","console","error","usersTable","init","scoreSetting","showcomment","hasApiKey","get_strings","key","component","done","getToken","find","get","forEach","entry","replyButton","length","on","event","hasClass","preventDefault","urlParts","this","attr","split","baseUrl","hash","indexOf","replace","finalUrl","location","href","ids","id","data","cmid","M","cfg","contextInstanceId","args","modulename","com","call","methodname","json","JSON","parse","filename","analyticButtonDiv","document","createElement","append","effort_ratio","classList","add","dataset","region","prepend","myEvents","context","tabledata","formattime","formatedTime","page","userid","apikey","authIcon","authorshipStatus","first_file","score","createModal","analytics","checkDiff","file_id","replyWriting","usercomment"],"mappings":"AAsBAA,wCAAO,CAAC,SAAU,YAAa,WAAY,iBAAkB,WAAY,oBACrE,kBAAmB,sBAAsB,SACzCC,EACAC,KACAC,IACAC,UACAC,OACAC,eACAC,aACAC,sBAEMC,gBAAkB,GAExBC,OAAOC,eAAiB,SAASC,IAAKC,aACjB,KAAbA,SAAiB,OACXC,OAAS,IAAIT,OACf,UAAYO,IACZC,SACA,IACA,EACA,UAAYD,KAEhBH,gBAAgBG,KAAOE,YAEvBV,UAAUW,OAAO,8BAA8BC,MAAKC,OAChDhB,EAAE,WAAaW,KAAKK,KAAKA,OAClB,KACRC,OAAMC,GAAKT,OAAOU,QAAQC,MAAMF,YAEhC,OAIPG,WAAa,CACbC,KAAM,SAASC,aAAcC,YAAaC,WACtCvB,IACKwB,YAAY,CACT,CAACC,IAAK,gBAAiBC,UAAW,kBAErCC,MAAK,WACFR,WAAWS,SAASP,aAAcC,YAAaC,eAG3DK,SAAU,SAASP,aAAcC,YAAaC,WAC1CzB,EAAE,2BAA2B+B,KAAK,WAAWC,MAAMC,SAAQ,SAASC,WAC5DC,YAAcnC,EAAE,+CAChBmC,YAAYC,OAAS,GACrBD,YAAYE,GAAG,SAAS,SAASC,WACbtC,EAAE,SAASuC,SAAS,iBACpB,CACZD,MAAME,qBAGFC,SAFMzC,EAAE0C,MAAMC,KAAK,QAEJC,MAAM,KACrBC,QAAUJ,SAAS,GACnBK,KAAOL,SAASL,OAAS,EAAI,IAAMK,SAAS,GAAK,GAEjDI,QAAQE,QAAQ,eAAiB,EACjCF,QAAUA,QAAQG,QAAQ,eAAgB,eACnCH,QAAQE,QAAQ,MAAQ,EAC/BF,SAAW,eAEXA,SAAW,mBAEXI,SAAWJ,QAAUC,KAEzBrC,OAAOyC,SAASC,KAAOF,iBAM/BG,IAAMpD,EAAE,IAAMkC,MAAMmB,IAAIC,KAAK,WAC7BC,KAAOC,EAAEC,IAAIC,sBAEbC,KAAO,CAACN,GAAID,IAAKQ,WAAY,QAASL,KAAMA,MAE5CM,IAAM5D,KAAK6D,KAAK,CAAC,CAACC,WADL,iCACiBJ,KAAAA,eAClCE,IAAI,GAAGhC,MAAK,SAASmC,UACbV,KAAOW,KAAKC,MAAMF,MAElBpD,SAAW,MACX0C,KAAKA,KAAKa,WACVvD,SAAW0C,KAAKA,KAAKa,UAErBvD,SAAU,KAENwD,kBAAoBC,SAASC,cAAc,OAE1C7C,UAGD2C,kBAAkBG,OAAOlE,eAAeiD,KAAKA,KAAKkB,aAAcpB,MAFhEpD,EAAEoE,mBAAmBpD,KAAKV,aAAa8C,MAK3CgB,kBAAkBK,UAAUC,IAAI,cAAe,QAC/CN,kBAAkBO,QAAQC,OAAS,eAAiBxB,IAEpDpD,EAAE,IAAMkC,MAAMmB,IAAItB,KAAK,iBAAmBqB,KAAKyB,QAAQT,uBAEnDU,SAAW,IAAIvE,mBACfwE,QAAU,CACVC,UAAW1B,KAAKA,KAChB2B,WAAYH,SAASI,aAAa5B,KAAKA,MACvC6B,KAAM5D,aACN6D,OAAQhC,IACRiC,OAAQ5D,eAGR6D,SAAWR,SAASS,iBAAiBjC,KAAKA,KAAKkC,WAAYlC,KAAKA,KAAKmC,MAAOlE,cAChFuD,SAASY,YAAYtC,IAAK2B,QAAS,GAAIvE,gBAAiB8E,UACxDR,SAASa,UAAUvC,IAAKjD,UAAW4E,QAAS,GAAIvE,gBAAiB8E,UACjER,SAASc,UAAUxC,IAAKE,KAAKA,KAAKuC,QAAS,GAAIrF,iBAC/CsE,SAASgB,aAAa1C,IAAKxC,SAAU,GAAIJ,qBAI1CqD,IAAIkC,wBAIhB1E"} \ No newline at end of file diff --git a/amd/build/document_view.min.js.map b/amd/build/document_view.min.js.map index e291a61f..4a08e91c 100644 --- a/amd/build/document_view.min.js.map +++ b/amd/build/document_view.min.js.map @@ -1 +1 @@ -{"version":3,"file":"document_view.min.js","sources":["../src/document_view.js"],"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 * This module provides functionality for document view management in the Tiny editor,\n * including full page mode display and sidebar information\n * @module tiny_cursive/document_view\n * @copyright 2025 Cursive Technology, Inc. \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Icons from 'tiny_cursive/svg_repo';\nexport default class DocumentView {\n\n constructor(User, Rubrics, submission, modulename, editor, quizInfo) {\n this.User = User;\n this.Rubrics = Rubrics;\n this.submission = submission;\n this.module = modulename;\n this.editor = editor;\n this.moduleIcon = Icons.assignment;\n this.quizInfo = quizInfo;\n this.initStrings();\n }\n\n normalMode() {\n let id = this.editor?.id + \"_ifr\";\n if (this.module === 'assign') {\n this.normalizePage(id);\n } else if (this.module === 'quiz') {\n this.normalizePage(id);\n } else if (this.module === 'forum') {\n this.normalizePage(id);\n } else if (this.module === 'lesson') {\n this.normalizePage(id);\n } else if(this.module === 'pdfannotator') {\n this.normalizePage(id);\n }\n }\n\n fullPageMode() {\n\n if (this.module === 'assign') {\n this.moduleIcon = Icons.assignment;\n this.fullPageModule(this.editor?.id);\n } else if (this.module === 'forum') {\n this.moduleIcon = Icons.forum;\n this.fullPageModule(this.editor?.id);\n } else if (this.module === 'quiz' && this.editor?.id) {\n this.moduleIcon = Icons.quiz;\n this.fullPageModule(this.editor?.id);\n } else if (this.module === 'lesson') {\n this.moduleIcon = Icons.lesson;\n this.fullPageModule(this.editor?.id);\n } else if (this.module === 'pdfannotator') {\n this.moduleIcon = Icons.pdfannotator;\n this.fullPageModule(this.editor?.id);\n }\n }\n\n docSideBar(status) {\n\n const url = new URL(window.location.href);\n const replyId = url.searchParams.get(\"reply\");\n const toggle = document.querySelector('#cursive-fullpagemode-sidebar-toggle');\n const timelimitBlock = this.getTimerBlock(this.module);\n const headerInfo = this.getSidebarTitle();\n const progressBar = document.querySelector('.box.progress_bar');\n\n const courseName = document.querySelector('#page-navbar > nav > ol > li:nth-child(1) > a');\n const courseDes = document.querySelector('#intro');\n const Dates = document.querySelector('.activity-dates');\n\n let openDate = Dates?.querySelector('div:nth-child(1)');\n let dueDate = Dates?.querySelector('div:nth-child(2)');\n\n const container = this.create('div');\n Object.assign(container, {\n id: 'cursive-fullpagemode-sidebar',\n className: 'bg-white h-100 shadow'\n });\n Object.assign(container.style, {\n width: '300px',\n overflow: 'auto'\n });\n\n const crossBtn = this.create('span');\n Object.assign(crossBtn, {\n id: 'cursive-collapse-sidebar',\n className: 'btn p-2',\n innerHTML: Icons.close\n });\n\n crossBtn.addEventListener('click', () => {\n container.style.transition = 'width 0.3s ease';\n container.style.width = '0';\n toggle.style.display = 'flex';\n });\n toggle?.addEventListener('click', function() {\n toggle.style.display = 'none';\n container.style.width = '300px';\n });\n\n const btnWrapper = this.create('div');\n Object.assign(btnWrapper, {\n padding: '0 1rem',\n position: 'sticky',\n top: '0',\n backgroundColor: 'white'\n });\n btnWrapper.append(crossBtn);\n\n\n const header = this.create('div');\n header.className = 'border-bottom p-3 bg-light';\n Object.assign(header.style, {\n position: 'sticky',\n top: '0'\n });\n\n const headerTitle = this.create('h3');\n headerTitle.className = 'mb-3 d-flex align-items-center';\n headerTitle.textContent = `${headerInfo.title} ${this.details}`;\n headerTitle.style.fontWeight = '600';\n\n const headerIcon = document.querySelector('.page-header-image > div');\n if (headerIcon) {\n headerTitle.prepend(headerIcon.cloneNode(true));\n }\n\n let wordCount = this.wordCounter(status);\n if (timelimitBlock?.textContent) {\n header.append(headerTitle, wordCount, this.timerCountDown(timelimitBlock));\n } else {\n header.append(headerTitle, wordCount);\n }\n\n const content = this.create('div');\n content.className = 'p-3';\n\n content.append(\n this.createBox({\n bg: 'bg-info',\n titleColor: 'text-info',\n icon: Icons.people,\n title: this.studentInfo,\n bodyHTML: this.generateStudentInfo(this.User, courseName)\n })\n );\n\n if (this.module === 'lesson' && progressBar) {\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: this.progress,\n bodyHTML: progressBar.innerHTML\n })\n );\n }\n\n if (courseDes && courseDes?.textContent.trim() !== '') {\n let fileSubDiv = document.querySelectorAll('.fileuploadsubmission');\n if (fileSubDiv) {\n fileSubDiv.forEach(Element => {\n Element.style.verticalAlign = 'middle';\n });\n }\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: `${this.getSidebarTitle().title} ${this.description}`,\n bodyHTML: courseDes.innerHTML\n })\n );\n }\n\n if (this.module === 'forum' && replyId) {\n this.checkForumSubject();\n let replyPost = document.querySelector(`#post-content-${replyId}`);\n if (replyPost?.textContent.trim()) {\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: this.replyingto,\n bodyHTML: replyPost.textContent.trim()\n })\n );\n }\n }\n\n if (this.module === 'quiz' && this.editor?.id) {\n\n let questionId = this.getQuestionId(this.editor?.id);\n let question = document.querySelector(`#question-${questionId} .qtext`);\n let intro = atob(this.quizInfo.intro);\n\n if (question?.textContent.trim()) {\n content.append(\n this.createBox({\n bg: 'bg-amber',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: this.answeringto,\n bodyHTML: question.textContent\n })\n );\n }\n\n if (intro && intro.trim() !== '') {\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: `${this.quiz} ${this.description}`,\n bodyHTML: intro\n })\n );\n }\n\n if (Number(this.quizInfo.open)) {\n content.append(\n this.createBox({\n bg: 'bg-amber',\n titleColor: 'text-dark',\n icon: Icons.time,\n title: this.importantdates,\n bodyHTML: this.generateImportantDates(Number(this.quizInfo.open), Number(this.quizInfo.close))\n })\n );\n }\n }\n\n if (Object.keys(this.Rubrics).length) {\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: this.rubrics,\n bodyHTML: this.generateRubrics(this.Rubrics)\n })\n );\n }\n\n if (Dates) {\n content.append(\n this.createBox({\n bg: 'bg-amber',\n titleColor: 'text-dark',\n icon: Icons.time,\n title: this.importantdates,\n bodyHTML: this.generateImportantDates(openDate, dueDate)\n })\n );\n }\n if (this.module === 'assign') {\n content.append(\n this.createBox({\n bg: 'bg-green',\n titleColor: 'text-success',\n icon: this.moduleIcon,\n title: this.subStatus,\n bodyHTML: this.submissionStatus(this.submission)\n })\n );\n }\n\n container.append(btnWrapper, header, content);\n return container;\n\n }\n // Helper to create info boxes\n createBox({bg, titleColor, icon, title, bodyHTML}) {\n const box = this.create('div');\n box.className = `tiny_cursive-fullpage-card ${bg}`;\n\n const heading = this.create('h4');\n heading.className = `tiny_cursive-fullpage-card-header ${titleColor} d-flex align-items-center`;\n heading.innerHTML = `${icon} ${title}`;\n\n const body = this.create('div');\n body.className = `tiny_cursive-fullpage-card-body`;\n body.innerHTML = bodyHTML;\n\n box.append(heading, body);\n return box;\n }\n\n generateRubrics(Rubrics) {\n const wrapper = this.create('div');\n\n Rubrics.forEach(rubric => {\n const rubricDiv = this.create('div');\n rubricDiv.className = 'tiny_cursive-rubric-card';\n\n const title = this.create('h3');\n title.className = 'tiny_cursive-rubric-title';\n title.textContent = rubric.description;\n rubricDiv.appendChild(title);\n\n Object.values(rubric.levels).forEach(level => {\n const levelDiv = this.create('div');\n const score = Number(level.score);\n\n // Assign background color class based on score\n if (score === 0) {\n levelDiv.className = 'tiny_cursive-rubric-level tiny_cursive-rubric-low';\n } else if (score <= 2) {\n levelDiv.className = 'tiny_cursive-rubric-level tiny_cursive-rubric-mid';\n } else {\n levelDiv.className = 'tiny_cursive-rubric-level tiny_cursive-rubric-high';\n }\n\n levelDiv.textContent = `${level.definition} / ${level.score}`;\n rubricDiv.appendChild(levelDiv);\n });\n\n wrapper.appendChild(rubricDiv);\n });\n\n return wrapper.innerHTML;\n }\n\n submissionStatus(submission) {\n const wrapper = this.create('div');\n\n const statusWrapper = this.create('div');\n statusWrapper.className = 'tiny_cursive-status-row';\n\n const statusName = this.create('span');\n statusName.textContent = `${this.status}:`;\n\n const statusValue = this.create('span');\n const isNew = submission?.current?.status === 'new';\n statusValue.textContent = isNew ? this.draftnot : this.draft;\n statusValue.className = `tiny_cursive-status-value ${isNew ? 'tiny_cursive-status-red' : 'tiny_cursive-status-green'}`;\n\n statusWrapper.append(statusName, statusValue);\n\n const modifiedWrapper = this.create('div');\n modifiedWrapper.className = 'tiny_cursive-status-row';\n\n const modifiedName = this.create('span');\n modifiedName.textContent = `${this.lastModified}: `;\n\n const modifiedValue = this.create('span');\n if (submission?.current?.timemodified) {\n const date = new Date(submission.current.timemodified * 1000);\n modifiedValue.textContent = this.formatDate(date);\n } else {\n modifiedValue.textContent = 'N/A';\n }\n modifiedWrapper.append(modifiedName, modifiedValue);\n\n const gradeWrapper = this.create('div');\n gradeWrapper.className = 'tiny_cursive-status-row';\n\n const gradeName = this.create('span');\n gradeName.textContent = `${this.gradings}: `;\n\n const gradeValue = this.create('span');\n\n if (submission?.grade) {\n gradeValue.textContent = Number(submission.grade.grade) > 0\n ? submission.grade.grade\n : this.gradenot;\n } else {\n gradeValue.textContent = this.gradenot;\n }\n\n gradeWrapper.append(gradeName, gradeValue);\n wrapper.append(statusWrapper, gradeWrapper, modifiedWrapper);\n return wrapper.innerHTML;\n }\n\n wordCounter(status) {\n const wordCount = this.create('div');\n const labelDiv = this.create('div');\n const label = this.create('span');\n const value = this.create('span');\n const icon = this.create('span');\n\n icon.className = 'me-2';\n icon.innerHTML = Icons.assignment;\n\n labelDiv.appendChild(icon);\n labelDiv.append(label);\n\n label.textContent = `${this.wordCount}:`;\n value.textContent = '0';\n value.className = 'text-primary';\n value.style.fontWeight = '600';\n value.style.fontSize = '14px';\n\n wordCount.className = 'bg-white rounded shadow-sm p-2 d-flex justify-content-between my-2';\n wordCount.append(labelDiv, value);\n wordCount.style.fontSize = '12px';\n\n const observer = new MutationObserver(() => {\n const newText = status.textContent.trim();\n value.textContent = `${newText.replace('words', '')}`;\n });\n\n observer.observe(status, {\n characterData: true,\n subtree: true,\n childList: true\n });\n\n return wordCount;\n }\n\n\n timerCountDown(timer) {\n\n let warningDiv = document.querySelector('#user-notifications > div');\n if (warningDiv) {\n let clone = warningDiv.cloneNode(true);\n clone.querySelector('button')?.remove();\n this.editor.notificationManager.open({\n text: clone.textContent,\n type: 'error'\n });\n }\n\n\n const timerCount = this.create('div');\n timerCount.className = 'bg-white rounded shadow-sm p-2 d-flex justify-content-between my-2';\n\n const labelDiv = this.create('div');\n const label = this.create('span');\n const value = this.create('span');\n const icon = this.create('span');\n icon.innerHTML = Icons.time;\n\n labelDiv.appendChild(icon);\n labelDiv.append(label);\n\n label.textContent = `${this.timeleft}:`;\n value.textContent = '00:00:00';\n value.className = warningDiv ? 'text-danger' : 'text-primary';\n Object.assign(value.style, {\n fontWeight: '600',\n fontSize: '14px'\n });\n\n\n timerCount.append(labelDiv, value);\n timerCount.style.fontSize = '12px';\n if (timer) {\n const observer = new MutationObserver(() => {\n const newText = timer.textContent.trim();\n value.textContent = `${newText}`;\n });\n observer.observe(timer, {\n characterData: true,\n subtree: true,\n childList: true\n });\n } else {\n value.textContent = this.nolimit;\n }\n\n\n return timerCount;\n }\n\n\n generateStudentInfo(user, course) {\n\n const wrapper = this.create('div');\n\n const nameWrapper = this.create('div');\n const usernameWrapper = this.create('div');\n const courseWrapper = this.create('div');\n\n const nameLabel = this.create('strong');\n const nameValue = this.create('span');\n const usernameLabel = this.create('strong');\n const usernameValue = this.create('span');\n const courseLabel = this.create('strong');\n const courseValue = this.create('span');\n\n nameLabel.textContent = `${this.name}`;\n nameValue.textContent = user.fullname;\n\n usernameLabel.textContent = `${this.userename}: `;\n usernameValue.textContent = user.username;\n\n courseLabel.textContent = `${this.course}: `;\n courseValue.textContent = course.title;\n\n usernameLabel.className = 'cfw-bold me-2';\n usernameValue.className = 'cursiveFw-wrap';\n courseLabel.className = 'cfw-bold me-2';\n courseValue.className = 'cursiveFw-wrap';\n nameLabel.className = 'cfw-bold me-2';\n nameValue.className = 'cursiveFw-wrap';\n\n nameWrapper.append(nameLabel, nameValue);\n usernameWrapper.append(usernameLabel, usernameValue);\n courseWrapper.append(courseLabel, courseValue);\n\n wrapper.append(nameWrapper, usernameWrapper, courseWrapper);\n\n return wrapper.innerHTML;\n\n }\n\n generateImportantDates(open, due) {\n\n const wrapper = this.create('div');\n let openDate = null;\n let dueDate = null;\n\n const openedWrapper = this.create('div');\n const dueWrapper = this.create('div');\n const remainingWrapper = this.create('div');\n\n const openedLabel = this.create('span');\n const openedValue = this.create('span');\n const dueLabel = this.create('span');\n const dueValue = this.create('span');\n const remainingLabel = this.create('span');\n const remainingValue = this.create('span');\n if (this.module === 'quiz') {\n openDate = open * 1000;\n dueDate = due * 1000;\n } else {\n openDate = this.extractDate(open?.textContent);\n dueDate = this.extractDate(due?.textContent);\n }\n\n openedLabel.textContent = `${this.opened}: `;\n openedValue.textContent = this.formatDate(openDate ? new Date(openDate) : null);\n openedValue.className = 'text-dark';\n\n dueLabel.textContent = `${this.due}: `;\n dueValue.textContent = this.formatDate(dueDate ? new Date(dueDate) : null);\n dueValue.className = 'text-danger';\n\n remainingLabel.textContent = `${this.remaining}: `;\n remainingValue.textContent = this.calculateDate(dueDate);\n remainingValue.className = 'text-danger';\n\n openedWrapper.className = 'd-flex justify-content-between';\n dueWrapper.className = 'd-flex justify-content-between';\n remainingWrapper.className = 'd-flex align-items-center justify-content-between mt-2 pt-2 border-top';\n\n openedWrapper.append(openedLabel, openedValue);\n dueWrapper.append(dueLabel, dueValue);\n remainingWrapper.append(remainingLabel, remainingValue);\n\n wrapper.append(openedWrapper, dueWrapper, remainingWrapper);\n\n return wrapper.innerHTML;\n }\n\n formatDate(date) {\n if (!date) {\n return '-';\n }\n\n let options = {year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: true};\n return date.toLocaleString('en-US', options);\n }\n\n extractDate(text) {\n if (!text) {\n return '-';\n }\n // Split on first colon and return the right part\n const parts = text?.split(':');\n if (parts.length > 1) {\n return parts.slice(1).join(':').trim();\n }\n\n return text.trim();\n }\n\n\n calculateDate(date) {\n if (!date) {\n return '-';\n }\n const date1 = new Date(date); // Due date (local time)\n const now = new Date(); // Current date/time\n\n // Calculate the difference in milliseconds\n const diffMs = date1 - now;\n\n // Convert to days, hours, minutes\n if (diffMs <= 0) {\n return \"Overdue\";\n } else {\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n const diffHours = Math.floor((diffMs / (1000 * 60 * 60)) % 24);\n\n return `${diffDays} days, ${diffHours} hours`;\n }\n\n }\n\n fullPageModule(module) {\n let current = this.module === 'quiz' ?\n document.getElementById(`${module}_ifr`) : document.querySelector(`#${module}_ifr`);\n\n let p1 = current.parentElement;\n let p2 = p1.parentElement;\n let p3 = p2.parentElement;\n let p4 = p3.parentElement;\n\n let statusBar = document.querySelector('.tox-statusbar__right-container > button');\n let assignName = document.querySelector('.page-context-header');\n let header = this.create('div');\n let btn = null;\n\n assignName.classList.remove('mb-2');\n header.id = 'tiny_cursive-fullpage-custom-header';\n Object.assign(header.style, {\n backgroundColor: 'white',\n display: 'flex',\n justifyContent: 'space-between'\n });\n\n if (this.module === 'quiz') {\n btn = document.querySelector('#mod_quiz-next-nav').cloneNode(true);\n btn.className = 'tiny_cursive-fullpage-submit-btn';\n btn.style.margin = '.5rem';\n } else {\n btn = this.create('input');\n btn.className = 'tiny_cursive-fullpage-submit-btn';\n btn.value = this.savechanges;\n btn.type = 'submit';\n btn.style.margin = '.5rem';\n }\n\n if (this.module === 'pdfannotator') {\n const style = document.createElement('style');\n style.id = 'cursiveForceStyle';\n style.textContent = `\n .path-mod-pdfannotator #comment-wrapper h4,\n .path-mod-pdfannotator #comment-nav {\n margin: 0 !important;\n }\n `;\n document.head.appendChild(style);\n }\n\n const leftSide = this.create('div');\n const rightSide = this.create('div');\n let commonStyle = {\n display: 'flex',\n alignItems: 'center',\n margin: '0 1rem'\n };\n\n Object.assign(leftSide.style, commonStyle);\n rightSide.id = 'tiny_cursive-fullpage-right-wrapper';\n Object.assign(rightSide.style, commonStyle);\n\n rightSide.appendChild(btn);\n leftSide.appendChild(assignName.cloneNode(true));\n\n header.appendChild(leftSide);\n header.appendChild(rightSide);\n\n p4.insertBefore(header, p4.firstChild);\n p2.style.backgroundColor = '#efefef';\n Object.assign(current.style, {\n width: '750px',\n minWidth: '750px',\n boxShadow: '0 10px 15px -3px rgb(0 0 0/0.1),0 4px 6px -4px rgb(0 0 0/0.1)'\n });\n\n Object.assign(p1.style, {\n display: 'flex',\n justifyContent: 'center',\n outline: 'none',\n margin: '2rem 0 0'\n });\n const style = this.create('style');\n style.id = 'tiny_cursive-fullpage-mode-style';\n style.textContent = `\n .tox.tox-edit-focus .tox-edit-area::before {\n opacity: 0;\n }`;\n document.head.appendChild(style);\n\n let iframeBody = current.contentDocument?.body || current.contentWindow?.document?.body;\n\n if (iframeBody) {\n iframeBody.style.padding = '0.5in';\n }\n p2.style.position = 'relative';\n document.getElementById('cursive-fullpagemode-sidebar')?.remove();\n\n let toggle = this.create('div');\n toggle.id = 'cursive-fullpagemode-sidebar-toggle';\n toggle.innerHTML = Icons.hamburger;\n p2.appendChild(toggle);\n p2.appendChild(this.docSideBar(statusBar));\n }\n\n normalizePage(editorId) {\n document.getElementById('tiny_cursive-fullpage-custom-header')?.remove();\n document.getElementById('cursive-fullpagemode-sidebar')?.remove();\n\n let current = document.getElementById(editorId);\n let p1 = current.parentElement;\n let p2 = p1.parentElement;\n\n Object.assign(p2.style, {\n backgroundColor: \"\",\n position: \"\"\n });\n\n Object.assign(current.style, {\n width: '',\n minWidth: '',\n boxShadow: '',\n });\n\n Object.assign(p1.style, {\n display: '',\n justifyContent: '',\n outline: '',\n margin: ''\n });\n\n p1.classList.remove('tiny-cursive-editor-container');\n\n let iframeBody = current.contentDocument?.body || current.contentWindow?.document?.body;\n if (iframeBody) {\n iframeBody.style.padding = '0';\n }\n document.head.querySelector('#tiny_cursive-fullpage-mode-style')?.remove();\n document.head.querySelector('#cursiveForceStyle')?.remove();\n }\n\n checkForumSubject() {\n const form = document.querySelector('#tiny_cursive-fullpage-right-wrapper > input');\n const msg = this.subjectnot;\n\n if (form) {\n form.addEventListener('click', (e) => {\n const subjectInput = document.getElementById('id_subject');\n let content = this.editor.getContent().trim();\n if (!subjectInput || subjectInput.value.trim() === '' || content === '') {\n e.preventDefault();\n e.stopPropagation();\n this.editor.windowManager.alert(msg);\n }\n });\n }\n }\n\n getSidebarTitle() {\n const [assign, discus, quiz, lesson] = this.getText('sbTitle');\n switch (this.module) {\n case 'assign':\n return {title: assign, icon: Icons.assignment};\n case 'forum':\n return {title: discus, icon: Icons.forum};\n case 'lesson':\n return {title: lesson, icon: Icons.forum};\n case 'quiz':\n return {title: quiz, icon: Icons.quiz};\n case 'pdfannotator':\n return {title: 'PDF Annotation', icon: Icons.pdfannotator};\n default:\n return {title: 'Page', icon: Icons.quiz};\n }\n }\n\n getTimerBlock(module) {\n switch (module) {\n case 'assign':\n return document.querySelector('#mod_assign_timelimit_block > div > div');\n case 'forum':\n return document.querySelector('#mod_forum_timelimit_block');\n case 'lesson':\n return document.querySelector('#lesson-timer');\n case 'quiz':\n return document.querySelector('#quiz-time-left');\n default:\n return null;\n }\n }\n\n getQuestionId(editoId) {\n try {\n if (!editoId || typeof editoId !== 'string') {\n return '';\n }\n return editoId.replace(/^q(\\d+):(\\d+)_.*$/, \"$1-$2\");\n } catch (error) {\n window.console.error('Error getting question ID:', error);\n return '';\n }\n }\n\n initStrings() {\n [\n this.details,\n this.studentInfo,\n this.progress,\n this.description,\n this.replyingto,\n this.answeringto,\n this.importantdates,\n this.rubrics,\n this.subStatus,\n this.status,\n this.draft,\n this.draftnot,\n this.lastModified,\n this.gradings,\n this.gradenot,\n this.wordCount,\n this.timeleft,\n this.nolimit,\n this.name,\n this.userename,\n this.course,\n this.opened,\n this.due,\n this.overdue,\n this.remaining,\n this.savechanges,\n this.subjectnot\n ] = this.getText('docSideBar');\n }\n\n getText(key) {\n return JSON.parse(localStorage.getItem(key)) || [];\n }\n\n create(tag) {\n return document.createElement(tag);\n }\n\n}"],"names":["constructor","User","Rubrics","submission","modulename","editor","quizInfo","module","moduleIcon","Icons","assignment","initStrings","normalMode","id","this","normalizePage","fullPageMode","fullPageModule","_this$editor2","forum","_this$editor3","_this$editor4","quiz","_this$editor5","lesson","_this$editor6","pdfannotator","_this$editor7","docSideBar","status","replyId","URL","window","location","href","searchParams","get","toggle","document","querySelector","timelimitBlock","getTimerBlock","headerInfo","getSidebarTitle","progressBar","courseName","courseDes","Dates","openDate","dueDate","container","create","Object","assign","className","style","width","overflow","crossBtn","innerHTML","close","addEventListener","transition","display","btnWrapper","padding","position","top","backgroundColor","append","header","headerTitle","textContent","title","details","fontWeight","headerIcon","prepend","cloneNode","wordCount","wordCounter","timerCountDown","content","createBox","bg","titleColor","icon","people","studentInfo","bodyHTML","generateStudentInfo","progress","trim","fileSubDiv","querySelectorAll","forEach","Element","verticalAlign","description","checkForumSubject","replyPost","replyingto","_this$editor8","questionId","getQuestionId","_this$editor9","question","intro","atob","answeringto","Number","open","time","importantdates","generateImportantDates","keys","length","rubrics","generateRubrics","subStatus","submissionStatus","box","heading","body","wrapper","rubric","rubricDiv","appendChild","values","levels","level","levelDiv","score","definition","statusWrapper","statusName","statusValue","isNew","current","draftnot","draft","modifiedWrapper","modifiedName","lastModified","modifiedValue","_submission$current2","timemodified","date","Date","formatDate","gradeWrapper","gradeName","gradings","gradeValue","grade","gradenot","labelDiv","label","value","fontSize","MutationObserver","newText","replace","observe","characterData","subtree","childList","timer","warningDiv","clone","remove","notificationManager","text","type","timerCount","timeleft","nolimit","user","course","nameWrapper","usernameWrapper","courseWrapper","nameLabel","nameValue","usernameLabel","usernameValue","courseLabel","courseValue","name","fullname","userename","username","due","openedWrapper","dueWrapper","remainingWrapper","openedLabel","openedValue","dueLabel","dueValue","remainingLabel","remainingValue","extractDate","opened","remaining","calculateDate","toLocaleString","year","month","day","hour","minute","hour12","parts","split","slice","join","diffMs","Math","floor","getElementById","p1","parentElement","p2","p4","statusBar","assignName","btn","classList","justifyContent","margin","savechanges","createElement","head","leftSide","rightSide","commonStyle","alignItems","insertBefore","firstChild","minWidth","boxShadow","outline","iframeBody","contentDocument","contentWindow","_current$contentWindo","_current$contentWindo2","hamburger","editorId","_current$contentWindo3","_current$contentWindo4","form","msg","subjectnot","e","subjectInput","getContent","preventDefault","stopPropagation","windowManager","alert","discus","getText","editoId","error","console","overdue","key","JSON","parse","localStorage","getItem","tag"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"document_view.min.js","sources":["../src/document_view.js"],"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 * This module provides functionality for document view management in the Tiny editor,\n * including full page mode display and sidebar information\n * @module tiny_cursive/document_view\n * @copyright 2025 Cursive Technology, Inc. \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Icons from 'tiny_cursive/svg_repo';\nexport default class DocumentView {\n\n constructor(User, Rubrics, submission, modulename, editor, quizInfo) {\n this.User = User;\n this.Rubrics = Rubrics;\n this.submission = submission;\n this.module = modulename;\n this.editor = editor;\n this.moduleIcon = Icons.assignment;\n this.quizInfo = quizInfo;\n this.initStrings();\n }\n\n normalMode() {\n let id = this.editor?.id + \"_ifr\";\n if (this.module === 'assign') {\n this.normalizePage(id);\n } else if (this.module === 'quiz') {\n this.normalizePage(id);\n } else if (this.module === 'forum') {\n this.normalizePage(id);\n } else if (this.module === 'lesson') {\n this.normalizePage(id);\n } else if (this.module === 'pdfannotator') {\n this.normalizePage(id);\n }\n }\n\n fullPageMode() {\n\n if (this.module === 'assign') {\n this.moduleIcon = Icons.assignment;\n this.fullPageModule(this.editor?.id);\n } else if (this.module === 'forum') {\n this.moduleIcon = Icons.forum;\n this.fullPageModule(this.editor?.id);\n } else if (this.module === 'quiz' && this.editor?.id) {\n this.moduleIcon = Icons.quiz;\n this.fullPageModule(this.editor?.id);\n } else if (this.module === 'lesson') {\n this.moduleIcon = Icons.lesson;\n this.fullPageModule(this.editor?.id);\n } else if (this.module === 'pdfannotator') {\n this.moduleIcon = Icons.pdfannotator;\n this.fullPageModule(this.editor?.id);\n }\n }\n\n docSideBar(status) {\n\n const url = new URL(window.location.href);\n const replyId = url.searchParams.get(\"reply\");\n const toggle = document.querySelector('#cursive-fullpagemode-sidebar-toggle');\n const timelimitBlock = this.getTimerBlock(this.module);\n const headerInfo = this.getSidebarTitle();\n const progressBar = document.querySelector('.box.progress_bar');\n\n const courseName = document.querySelector('#page-navbar > nav > ol > li:nth-child(1) > a');\n const courseDes = document.querySelector('#intro');\n const Dates = document.querySelector('.activity-dates');\n\n let openDate = Dates?.querySelector('div:nth-child(1)');\n let dueDate = Dates?.querySelector('div:nth-child(2)');\n\n const container = this.create('div');\n Object.assign(container, {\n id: 'cursive-fullpagemode-sidebar',\n className: 'bg-white h-100 shadow'\n });\n Object.assign(container.style, {\n width: '300px',\n overflow: 'auto'\n });\n\n const crossBtn = this.create('span');\n Object.assign(crossBtn, {\n id: 'cursive-collapse-sidebar',\n className: 'btn p-2',\n innerHTML: Icons.close\n });\n\n crossBtn.addEventListener('click', () => {\n container.style.transition = 'width 0.3s ease';\n container.style.width = '0';\n toggle.style.display = 'flex';\n });\n toggle?.addEventListener('click', function() {\n toggle.style.display = 'none';\n container.style.width = '300px';\n });\n\n const btnWrapper = this.create('div');\n Object.assign(btnWrapper, {\n padding: '0 1rem',\n position: 'sticky',\n top: '0',\n backgroundColor: 'white'\n });\n btnWrapper.append(crossBtn);\n\n\n const header = this.create('div');\n header.className = 'border-bottom p-3 bg-light';\n Object.assign(header.style, {\n position: 'sticky',\n top: '0'\n });\n\n const headerTitle = this.create('h3');\n headerTitle.className = 'mb-3 d-flex align-items-center';\n headerTitle.textContent = `${headerInfo.title} ${this.details}`;\n headerTitle.style.fontWeight = '600';\n\n const headerIcon = document.querySelector('.page-header-image > div');\n if (headerIcon) {\n headerTitle.prepend(headerIcon.cloneNode(true));\n }\n\n let wordCount = this.wordCounter(status);\n if (timelimitBlock?.textContent) {\n header.append(headerTitle, wordCount, this.timerCountDown(timelimitBlock));\n } else {\n header.append(headerTitle, wordCount);\n }\n\n const content = this.create('div');\n content.className = 'p-3';\n\n content.append(\n this.createBox({\n bg: 'bg-info',\n titleColor: 'text-info',\n icon: Icons.people,\n title: this.studentInfo,\n bodyHTML: this.generateStudentInfo(this.User, courseName)\n })\n );\n\n if (this.module === 'lesson' && progressBar) {\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: this.progress,\n bodyHTML: progressBar.innerHTML\n })\n );\n }\n\n if (courseDes && courseDes?.textContent.trim() !== '') {\n let fileSubDiv = document.querySelectorAll('.fileuploadsubmission');\n if (fileSubDiv) {\n fileSubDiv.forEach(Element => {\n Element.style.verticalAlign = 'middle';\n });\n }\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: `${this.getSidebarTitle().title} ${this.description}`,\n bodyHTML: courseDes.innerHTML\n })\n );\n }\n\n if (this.module === 'forum' && replyId) {\n this.checkForumSubject();\n let replyPost = document.querySelector(`#post-content-${replyId}`);\n if (replyPost?.textContent.trim()) {\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: this.replyingto,\n bodyHTML: replyPost.textContent.trim()\n })\n );\n }\n }\n\n if (this.module === 'quiz' && this.editor?.id) {\n\n let questionId = this.getQuestionId(this.editor?.id);\n let question = document.querySelector(`#question-${questionId} .qtext`);\n let intro = atob(this.quizInfo.intro);\n\n if (question?.textContent.trim()) {\n content.append(\n this.createBox({\n bg: 'bg-amber',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: this.answeringto,\n bodyHTML: question.textContent\n })\n );\n }\n\n if (intro && intro.trim() !== '') {\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: `${this.quiz} ${this.description}`,\n bodyHTML: intro\n })\n );\n }\n\n if (Number(this.quizInfo.open)) {\n content.append(\n this.createBox({\n bg: 'bg-amber',\n titleColor: 'text-dark',\n icon: Icons.time,\n title: this.importantdates,\n bodyHTML: this.generateImportantDates(Number(this.quizInfo.open), Number(this.quizInfo.close))\n })\n );\n }\n }\n\n if (Object.keys(this.Rubrics).length) {\n content.append(\n this.createBox({\n bg: 'bg-gray',\n titleColor: 'text-dark',\n icon: this.moduleIcon,\n title: this.rubrics,\n bodyHTML: this.generateRubrics(this.Rubrics)\n })\n );\n }\n\n if (Dates) {\n content.append(\n this.createBox({\n bg: 'bg-amber',\n titleColor: 'text-dark',\n icon: Icons.time,\n title: this.importantdates,\n bodyHTML: this.generateImportantDates(openDate, dueDate)\n })\n );\n }\n if (this.module === 'assign') {\n content.append(\n this.createBox({\n bg: 'bg-green',\n titleColor: 'text-success',\n icon: this.moduleIcon,\n title: this.subStatus,\n bodyHTML: this.submissionStatus(this.submission)\n })\n );\n }\n\n container.append(btnWrapper, header, content);\n return container;\n\n }\n // Helper to create info boxes\n createBox({bg, titleColor, icon, title, bodyHTML}) {\n const box = this.create('div');\n box.className = `tiny_cursive-fullpage-card ${bg}`;\n\n const heading = this.create('h4');\n heading.className = `tiny_cursive-fullpage-card-header ${titleColor} d-flex align-items-center`;\n heading.innerHTML = `${icon} ${title}`;\n\n const body = this.create('div');\n body.className = `tiny_cursive-fullpage-card-body`;\n body.innerHTML = bodyHTML;\n\n box.append(heading, body);\n return box;\n }\n\n generateRubrics(Rubrics) {\n const wrapper = this.create('div');\n\n Rubrics.forEach(rubric => {\n const rubricDiv = this.create('div');\n rubricDiv.className = 'tiny_cursive-rubric-card';\n\n const title = this.create('h3');\n title.className = 'tiny_cursive-rubric-title';\n title.textContent = rubric.description;\n rubricDiv.appendChild(title);\n\n Object.values(rubric.levels).forEach(level => {\n const levelDiv = this.create('div');\n const score = Number(level.score);\n\n // Assign background color class based on score\n if (score === 0) {\n levelDiv.className = 'tiny_cursive-rubric-level tiny_cursive-rubric-low';\n } else if (score <= 2) {\n levelDiv.className = 'tiny_cursive-rubric-level tiny_cursive-rubric-mid';\n } else {\n levelDiv.className = 'tiny_cursive-rubric-level tiny_cursive-rubric-high';\n }\n\n levelDiv.textContent = `${level.definition} / ${level.score}`;\n rubricDiv.appendChild(levelDiv);\n });\n\n wrapper.appendChild(rubricDiv);\n });\n\n return wrapper.innerHTML;\n }\n\n submissionStatus(submission) {\n const wrapper = this.create('div');\n\n const statusWrapper = this.create('div');\n statusWrapper.className = 'tiny_cursive-status-row';\n\n const statusName = this.create('span');\n statusName.textContent = `${this.status}:`;\n\n const statusValue = this.create('span');\n const isNew = submission?.current?.status === 'new';\n statusValue.textContent = isNew ? this.draftnot : this.draft;\n statusValue.className = `tiny_cursive-status-value ${isNew ? 'tiny_cursive-status-red' : 'tiny_cursive-status-green'}`;\n\n statusWrapper.append(statusName, statusValue);\n\n const modifiedWrapper = this.create('div');\n modifiedWrapper.className = 'tiny_cursive-status-row';\n\n const modifiedName = this.create('span');\n modifiedName.textContent = `${this.lastModified}: `;\n\n const modifiedValue = this.create('span');\n if (submission?.current?.timemodified) {\n const date = new Date(submission.current.timemodified * 1000);\n modifiedValue.textContent = this.formatDate(date);\n } else {\n modifiedValue.textContent = 'N/A';\n }\n modifiedWrapper.append(modifiedName, modifiedValue);\n\n const gradeWrapper = this.create('div');\n gradeWrapper.className = 'tiny_cursive-status-row';\n\n const gradeName = this.create('span');\n gradeName.textContent = `${this.gradings}: `;\n\n const gradeValue = this.create('span');\n\n if (submission?.grade) {\n gradeValue.textContent = Number(submission.grade.grade) > 0\n ? submission.grade.grade\n : this.gradenot;\n } else {\n gradeValue.textContent = this.gradenot;\n }\n\n gradeWrapper.append(gradeName, gradeValue);\n wrapper.append(statusWrapper, gradeWrapper, modifiedWrapper);\n return wrapper.innerHTML;\n }\n\n wordCounter(status) {\n const wordCount = this.create('div');\n const labelDiv = this.create('div');\n const label = this.create('span');\n const value = this.create('span');\n const icon = this.create('span');\n\n icon.className = 'me-2';\n icon.innerHTML = Icons.assignment;\n\n labelDiv.appendChild(icon);\n labelDiv.append(label);\n\n label.textContent = `${this.wordCount}:`;\n value.textContent = '0';\n value.className = 'text-primary';\n value.style.fontWeight = '600';\n value.style.fontSize = '14px';\n\n wordCount.className = 'bg-white rounded shadow-sm p-2 d-flex justify-content-between my-2';\n wordCount.append(labelDiv, value);\n wordCount.style.fontSize = '12px';\n\n const observer = new MutationObserver(() => {\n const newText = status.textContent.trim();\n value.textContent = `${newText.replace('words', '')}`;\n });\n\n observer.observe(status, {\n characterData: true,\n subtree: true,\n childList: true\n });\n\n return wordCount;\n }\n\n\n timerCountDown(timer) {\n\n let warningDiv = document.querySelector('#user-notifications > div');\n if (warningDiv) {\n let clone = warningDiv.cloneNode(true);\n clone.querySelector('button')?.remove();\n this.editor.notificationManager.open({\n text: clone.textContent,\n type: 'error'\n });\n }\n\n\n const timerCount = this.create('div');\n timerCount.className = 'bg-white rounded shadow-sm p-2 d-flex justify-content-between my-2';\n\n const labelDiv = this.create('div');\n const label = this.create('span');\n const value = this.create('span');\n const icon = this.create('span');\n icon.innerHTML = Icons.time;\n\n labelDiv.appendChild(icon);\n labelDiv.append(label);\n\n label.textContent = `${this.timeleft}:`;\n value.textContent = '00:00:00';\n value.className = warningDiv ? 'text-danger' : 'text-primary';\n Object.assign(value.style, {\n fontWeight: '600',\n fontSize: '14px'\n });\n\n\n timerCount.append(labelDiv, value);\n timerCount.style.fontSize = '12px';\n if (timer) {\n const observer = new MutationObserver(() => {\n const newText = timer.textContent.trim();\n value.textContent = `${newText}`;\n });\n observer.observe(timer, {\n characterData: true,\n subtree: true,\n childList: true\n });\n } else {\n value.textContent = this.nolimit;\n }\n\n\n return timerCount;\n }\n\n\n generateStudentInfo(user, course) {\n\n const wrapper = this.create('div');\n\n const nameWrapper = this.create('div');\n const usernameWrapper = this.create('div');\n const courseWrapper = this.create('div');\n\n const nameLabel = this.create('strong');\n const nameValue = this.create('span');\n const usernameLabel = this.create('strong');\n const usernameValue = this.create('span');\n const courseLabel = this.create('strong');\n const courseValue = this.create('span');\n\n nameLabel.textContent = `${this.name}`;\n nameValue.textContent = user.fullname;\n\n usernameLabel.textContent = `${this.userename}: `;\n usernameValue.textContent = user.username;\n\n courseLabel.textContent = `${this.course}: `;\n courseValue.textContent = course.title;\n\n usernameLabel.className = 'cfw-bold me-2';\n usernameValue.className = 'cursiveFw-wrap';\n courseLabel.className = 'cfw-bold me-2';\n courseValue.className = 'cursiveFw-wrap';\n nameLabel.className = 'cfw-bold me-2';\n nameValue.className = 'cursiveFw-wrap';\n\n nameWrapper.append(nameLabel, nameValue);\n usernameWrapper.append(usernameLabel, usernameValue);\n courseWrapper.append(courseLabel, courseValue);\n\n wrapper.append(nameWrapper, usernameWrapper, courseWrapper);\n\n return wrapper.innerHTML;\n\n }\n\n generateImportantDates(open, due) {\n\n const wrapper = this.create('div');\n let openDate = null;\n let dueDate = null;\n\n const openedWrapper = this.create('div');\n const dueWrapper = this.create('div');\n const remainingWrapper = this.create('div');\n\n const openedLabel = this.create('span');\n const openedValue = this.create('span');\n const dueLabel = this.create('span');\n const dueValue = this.create('span');\n const remainingLabel = this.create('span');\n const remainingValue = this.create('span');\n if (this.module === 'quiz') {\n openDate = open * 1000;\n dueDate = due * 1000;\n } else {\n openDate = this.extractDate(open?.textContent);\n dueDate = this.extractDate(due?.textContent);\n }\n\n openedLabel.textContent = `${this.opened}: `;\n openedValue.textContent = this.formatDate(openDate ? new Date(openDate) : null);\n openedValue.className = 'text-dark';\n\n dueLabel.textContent = `${this.due}: `;\n dueValue.textContent = this.formatDate(dueDate ? new Date(dueDate) : null);\n dueValue.className = 'text-danger';\n\n remainingLabel.textContent = `${this.remaining}: `;\n remainingValue.textContent = this.calculateDate(dueDate);\n remainingValue.className = 'text-danger';\n\n openedWrapper.className = 'd-flex justify-content-between';\n dueWrapper.className = 'd-flex justify-content-between';\n remainingWrapper.className = 'd-flex align-items-center justify-content-between mt-2 pt-2 border-top';\n\n openedWrapper.append(openedLabel, openedValue);\n dueWrapper.append(dueLabel, dueValue);\n remainingWrapper.append(remainingLabel, remainingValue);\n\n wrapper.append(openedWrapper, dueWrapper, remainingWrapper);\n\n return wrapper.innerHTML;\n }\n\n formatDate(date) {\n if (!date) {\n return '-';\n }\n\n let options = {year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: true};\n return date.toLocaleString('en-US', options);\n }\n\n extractDate(text) {\n if (!text) {\n return '-';\n }\n // Split on first colon and return the right part\n const parts = text?.split(':');\n if (parts.length > 1) {\n return parts.slice(1).join(':').trim();\n }\n\n return text.trim();\n }\n\n\n calculateDate(date) {\n if (!date) {\n return '-';\n }\n const date1 = new Date(date); // Due date (local time)\n const now = new Date(); // Current date/time\n\n // Calculate the difference in milliseconds\n const diffMs = date1 - now;\n\n // Convert to days, hours, minutes\n if (diffMs <= 0) {\n return \"Overdue\";\n } else {\n const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));\n const diffHours = Math.floor((diffMs / (1000 * 60 * 60)) % 24);\n\n return `${diffDays} days, ${diffHours} hours`;\n }\n\n }\n\n fullPageModule(module) {\n let current = this.module === 'quiz' ?\n document.getElementById(`${module}_ifr`) : document.querySelector(`#${module}_ifr`);\n\n let p1 = current.parentElement;\n let p2 = p1.parentElement;\n let p3 = p2.parentElement;\n let p4 = p3.parentElement;\n\n let statusBar = document.querySelector('.tox-statusbar__right-container > button');\n let assignName = document.querySelector('.page-context-header');\n let header = this.create('div');\n let btn = null;\n\n assignName.classList.remove('mb-2');\n header.id = 'tiny_cursive-fullpage-custom-header';\n Object.assign(header.style, {\n backgroundColor: 'white',\n display: 'flex',\n justifyContent: 'space-between'\n });\n\n if (this.module === 'quiz') {\n btn = document.querySelector('#mod_quiz-next-nav').cloneNode(true);\n btn.className = 'tiny_cursive-fullpage-submit-btn';\n btn.style.margin = '.5rem';\n } else {\n btn = this.create('input');\n btn.className = 'tiny_cursive-fullpage-submit-btn';\n btn.value = this.savechanges;\n btn.type = 'submit';\n btn.style.margin = '.5rem';\n }\n\n if (this.module === 'pdfannotator') {\n const style = document.createElement('style');\n style.id = 'cursiveForceStyle';\n style.textContent = `\n .path-mod-pdfannotator #comment-wrapper h4,\n .path-mod-pdfannotator #comment-nav {\n margin: 0 !important;\n }\n `;\n document.head.appendChild(style);\n }\n\n const leftSide = this.create('div');\n const rightSide = this.create('div');\n let commonStyle = {\n display: 'flex',\n alignItems: 'center',\n margin: '0 1rem'\n };\n\n Object.assign(leftSide.style, commonStyle);\n rightSide.id = 'tiny_cursive-fullpage-right-wrapper';\n Object.assign(rightSide.style, commonStyle);\n\n rightSide.appendChild(btn);\n leftSide.appendChild(assignName.cloneNode(true));\n\n header.appendChild(leftSide);\n header.appendChild(rightSide);\n\n p4.insertBefore(header, p4.firstChild);\n p2.style.backgroundColor = '#efefef';\n Object.assign(current.style, {\n width: '750px',\n minWidth: '750px',\n boxShadow: '0 10px 15px -3px rgb(0 0 0/0.1),0 4px 6px -4px rgb(0 0 0/0.1)'\n });\n\n Object.assign(p1.style, {\n display: 'flex',\n justifyContent: 'center',\n outline: 'none',\n margin: '2rem 0 0'\n });\n const style = this.create('style');\n style.id = 'tiny_cursive-fullpage-mode-style';\n style.textContent = `\n .tox.tox-edit-focus .tox-edit-area::before {\n opacity: 0;\n }`;\n document.head.appendChild(style);\n\n let iframeBody = current.contentDocument?.body || current.contentWindow?.document?.body;\n\n if (iframeBody) {\n iframeBody.style.padding = '0.5in';\n }\n p2.style.position = 'relative';\n document.getElementById('cursive-fullpagemode-sidebar')?.remove();\n\n let toggle = this.create('div');\n toggle.id = 'cursive-fullpagemode-sidebar-toggle';\n toggle.innerHTML = Icons.hamburger;\n p2.appendChild(toggle);\n p2.appendChild(this.docSideBar(statusBar));\n }\n\n normalizePage(editorId) {\n document.getElementById('tiny_cursive-fullpage-custom-header')?.remove();\n document.getElementById('cursive-fullpagemode-sidebar')?.remove();\n\n let current = document.getElementById(editorId);\n let p1 = current.parentElement;\n let p2 = p1.parentElement;\n\n Object.assign(p2.style, {\n backgroundColor: \"\",\n position: \"\"\n });\n\n Object.assign(current.style, {\n width: '',\n minWidth: '',\n boxShadow: '',\n });\n\n Object.assign(p1.style, {\n display: '',\n justifyContent: '',\n outline: '',\n margin: ''\n });\n\n p1.classList.remove('tiny-cursive-editor-container');\n\n let iframeBody = current.contentDocument?.body || current.contentWindow?.document?.body;\n if (iframeBody) {\n iframeBody.style.padding = '0';\n }\n document.head.querySelector('#tiny_cursive-fullpage-mode-style')?.remove();\n document.head.querySelector('#cursiveForceStyle')?.remove();\n }\n\n checkForumSubject() {\n const form = document.querySelector('#tiny_cursive-fullpage-right-wrapper > input');\n const msg = this.subjectnot;\n\n if (form) {\n form.addEventListener('click', (e) => {\n const subjectInput = document.getElementById('id_subject');\n let content = this.editor.getContent().trim();\n if (!subjectInput || subjectInput.value.trim() === '' || content === '') {\n e.preventDefault();\n e.stopPropagation();\n this.editor.windowManager.alert(msg);\n }\n });\n }\n }\n\n getSidebarTitle() {\n const [assign, discus, quiz, lesson] = this.getText('sbTitle');\n switch (this.module) {\n case 'assign':\n return {title: assign, icon: Icons.assignment};\n case 'forum':\n return {title: discus, icon: Icons.forum};\n case 'lesson':\n return {title: lesson, icon: Icons.forum};\n case 'quiz':\n return {title: quiz, icon: Icons.quiz};\n case 'pdfannotator':\n return {title: 'PDF Annotation', icon: Icons.pdfannotator};\n default:\n return {title: 'Page', icon: Icons.quiz};\n }\n }\n\n getTimerBlock(module) {\n switch (module) {\n case 'assign':\n return document.querySelector('#mod_assign_timelimit_block > div > div');\n case 'forum':\n return document.querySelector('#mod_forum_timelimit_block');\n case 'lesson':\n return document.querySelector('#lesson-timer');\n case 'quiz':\n return document.querySelector('#quiz-time-left');\n default:\n return null;\n }\n }\n\n getQuestionId(editoId) {\n try {\n if (!editoId || typeof editoId !== 'string') {\n return '';\n }\n return editoId.replace(/^q(\\d+):(\\d+)_.*$/, \"$1-$2\");\n } catch (error) {\n window.console.error('Error getting question ID:', error);\n return '';\n }\n }\n\n initStrings() {\n [\n this.details,\n this.studentInfo,\n this.progress,\n this.description,\n this.replyingto,\n this.answeringto,\n this.importantdates,\n this.rubrics,\n this.subStatus,\n this.status,\n this.draft,\n this.draftnot,\n this.lastModified,\n this.gradings,\n this.gradenot,\n this.wordCount,\n this.timeleft,\n this.nolimit,\n this.name,\n this.userename,\n this.course,\n this.opened,\n this.due,\n this.overdue,\n this.remaining,\n this.savechanges,\n this.subjectnot\n ] = this.getText('docSideBar');\n }\n\n getText(key) {\n return JSON.parse(localStorage.getItem(key)) || [];\n }\n\n create(tag) {\n return document.createElement(tag);\n }\n\n}"],"names":["constructor","User","Rubrics","submission","modulename","editor","quizInfo","module","moduleIcon","Icons","assignment","initStrings","normalMode","id","this","normalizePage","fullPageMode","fullPageModule","_this$editor2","forum","_this$editor3","_this$editor4","quiz","_this$editor5","lesson","_this$editor6","pdfannotator","_this$editor7","docSideBar","status","replyId","URL","window","location","href","searchParams","get","toggle","document","querySelector","timelimitBlock","getTimerBlock","headerInfo","getSidebarTitle","progressBar","courseName","courseDes","Dates","openDate","dueDate","container","create","Object","assign","className","style","width","overflow","crossBtn","innerHTML","close","addEventListener","transition","display","btnWrapper","padding","position","top","backgroundColor","append","header","headerTitle","textContent","title","details","fontWeight","headerIcon","prepend","cloneNode","wordCount","wordCounter","timerCountDown","content","createBox","bg","titleColor","icon","people","studentInfo","bodyHTML","generateStudentInfo","progress","trim","fileSubDiv","querySelectorAll","forEach","Element","verticalAlign","description","checkForumSubject","replyPost","replyingto","_this$editor8","questionId","getQuestionId","_this$editor9","question","intro","atob","answeringto","Number","open","time","importantdates","generateImportantDates","keys","length","rubrics","generateRubrics","subStatus","submissionStatus","box","heading","body","wrapper","rubric","rubricDiv","appendChild","values","levels","level","levelDiv","score","definition","statusWrapper","statusName","statusValue","isNew","current","draftnot","draft","modifiedWrapper","modifiedName","lastModified","modifiedValue","_submission$current2","timemodified","date","Date","formatDate","gradeWrapper","gradeName","gradings","gradeValue","grade","gradenot","labelDiv","label","value","fontSize","MutationObserver","newText","replace","observe","characterData","subtree","childList","timer","warningDiv","clone","remove","notificationManager","text","type","timerCount","timeleft","nolimit","user","course","nameWrapper","usernameWrapper","courseWrapper","nameLabel","nameValue","usernameLabel","usernameValue","courseLabel","courseValue","name","fullname","userename","username","due","openedWrapper","dueWrapper","remainingWrapper","openedLabel","openedValue","dueLabel","dueValue","remainingLabel","remainingValue","extractDate","opened","remaining","calculateDate","toLocaleString","year","month","day","hour","minute","hour12","parts","split","slice","join","diffMs","Math","floor","getElementById","p1","parentElement","p2","p4","statusBar","assignName","btn","classList","justifyContent","margin","savechanges","createElement","head","leftSide","rightSide","commonStyle","alignItems","insertBefore","firstChild","minWidth","boxShadow","outline","iframeBody","contentDocument","contentWindow","_current$contentWindo","_current$contentWindo2","hamburger","editorId","_current$contentWindo3","_current$contentWindo4","form","msg","subjectnot","e","subjectInput","getContent","preventDefault","stopPropagation","windowManager","alert","discus","getText","editoId","error","console","overdue","key","JSON","parse","localStorage","getItem","tag"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/append_fourm_post.js b/amd/src/append_fourm_post.js index 36936fea..f8b9c1b4 100644 --- a/amd/src/append_fourm_post.js +++ b/amd/src/append_fourm_post.js @@ -69,26 +69,26 @@ define(["jquery", "core/ajax", "core/str", "core/templates", "./replay", "./anal if (replyButton.length > 0) { replyButton.on('click', function(event) { var isTeacher = $('#body').hasClass('teacher_admin'); - if (isTeacher) { - return true; + if (!isTeacher) { + event.preventDefault(); + var url = $(this).attr('href'); + + var urlParts = url.split('#'); + var baseUrl = urlParts[0]; + var hash = urlParts.length > 1 ? '#' + urlParts[1] : ''; + + if (baseUrl.indexOf('setformat=') > -1) { + baseUrl = baseUrl.replace(/setformat=\d/, 'setformat=1'); + } else if (baseUrl.indexOf('?') > -1) { + baseUrl += '&setformat=1'; + } else { + baseUrl += '?setformat=1'; + } + var finalUrl = baseUrl + hash; + + window.location.href = finalUrl; } - event.preventDefault(); - var url = $(this).attr('href'); - var urlParts = url.split('#'); - var baseUrl = urlParts[0]; - var hash = urlParts.length > 1 ? '#' + urlParts[1] : ''; - - if (baseUrl.indexOf('setformat=') > -1) { - baseUrl = baseUrl.replace(/setformat=\d/, 'setformat=1'); - } else if (baseUrl.indexOf('?') > -1) { - baseUrl += '&setformat=1'; - } else { - baseUrl += '?setformat=1'; - } - var finalUrl = baseUrl + hash; - - window.location.href = finalUrl; }); } diff --git a/amd/src/document_view.js b/amd/src/document_view.js index 14eeb59a..3875bf86 100644 --- a/amd/src/document_view.js +++ b/amd/src/document_view.js @@ -45,7 +45,7 @@ export default class DocumentView { this.normalizePage(id); } else if (this.module === 'lesson') { this.normalizePage(id); - } else if(this.module === 'pdfannotator') { + } else if (this.module === 'pdfannotator') { this.normalizePage(id); } } diff --git a/classes/observers.php b/classes/observers.php index 09134a27..0ca74504 100644 --- a/classes/observers.php +++ b/classes/observers.php @@ -206,7 +206,6 @@ public static function reset_tracking_data(\core\event\course_reset_ended $event foreach ($fileids as $file) { $DB->delete_records('tiny_cursive_user_writing', ['file_id' => $file->id]); $DB->delete_records('tiny_cursive_writing_diff', ['file_id' => $file->id]); - $DB->delete_records('tiny_cursive_quality_metrics', ['file_id' => $file->id]); } } diff --git a/pix/icon.svg b/pix/icon.svg new file mode 100644 index 00000000..270fa9de --- /dev/null +++ b/pix/icon.svg @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/renderer.php b/renderer.php index 6e6b5c01..0bccee6c 100644 --- a/renderer.php +++ b/renderer.php @@ -225,7 +225,7 @@ public function tiny_cursive_user_writing_report($users, $userprofile, $userid, $cm = null; if ($courseid) { $modinfo = get_fast_modinfo($courseid); - if ($modinfo) { + if ($modinfo && isset($modinfo->cms[$user->cmid])) { $cm = $modinfo->get_cm($user->cmid); } } diff --git a/styles.css b/styles.css index 0f2d9860..7d3dedb6 100644 --- a/styles.css +++ b/styles.css @@ -20,7 +20,11 @@ color: #212529; border-collapse: collapse; } - +.tiny_cursive_table.table, +.tiny_cursive_table.table th, +.tiny_cursive_table.table td { + border-top: none; +} .tiny_cursive_table th, .tiny_cursive_table td { padding: 0.75rem; @@ -397,14 +401,28 @@ transform: translateY(-5px); } -.tiny_cursive_added { - background-color: #fff2cc; +.tiny_cursive_added, +.tiny_cursive-inserted, +.tiny_cursive-pasted_content, +.tiny_cursive-ai_inserted { color: rgb(0, 41, 0); font-weight: bold; padding: 2px 4px; border-radius: 4px; word-wrap: break-word; } +.tiny_cursive_added { + background-color: #fff2cc; +} +.tiny_cursive-inserted { + background-color: #fff2cc; +} +.tiny_cursive-pasted_content { + background-color: #fff2cc; +} +.tiny_cursive-ai_inserted { + background-color: #fff2cc; +} .tiny_cursive-legend-item { display: flex; diff --git a/templates/analytics_modal.mustache b/templates/analytics_modal.mustache index 97deaf34..d292dc1d 100644 --- a/templates/analytics_modal.mustache +++ b/templates/analytics_modal.mustache @@ -116,7 +116,7 @@
{{#apikey}} - +
{{#tabledata.total_time_seconds}} diff --git a/templates/analytics_table.mustache b/templates/analytics_table.mustache index 32f7f1ef..e33c5da2 100644 --- a/templates/analytics_table.mustache +++ b/templates/analytics_table.mustache @@ -33,7 +33,7 @@ } }} -
+
{{#tabledata.total_time_seconds}} diff --git a/version.php b/version.php index ace6bacb..1020878c 100644 --- a/version.php +++ b/version.php @@ -28,7 +28,7 @@ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'tiny_cursive'; -$plugin->release = '2.1.3'; -$plugin->version = 2026013100; +$plugin->release = '2.1.4'; +$plugin->version = 2026022000; $plugin->requires = 2022041912; $plugin->maturity = MATURITY_STABLE;