').html(text).text();
+
+ var stringarray = doc.splitTextToSize(text, characters);
+ var textbit;
+ for (var j = 0; j < stringarray.length; j++) {
+ //doc.setFont('NotoSans');
+ doc.setFont(undefined, 'normal');
+ textbit = stringarray[j];
if (count >= a4height) {
doc.addPage();
count = contentTopBottomMargin;
}
- doc.text(15, count, M.util.get_string('page', 'pdfannotator') + " " + page);
- doc.setFont(undefined, "normal");
+ doc.text(contentRightMargin, count, textbit);
count += 5;
- };
- // Add icon to each question depending on its annotation type and increment count by 5 or 7.
- addIcon(post['annotationtypeid']);
-
- // Add question in RWTH dark blue.
- var question = post['answeredquestion'];
- var author = post['author'];
- var timeasked = post['timemodified'];
- doc.setTextColor(0,84,159);
- breakLines(author, timeasked, question);
- // Add answers to the question in black (extremely dark blue which looks better).
- doc.setTextColor(0,0,51);
- var answers = post['answers'];
- var answer;
- for (var z = 0; z < answers.length; z++) {
- (function (innerZ){
- answer = answers[innerZ];
- count+= 5;
- breakLines(answer['author'], answer['timemodified'], answer['answer']);
- })(z);
- }
- })(i);
- count += 10;
- }
- var printtitle = title + "_" + M.util.get_string('comments', 'pdfannotator');
- doc.save(printtitle + ".pdf");
- /**
- * Take a user's post (i.e. an individual question or answer), determine whether
- * it contains latex formulae images or not and place its text and/or images on the pdf
- */
- function breakLines(author=null, timemodified=null, post, characters = 130) {
- // 1. print the author right away
- printAuthor(author, timemodified);
- post.forEach(function(subContent) {
- // Answer contains text only or any object such as array.
- if (typeof subContent === "string") {
- printTextblock(author, timemodified, subContent, characters);
- } else if (typeof subContent === "object") {
- printItem(subContent);
- }
- });
- }
- /**
- * Take a text block, split it into pieces no larger than 130 characters
- * and print one piece per line
- */
- function printTextblock(author=null, timemodified=null, text, characters = 130) {
- // In the comments linebreaks are represented by
-Tags. Sometimes there is an additional \n
- // jsPDF needs \n-linebreaks so we replace
with \n. But first we remove all \n that already exist.
- text = text.replace(/\n/g, "");
- text = text.replace(/
/g, "\n");
- // Remove all other HTML-Tags.
- text = $("
").html(text).text();
-
- var stringarray = doc.splitTextToSize(text, characters);
- var textbit;
- for (var j = 0; j < stringarray.length; j++) {
- //doc.setFont('NotoSans');
- doc.setFont(undefined, "normal");
- textbit = stringarray[j];
- if (count >= a4height) {
- doc.addPage();
- count = contentTopBottomMargin;
}
- doc.text(contentRightMargin, count, textbit);
- count += 5;
}
- }
- function printItem(item, index) {
- if (typeof item === "object") { //item.includes('data:image/png;base64,')) {
- if (item['mathform']) {
- printMathFrom(item);
- } else if (item['image']) {
- printImage(item);
+ function printItem(item, index) {
+ if (typeof item === 'object') {
+ //item.includes('data:image/png;base64,')) {
+ if (item['mathform']) {
+ printMathFrom(item);
+ } else if (item['image']) {
+ printImage(item);
+ }
+ } else if (typeof item === 'string') {
+ printTextblock(null, null, item);
+ } else {
+ console.error(M.util.get_string('error:printlatex', 'pdfannotator'));
+ notification.addNotification({
+ message: M.util.get_string('error:printlatex', 'pdfannotator'),
+ type: 'error',
+ });
}
- } else if (typeof item === "string"){
- printTextblock(null, null, item);
- } else {
- console.error(M.util.get_string('error:printlatex', 'pdfannotator'));
- notification.addNotification({
- message: M.util.get_string('error:printlatex','pdfannotator'),
- type: "error"
- });
}
- }
- function printImage(data) {
- var url;
- var image;
-
- if (data['image'] !== 'error') {
- image = data['image'];
- var height = data['imageheight'] * 0.264583333333334; // Convert pixel into mm.
- // Reduce height and witdh if its size more than a4height.
- while ( height > (a4height-(2*contentTopBottomMargin) )) {
- height = height - (height*0.1);
- }
- var width = data['imagewidth'] * 0.264583333333334;
- while ( width > (a4width-(contentLeftMargin+contentRightMargin)) ) {
- width = width - (width*0.1);
+ function printImage(data) {
+ var url;
+ var image;
+
+ if (data['image'] !== 'error') {
+ image = data['image'];
+ var height = data['imageheight'] * 0.264583333333334; // Convert pixel into mm.
+ // Reduce height and witdh if its size more than a4height.
+ while (height > a4height - 2 * contentTopBottomMargin) {
+ height = height - height * 0.1;
+ }
+ var width = data['imagewidth'] * 0.264583333333334;
+ while (width > a4width - (contentLeftMargin + contentRightMargin)) {
+ width = width - width * 0.1;
+ }
+ if (count + height >= a4height) {
+ doc.addPage();
+ count = contentTopBottomMargin;
+ }
+ doc.addImage(
+ image,
+ data['format'],
+ contentRightMargin,
+ count,
+ width,
+ height
+ ); // image data, format, offset to the left, offset to the top, width, height
+ count += 5 + height;
+ } else {
+ let item = `
${data['message']}
`;
+ printTextblock(null, null, item);
}
- if ( (count+height) >= a4height ) {
+ }
+ /**
+ * Take an image, calculate its height in millimeters and print it on the pdf
+ */
+ function printMathFrom(data) {
+ var img = data['mathform'];
+ var height = data['mathformheight'] * 0.264583333333334; // Convert pixel into mm.
+ if (count + height >= a4height) {
doc.addPage();
count = contentTopBottomMargin;
}
- doc.addImage(image, data['format'], contentRightMargin, count, width, height); // image data, format, offset to the left, offset to the top, width, height
- count += (5 + height);
- } else {
- let item = `
${data['message']}
`;
- printTextblock(null, null, item);
+ doc.addImage(img, data['format'], contentRightMargin, count, 0, 0); // image data, format, offset to the left, offset to the top, width, height
+ count += 5 + height;
}
- }
- /**
- * Take an image, calculate its height in millimeters and print it on the pdf
- */
- function printMathFrom(data) {
- var img = data['mathform'];
- var height = data['mathformheight'] * 0.264583333333334; // Convert pixel into mm.
- if ( (count+height) >= a4height ) {
- doc.addPage();
- count = contentTopBottomMargin;
- }
- doc.addImage(img, data['format'], contentRightMargin, count, 0, 0); // image data, format, offset to the left, offset to the top, width, height
- count += (5 + height);
- }
- /**
- * Print the author in bold
- * @param {type} author
- * @returns {undefined}
- */
- function printAuthor(author, timemodified=null) {
- doc.setFont(undefined, "bold");
- if (timemodified !== null) {
- doc.text(120, count, timemodified);
- }
- if (author.length > 37) {
+ /**
+ * Print the author in bold
+ * @param {type} author
+ * @returns {undefined}
+ */
+ function printAuthor(author, timemodified = null) {
+ doc.setFont(undefined, 'bold');
+ if (timemodified !== null) {
+ doc.text(120, count, timemodified);
+ }
+ if (author.length > 37) {
+ count += 5;
+ }
+ doc.text(contentRightMargin, count, author);
+ doc.setFont(undefined, 'normal');
count += 5;
}
- doc.text(contentRightMargin, count, author);
- doc.setFont(undefined, "normal");
- count += 5;
- }
- /**
- * Place an icon before each question, depending on the question's type of annotation
- * Increment the height variable so that the next line does not overlap with the currnet one
- */
- function addIcon(annotationtype) {
- if (count >= a4height) {
- doc.addPage();
- count = contentTopBottomMargin;
+ /**
+ * Place an icon before each question, depending on the question's type of annotation
+ * Increment the height variable so that the next line does not overlap with the currnet one
+ */
+ function addIcon(annotationtype) {
+ if (count >= a4height) {
+ doc.addPage();
+ count = contentTopBottomMargin;
+ }
+ var height = 5;
+ switch (annotationtype) {
+ case '1':
+ doc.addImage(myarea, 'PNG', 15, count, 5, 5);
+ break;
+ case '3':
+ doc.addImage(myhighlight, 'PNG', 15, count, 5, 5);
+ break;
+ case '4':
+ doc.addImage(mypin, 'PNG', 15, count, 5, 7);
+ height = 7;
+ break;
+ case '5':
+ doc.addImage(mystrikeout, 'PNG', 15, count, 5, 5);
+ break;
+ default:
+ doc.addImage(mypin, 'PNG', 15, count, 5, 7);
+ height = 7;
+ }
+ count += height;
}
- var height = 5;
- switch(annotationtype) {
- case '1':
- doc.addImage(myarea, 'PNG', 15, count, 5, 5);
- break;
- case '3':
- doc.addImage(myhighlight, 'PNG', 15, count, 5, 5);
- break;
- case '4':
- doc.addImage(mypin, 'PNG', 15, count, 5, 7);
- height = 7;
- break;
- case '5':
- doc.addImage(mystrikeout, 'PNG', 15, count, 5, 5);
- break;
- default:
- doc.addImage(mypin, 'PNG', 15, count, 5, 7);
- height = 7;
- }
- count+= height;
+ } else if (data.status === 'empty') {
+ notification.addNotification({
+ message: M.util.get_string('infonocomments', 'pdfannotator'),
+ type: 'info',
+ });
+ } else if (data.status === 'error') {
+ notification.addNotification({
+ message: M.util.get_string('error:printcomments', 'pdfannotator'),
+ type: 'error',
+ });
+ }
+ });
+ } // end of function openCommentsCallback
+ }
+ })();
+
+ /**
+ * First function to render the pdf document. Renders only the first page
+ * and triggers the function to sync the annotations.
+ * @returns {undefined}
+ */
+ function render() {
+ return pdfjsLib
+ .getDocument(RENDER_OPTIONS.documentPath)
+ .promise.then(
+ function fulfilled(pdf) {
+ RENDER_OPTIONS.pdfDocument = pdf;
+ pdf.getPage(1).then(function (result) {
+ let rotate = result._pageInfo.rotate;
+ RENDER_OPTIONS.rotate =
+ parseInt(localStorage.getItem(documentId + '/rotate'), 10) || rotate;
+
+ var viewer = document.getElementById('viewer');
+ viewer.innerHTML = '';
+ NUM_PAGES = pdf._pdfInfo.numPages;
+ for (var i = 0; i < NUM_PAGES; i++) {
+ var page = UI.createPage(i + 1);
+ viewer.appendChild(page);
}
+ return UI.renderPage(_page, RENDER_OPTIONS, true).then(function (_ref) {
+ var _ref2 = _slicedToArray(_ref, 2);
+
+ var pdfPage = _ref2[0];
+ var annotations = _ref2[1];
+ var viewport = pdfPage.getViewport({
+ scale: RENDER_OPTIONS.scale,
+ rotation: RENDER_OPTIONS.rotate,
+ });
+ PAGE_HEIGHT = viewport.height;
- } else if (data.status === 'empty') {
- notification.addNotification({
- message: M.util.get_string('infonocomments','pdfannotator'),
- type: "info"
- });
- } else if(data.status === 'error') {
- notification.addNotification({
- message: M.util.get_string('error:printcomments','pdfannotator'),
- type: "error"
+ //Set the right page height to every nonseen page to calculate the current seen page better during scrolling
+ document.querySelectorAll('#viewer .page').forEach(function (elem) {
+ elem.style.height = PAGE_HEIGHT + 'px';
+ });
+
+ if (!$('.path-mod-pdfannotator').first().hasClass('fullscreenWrapper')) {
+ var pageheight100 = pdfPage.getViewport({
+ scale: 1,
+ rotation: 0,
+ }).height;
+ $('#body-wrapper').css('height', pageheight100 + 40);
+ }
+ document.getElementById('currentPage').value = _page;
+ document.getElementById('currentPage').max = NUM_PAGES;
+ document.getElementById('sumPages').innerHTML = NUM_PAGES;
+
+ //pick annotation, if the annotation id has been passed
+ if (_annoid !== null) {
+ UI.pickAnnotation(_page, _annoid, _commid);
+ } else {
+ UI.renderAllQuestions(documentId, _page);
+ }
+
+ setTimeout(UI.loadNewAnnotations, 5000);
});
- }
- });
- } // end of function openCommentsCallback
- }
-
- })();
-
- /**
- * First function to render the pdf document. Renders only the first page
- * and triggers the function to sync the annotations.
- * @returns {undefined}
- */
- function render() {
-
- return pdfjsLib.getDocument(RENDER_OPTIONS.documentPath).promise.then(function fulfilled(pdf) {
- RENDER_OPTIONS.pdfDocument = pdf;
- pdf.getPage(1).then(function(result){
- let rotate = result._pageInfo.rotate;
- RENDER_OPTIONS.rotate = parseInt(localStorage.getItem(documentId + '/rotate'), 10) || rotate;
-
- var viewer = document.getElementById('viewer');
- viewer.innerHTML = '';
- NUM_PAGES = pdf._pdfInfo.numPages;
- for (var i = 0; i < NUM_PAGES; i++) {
- var page = UI.createPage(i + 1);
- viewer.appendChild(page);
- }
- return UI.renderPage(_page, RENDER_OPTIONS, true).then(function (_ref) {
- var _ref2 = _slicedToArray(_ref, 2);
-
- var pdfPage = _ref2[0];
- var annotations = _ref2[1];
- var viewport = pdfPage.getViewport({scale:RENDER_OPTIONS.scale, rotation:RENDER_OPTIONS.rotate});
- PAGE_HEIGHT = viewport.height;
-
- //Set the right page height to every nonseen page to calculate the current seen page better during scrolling
- document.querySelectorAll('#viewer .page').forEach(function(elem){
- elem.style.height = PAGE_HEIGHT+'px';
- });
-
- if (! $('.path-mod-pdfannotator').first().hasClass('fullscreenWrapper')) {
- var pageheight100 = pdfPage.getViewport({scale:1, rotation:0}).height;
- $('#body-wrapper').css('height',pageheight100+40);
- }
- document.getElementById('currentPage').value = _page;
- document.getElementById('currentPage').max = NUM_PAGES;
- document.getElementById('sumPages').innerHTML = NUM_PAGES;
-
- //pick annotation, if the annotation id has been passed
- if(_annoid !== null){
- UI.pickAnnotation(_page,_annoid,_commid);
- }else{
- UI.renderAllQuestions(documentId, _page);
- }
-
- setTimeout(UI.loadNewAnnotations, 5000);
- });
- });
- },function rejected(err){
- let child = document.createElement('div');
- child.innerHTML = M.util.get_string('error:openingPDF', 'pdfannotator');
- document.getElementById('viewer').appendChild(child);
- }).catch(function (err) {
- let child = document.createElement('div');
- child.innerHTML = M.util.get_string('error:openingPDF', 'pdfannotator');
- document.getElementById('viewer').appendChild(child);
- });
- }
-
- render();
-
- //initialize button allQuestions
- (function (){
- document.querySelector('#allQuestions').addEventListener('click', function(){
- UI.renderAllQuestions(documentId);
- });
- })();
-
- //initialize button questionsOnThisPage
- (function (){
- document.querySelector('#questionsOnThisPage').addEventListener('click', function(){
- var pageNumber = document.getElementById('currentPage').value;
- UI.renderQuestions(documentId, pageNumber, 1);
-
- });
- })();
-
- /**
- * Function for a fixed toolbar, when scrolliing down. But only as long as the document is visible.
- * @returns {undefined}
- */
- (function () {
- var top = $('#pdftoolbar').offset().top - parseFloat($('#pdftoolbar').css('marginTop').replace(/auto/, 0));
- var width = $('#pdftoolbar').width();
- var fixedTop = 0; // Height of moodle-navbar.
- if ($('.fixed-top').length > 0) {
- fixedTop = $('.fixed-top').outerHeight();
- } else if ($('.navbar-static-top').length > 0) {
- fixedTop = $('.navbar-static-top').outerHeight();
- }
- var toolbarHeight = $('#pdftoolbar').outerHeight();
- var contentTop = $('#content-wrapper').offset().top;
-
- var oldTop = $('#pdftoolbar').css('top');
- var contentHeight = $('#content-wrapper').height();
- var bottom = contentTop+contentHeight-fixedTop - toolbarHeight;
-
- $(window).scroll(function (event) {
- var y = $(this).scrollTop();
-
- // Calculate again in case contentHeight was 1 (because content wasn't loaded yet?)
- contentHeight = $('#content-wrapper').height();
- bottom = contentTop + contentHeight - fixedTop - toolbarHeight;
- var notifications = $('#user-notifications').children();
-
- if (y >= top + 1 - fixedTop && y < bottom - 50 && !notifications) {
- $('#pdftoolbar').addClass('fixtool');
- $('#pdftoolbar').width(width);
- document.getElementById("pdftoolbar").style.top = fixedTop + "px";
- } else {
- $('#pdftoolbar').removeClass('fixtool');
- document.getElementById("pdftoolbar").style.top = oldTop;
- }
- });
-
- // adjust width of toolbar
- $(window).resize( function() {
- width = $('#pdftoolbar').parent().width();
- $('#pdftoolbar').width(width);
- })
- })();
-
- //initialize searchForm
- (function(){
- // hide form and show/hide it after click on the search icon
- $('#searchForm').hide();
- $('#searchButton').click( function (e) {
- $('#searchForm').toggle();
- $('#searchPattern').val('');
- $('#searchClear').hide();
- $('#searchPattern').focus();
- });
- // Search if the user typed
- $('#searchPattern').keyup( function(e) {
- if($('#searchPattern').val().length > 0){
- $('#searchClear').show();
- } else {
- $('#searchClear').hide();
+ });
+ },
+ function rejected(err) {
+ let child = document.createElement('div');
+ child.innerHTML = M.util.get_string('error:openingPDF', 'pdfannotator');
+ document.getElementById('viewer').appendChild(child);
+ }
+ )
+ .catch(function (err) {
+ let child = document.createElement('div');
+ child.innerHTML = M.util.get_string('error:openingPDF', 'pdfannotator');
+ document.getElementById('viewer').appendChild(child);
+ });
}
- let pageNumber = document.getElementById('currentPage').value;
- UI.renderQuestions(documentId, pageNumber, 1);
- });
-
- //Clear-Button
- $('#searchForm').submit (function(e) {
- $('#searchPattern').val('');
- $('#searchClear').hide();
- let pageNumber = document.getElementById('currentPage').value;
- UI.renderQuestions(documentId, pageNumber, 1);
- return false;
- });
-
- })();
-
-
-
- if(_toolbarSettings.use_studenttextbox === "1"|| _capabilities.usetextbox){
- // initialize the textbox
- (function () {
- var textSize = void 0;
- var textColor = void 0;
-
- function initText() {
- var size = document.querySelector('.toolbar .text-size');
- [8, 9, 10, 11, 12, 14, 18, 24, 30, 36, 48, 60, 72, 96].forEach(function (s) {
- size.appendChild(new Option(s, s));
- });
-
- setText(localStorage.getItem(RENDER_OPTIONS.documentId + '/text/size') || 10, localStorage.getItem(RENDER_OPTIONS.documentId + '/text/color') || '#000000');
-
- (0, _initColorPicker2.default)(document.querySelector('.text-color'), textColor, function (value) {
- setText(textSize, value);
- });
- }
- function setText(size, color) {
- var modified = false;
-
- if (textSize !== size) {
- modified = true;
- textSize = size;
- localStorage.setItem(RENDER_OPTIONS.documentId + '/text/size', textSize);
- document.querySelector('.toolbar .text-size').value = textSize;
- }
-
- if (textColor !== color) {
- modified = true;
- textColor = color;
- localStorage.setItem(RENDER_OPTIONS.documentId + '/text/color', textColor);
-
- var selected = document.querySelector('.toolbar .text-color.color-selected');
- if (selected) {
- selected.classList.remove('color-selected');
- selected.removeAttribute('aria-selected');
- }
+ render();
- selected = document.querySelector('.toolbar .text-color[data-color="' + color + '"]');
- if (selected) {
- selected.classList.add('color-selected');
- selected.setAttribute('aria-selected', true);
- }
- }
+ //initialize button allQuestions
+ (function () {
+ document.querySelector('#allQuestions').addEventListener('click', function () {
+ UI.renderAllQuestions(documentId);
+ });
+ })();
- if (modified) {
- UI.setText(textSize, textColor);
- }
- }
+ //initialize button questionsOnThisPage
+ (function () {
+ document.querySelector('#questionsOnThisPage').addEventListener('click', function () {
+ var pageNumber = document.getElementById('currentPage').value;
+ UI.renderQuestions(documentId, pageNumber, 1);
+ });
+ })();
+
+ /**
+ * Initialize buttons comment-visibility
+ * @returns {undefined}
+ */
+ (function () {
+ const visibilityButtons = document.querySelectorAll('.comment-visibility-button');
+ const clearActiveAttribute = (nodes) => {
+ nodes.forEach(btn => {btn.setAttribute('data-active', false)});
+ };
+ visibilityButtons.forEach(btn => {
+ btn.addEventListener('click', function () {
+ if(btn.getAttribute('data-active') === 'false'){
+ clearActiveAttribute(visibilityButtons);
+ btn.setAttribute('data-active', true);
+ const pageNumber = document.getElementById('currentPage').value;
+ UI.renderQuestions(documentId, pageNumber, 1);
+ }
+ });
+ });
+ })();
+
+ /**
+ * Function for a fixed toolbar, when scrolliing down. But only as long as the document is visible.
+ * @returns {undefined}
+ */
+ (function () {
+ var top =
+ $('#pdftoolbar').offset().top -
+ parseFloat($('#pdftoolbar').css('marginTop').replace(/auto/, 0));
+ var width = $('#pdftoolbar').width();
+ var fixedTop = 0; // Height of moodle-navbar.
+ if ($('.fixed-top').length > 0) {
+ fixedTop = $('.fixed-top').outerHeight();
+ } else if ($('.navbar-static-top').length > 0) {
+ fixedTop = $('.navbar-static-top').outerHeight();
+ }
+ var toolbarHeight = $('#pdftoolbar').outerHeight();
+ var contentTop = $('#content-wrapper').offset().top;
- function handleTextSizeChange(e) {
- setText(e.target.value, textColor);
- document.querySelector('#pdftoolbar button.text').click(); // Select text.
- }
-
- document.querySelector('.toolbar .text-size').addEventListener('change', handleTextSizeChange);
+ var oldTop = $('#pdftoolbar').css('top');
+ var contentHeight = $('#content-wrapper').height();
+ var bottom = contentTop + contentHeight - fixedTop - toolbarHeight;
- initText();
- })(); // Initialize textbox end.
- }
-
- if(_toolbarSettings.use_studentdrawing === "1"|| _capabilities.usedrawing){
- // Initialize pen.
- (function () {
- var penSize = void 0;
- var penColor = void 0;
-
- function initPen() {
- var size = document.querySelector('.toolbar .pen-size');
- for (var i = 0; i < 20; i++) {
- size.appendChild(new Option(i + 1, i + 1));
- }
+ $(window).scroll(function (event) {
+ var y = $(this).scrollTop();
- setPen(localStorage.getItem(RENDER_OPTIONS.documentId + '/pen/size') || 1, localStorage.getItem(RENDER_OPTIONS.documentId + '/pen/color') || '#000000');
+ // Calculate again in case contentHeight was 1 (because content wasn't loaded yet?)
+ contentHeight = $('#content-wrapper').height();
+ bottom = contentTop + contentHeight - fixedTop - toolbarHeight;
+ var notifications = $('#user-notifications').children();
- (0, _initColorPicker2.default)(document.querySelector('.pen-color'), penColor, function (value) {
- setPen(penSize, value);
- });
- }
+ if (y >= top + 1 - fixedTop && y < bottom - 50 && !notifications) {
+ $('#pdftoolbar').addClass('fixtool');
+ $('#pdftoolbar').width(width);
+ document.getElementById('pdftoolbar').style.top = fixedTop + 'px';
+ } else {
+ $('#pdftoolbar').removeClass('fixtool');
+ document.getElementById('pdftoolbar').style.top = oldTop;
+ }
+ });
+
+ // adjust width of toolbar
+ $(window).resize(function () {
+ width = $('#pdftoolbar').parent().width();
+ $('#pdftoolbar').width(width);
+ });
+ })();
+
+ //initialize searchForm
+ (function () {
+ // hide form and show/hide it after click on the search icon
+ $('#searchForm').hide();
+ $('#searchButton').click(function (e) {
+ $('#searchForm').toggle();
+ $('#searchPattern').val('');
+ $('#searchClear').hide();
+ $('#searchPattern').focus();
+ });
+ // Search if the user typed
+ $('#searchPattern').keyup(function (e) {
+ if ($('#searchPattern').val().length > 0) {
+ $('#searchClear').show();
+ } else {
+ $('#searchClear').hide();
+ }
+ let pageNumber = document.getElementById('currentPage').value;
+ UI.renderQuestions(documentId, pageNumber, 1);
+ });
- function setPen(size, color) {
- var modified = false;
+ //Clear-Button
+ $('#searchForm').submit(function (e) {
+ $('#searchPattern').val('');
+ $('#searchClear').hide();
+ let pageNumber = document.getElementById('currentPage').value;
+ UI.renderQuestions(documentId, pageNumber, 1);
+ return false;
+ });
+ })();
- if (penSize !== size) {
- modified = true;
- penSize = size;
- localStorage.setItem(RENDER_OPTIONS.documentId + '/pen/size', penSize);
- document.querySelector('.toolbar .pen-size').value = penSize;
- }
+ if (_toolbarSettings.use_studenttextbox === '1' || _capabilities.usetextbox) {
+ // initialize the textbox
+ (function () {
+ var textSize = void 0;
+ var textColor = void 0;
- if (penColor !== color) {
- modified = true;
- penColor = color;
- localStorage.setItem(RENDER_OPTIONS.documentId + '/pen/color', penColor);
-
- var selected = document.querySelector('.toolbar .pen-color.color-selected');
- if (selected) {
- selected.classList.remove('color-selected');
- selected.removeAttribute('aria-selected');
- }
-
- selected = document.querySelector('.toolbar .pen-color[data-color="' + color + '"]');
- if (selected) {
- selected.classList.add('color-selected');
- selected.setAttribute('aria-selected', true);
- }
- }
+ function initText() {
+ var size = document.querySelector('.toolbar .text-size');
+ [8, 9, 10, 11, 12, 14, 18, 24, 30, 36, 48, 60, 72, 96].forEach(function (s) {
+ size.appendChild(new Option(s, s));
+ });
- if (modified) {
- UI.setPen(penSize, penColor);
- }
- }
+ setText(
+ localStorage.getItem(RENDER_OPTIONS.documentId + '/text/size') || 10,
+ localStorage.getItem(RENDER_OPTIONS.documentId + '/text/color') || '#000000'
+ );
- function handlePenSizeChange(e) {
- setPen(e.target.value, penColor);
- document.querySelector('#pdftoolbar button.pen').click(); // Select pen.
- }
+ (0, _initColorPicker2.default)(
+ document.querySelector('.text-color'),
+ textColor,
+ function (value) {
+ setText(textSize, value);
+ }
+ );
+ }
- document.querySelector('.toolbar .pen-size').addEventListener('change', handlePenSizeChange);
+ function setText(size, color) {
+ var modified = false;
- initPen();
- })(); // End initialize pen.
- }
- // Toolbar buttons (defined in index.mustache) are given event listeners:
- (function () {
- //Cursor should always be default selected
- var tooltype = 'cursor';
- if (tooltype) {
- setActiveToolbarItem(tooltype, document.querySelector('.toolbar button[data-tooltype=' + tooltype + ']'));
- }
-
- function setActiveToolbarItem(type, button) {
- var active = document.querySelector('.toolbar button.active');
- if (active) {
- active.classList.remove('active');
-
- switch (tooltype) {
- case 'cursor':
- UI.disableEdit();
- break;
- case 'draw':
- UI.disablePen();
- break;
- case 'text':
- UI.disableText();
- break;
- case 'point':
- UI.disablePoint();
- break;
- case 'area':
- case 'highlight':
- case 'strikeout':
- UI.disableRect();
- break;
- }
- }
-
- if (button) {
- button.classList.add('active');
- }
- if (tooltype !== type) {
- localStorage.setItem(RENDER_OPTIONS.documentId + '/tooltype', type);
- }
- tooltype = type;
-
- switch (type) {
- case 'cursor':
- UI.enableEdit();
- break;
- case 'draw':
- UI.enablePen();
- break;
- case 'text':
- UI.enableText();
- break;
- case 'point':
- UI.enablePoint();
- break;
- case 'area':
- case 'highlight':
- case 'strikeout':
- UI.enableRect(type);
- break;
- }
- }
-
- function handleToolbarClick(e) {
- var target = e.target;
- //The content of some buttons are img-tags.
- //Then the nodeName of the clicked target will be IMG, but we need the outer button element
- if((target.nodeName === 'IMG' || target.nodeName === 'I') && target.parentElement.nodeName === 'BUTTON'){
- target = e.target.parentElement;
- }
- if (target.nodeName === 'BUTTON') {
- //Only setActiveToolbarItem if the button is not disabled! (It is disables, if the annotations are hidden)
- if(!target.disabled){
- setActiveToolbarItem(target.getAttribute('data-tooltype'), target);
- }
- }
- //clear right side (comment-wrapper), if there are comments of an annotation
- var form = document.querySelector('.comment-list-form');
- if(form.style.display !== 'none'){
- form.style.display = 'none';
- document.querySelector('.comment-list-container').innerHTML = '';
- }
- }
- document.querySelector('.toolbar').addEventListener('click', handleToolbarClick);
- })(); //end Toolbar buttons
-
- // Scale
-
- (function () {
- function setScaleRotate(scale, rotate) {
- scale = parseFloat(scale, 10);
- rotate = parseInt(rotate, 10);
-
- if (RENDER_OPTIONS.scale !== scale || RENDER_OPTIONS.rotate !== rotate) {
- RENDER_OPTIONS.scale = scale;
- RENDER_OPTIONS.rotate = rotate;
-
- localStorage.setItem(RENDER_OPTIONS.documentId + '/scale', RENDER_OPTIONS.scale);
- localStorage.setItem(RENDER_OPTIONS.documentId + '/rotate', RENDER_OPTIONS.rotate % 360);
- _page = parseInt(document.getElementById('currentPage').value);
-
- let pagecontainer = document.getElementById('pageContainer'+_page);
- let loader = document.createElement('div');
- loader.id = "loader";
-
- document.body.appendChild(loader);
- render().then(function(){
- $('#content-wrapper').scrollTop(document.getElementById('pageContainer'+_page).offsetTop);
- document.body.removeChild(loader);
- });
- }
- }
-
- function handleScaleChange(e) {
- setScaleRotate(e.target.value, RENDER_OPTIONS.rotate);
- }
-
- function handleRotateCWClick() {
- setScaleRotate(RENDER_OPTIONS.scale, RENDER_OPTIONS.rotate + 90);
- }
-
- function handleRotateCCWClick() {
- setScaleRotate(RENDER_OPTIONS.scale, RENDER_OPTIONS.rotate - 90);
- }
-
- document.querySelector('.toolbar select.scale').value = RENDER_OPTIONS.scale;
-
- // Add eventHandlers to select and +/- Button for scaling
- $('.toolbar select.scale').change(handleScaleChange);
-
- let options = document.querySelector('.toolbar select.scale').options.length;
- document.querySelector('.toolbar #scalePlus').addEventListener('click', function() {
- handleScaleButton(1);
- });
- document.querySelector('.toolbar #scaleMinus').addEventListener('click', function() {
- handleScaleButton(-1);
- });
-
- function handleScaleButton(value){
- let index = document.querySelector('.toolbar select.scale').selectedIndex + value;
- if (index >= 0 && index < options) {
- document.querySelector('.toolbar select.scale').selectedIndex = index;
- }
- $('.toolbar select.scale').change();
- setTimeout(function(){
- document.getElementById('pdfannotator_cursor').click();
- }, 100);
- }
-
- })(); //end scale rotate
-
- // Hide/Show annotations Button
- (function(){
- //hide is 'block' for display annotations and 'none' for hide annotations
- var hide = localStorage.getItem(RENDER_OPTIONS.documentId + '/hide') || 'block';
-
- function handleHideClick(e) {
- toggleHide(e);
-
- for (var i = 0; i < NUM_PAGES; i++) {
- document.querySelector('div#pageContainer' + (i + 1) + ' svg.annotationLayer').style.display = hide;
- }
- }
-
- function toggleHide(e){
- let img;
- let a;
- if(e.target.tagName === 'A'){
- a = e.target;
- img = e.target.childNodes[0];
- }else{
- img = e.target;
- a = img.parentNode;
- }
- hide = hide === 'block'? 'none' :'block';
- img.src = img.src.indexOf('accessibility_checker') !== -1 ? M.util.image_url('/i/hide') /*'/moodle/theme/image.php/clean/core/1504678549/i/hide' */ : M.util.image_url('/e/accessibility_checker'); // '/moodle/theme/image.php/clean/core/1504678549/e/accessibility_checker';
- if(hide === 'block'){
- document.querySelectorAll('.toolbar button[data-tooltype]').forEach(function(elem){
- elem.disabled = false;
- });
- img.alt = M.util.get_string('hideAnnotations','pdfannotator');
- img.title = M.util.get_string('hideAnnotations','pdfannotator');
- a.title = M.util.get_string('hideAnnotations','pdfannotator');
- }else{
- document.querySelectorAll('.toolbar button[data-tooltype]').forEach(function(elem){
- elem.disabled = true;
- });
- img.alt = M.util.get_string('showAnnotations','pdfannotator');
- img.title = M.util.get_string('showAnnotations','pdfannotator');
- a.title = M.util.get_string('showAnnotations','pdfannotator');
- }
- }
- document.querySelector('a.hideComments').addEventListener('click', handleHideClick);
- })(); //end hide/show annotations button
-
- // Jump to Page
- (function(){
- var currentPageInput = $('#currentPage');
- var oldPage = currentPageInput.val();
-
- function jumpToPage(){
- var numPages = parseInt($('#sumPages').html(), 10);
- var newPage = parseInt(currentPageInput.val(), 10);
-
- var inputValid = false;
- if (Number.isInteger(newPage)){
- if (newPage >= 1 && newPage <= numPages ){
- inputValid = true;
- }
- }
+ if (textSize !== size) {
+ modified = true;
+ textSize = size;
+ localStorage.setItem(RENDER_OPTIONS.documentId + '/text/size', textSize);
+ document.querySelector('.toolbar .text-size').value = textSize;
+ }
- if(!inputValid){
- currentPageInput.val(oldPage);
- return;
- }
-
- oldPage = newPage;
- $('#content-wrapper').scrollTop(document.getElementById('pageContainer'+newPage).offsetTop);
- }
-
- // Add eventListener for inputfield and buttons
- currentPageInput.change(jumpToPage);
-
- $('#nextPage').click(function(){
- currentPageInput.val(parseInt(currentPageInput.val(), 10) + 1);
- currentPageInput.change();
- setTimeout(function(){
- document.getElementById('pdfannotator_cursor').click();
- }, 100);
- });
- $('#prevPage').click(function(){
- currentPageInput.val(parseInt(currentPageInput.val(), 10) - 1);
- currentPageInput.change();
- setTimeout(function(){
- document.getElementById('pdfannotator_cursor').click();
- }, 100);
- });
- })();
-
- // Make toolbar responsive: Elements that can't be displayed in one row, are in a dropdown.
- (function () {
- // Set width as attribute because width of elements in dropdown is 0 if dropdown is collapsed.
- $('#toolbarContent').children().each(function(){
- $(this).attr('visibleWidth', $(this).outerWidth());
- });
-
- function responsiveToolbar() {
- let changed = false;
- do {
- changed = false;
- let lastElement = $('#toolbarContent').children(':not(.pdf-annotator-hidden)').last(); // Last visible element in toolbar.
- let firstDropdownElement = $('#toolbar-dropdown-content').children().first(); // First element in dropdown.
- let firstWidth = parseInt(firstDropdownElement.attr('visibleWidth')); // Width of first element in dropdown.
- // If lastElem is displayed in a second row because screen isn't wide enough.
- if (lastElement.offset().top > $('#toolbarContent').offset().top + 10) {
- // Move last element (not dropdown-button) into dropdown and display button.
- let toolbarElements = $('#toolbarContent').children(':not(#toolbar-dropdown-button)');
- if(toolbarElements.length > 0) {
- lastElement = toolbarElements.last();
- $('#toolbar-dropdown-content').prepend(lastElement);
- $('#toolbar-dropdown-button').removeClass('pdf-annotator-hidden');
- changed = true;
+ if (textColor !== color) {
+ modified = true;
+ textColor = color;
+ localStorage.setItem(RENDER_OPTIONS.documentId + '/text/color', textColor);
+
+ var selected = document.querySelector('.toolbar .text-color.color-selected');
+ if (selected) {
+ selected.classList.remove('color-selected');
+ selected.removeAttribute('aria-selected');
+ }
+
+ selected = document.querySelector('.toolbar .text-color[data-color="' + color + '"]');
+ if (selected) {
+ selected.classList.add('color-selected');
+ selected.setAttribute('aria-selected', true);
+ }
+ }
+
+ if (modified) {
+ UI.setText(textSize, textColor);
+ }
}
- // If there is enough space to display the next hidden element.
- } else if ((firstDropdownElement.length !== 0) &&
- (lastElement.offset().left + lastElement.outerWidth() + firstWidth + 20 < $('#toolbarContent').offset().left + $('#toolbarContent').width())){
- firstDropdownElement.insertBefore('#toolbar-dropdown-button'); // Move element from dropdown to toolbar.
- // Hide button if all elements are shown.
- if ($('#toolbar-dropdown-content').children().length === 0){
- $('#toolbar-dropdown-button').addClass('pdf-annotator-hidden');
+
+ function handleTextSizeChange(e) {
+ setText(e.target.value, textColor);
+ document.querySelector('#pdftoolbar button.text').click(); // Select text.
}
- changed = true;
- }
- } while (changed);
- }
- responsiveToolbar();
- $(window).resize(responsiveToolbar);
- $('#toolbar-dropdown-button').click(function(){
- setTimeout(function(){
- document.getElementById('pdfannotator_cursor').click();
- }, 100);
- });
-
- })();
-
- // Comment annotations.
- (function (window, document) {
- var commentList = document.querySelector('#comment-wrapper .comment-list-container'); // to be found in index.php
- var commentForm = document.querySelector('#comment-wrapper .comment-list-form'); // to be found in index.php
-
- // Function checks whether the target annotation type allows comments.
- function supportsComments(target) {
- var type = target.getAttribute('data-pdf-annotate-type');
- return ['point', 'highlight', 'area', 'strikeout'].indexOf(type) > -1;
- }
-
-
- /*
- * Function inserts a comment into the HTML DOM for display.
- * A comment consists of its content as well as a delete button, wrapped up in a shared div.
- *
- * @return {Element}
- */
- function insertComments(comments, markCommentid = undefined) {
- if(!comments) {
- return false;
- }
- if(!comments.comments){
- comments = {comments: [comments]};
+
+ document.querySelector('.toolbar .text-size').addEventListener('change', handleTextSizeChange);
+
+ initText();
+ })(); // Initialize textbox end.
}
-
- (function(templates, data) {
- if(data.comments[0] !== false) {
- templates.render('mod_pdfannotator/comment', data)
- .then(function(html,js){
- if(data.comments.length === 1 && !data.comments[0].isquestion) {
- $('.comment-list-container').append(html);
- } else {
- templates.replaceNodeContents('.comment-list-container', html, js);
- }
- }).then(function() {
- data.comments.forEach(function(comment) {
- createVoteHandler(comment);
- createEditFormHandler(comment);
- createSubscriptionHandler(comment);
- createHideHandler(comment);
- createDeleteHandler(comment);
- createSolvedHandler(comment);
- let pattern = $('#searchPattern').val();
- if(pattern !== '' && comment.content.search(new RegExp(pattern, "i")) !== -1){
- $('#comment_'+comment.uuid).addClass('mark');
- }
-
- let selector = '#comment_' + comment.uuid + ' .chat-message-text p';
- let element = document.querySelector(selector);
- renderMathJax(element);
- });
- //if the target has the attribute markCommentid a specific comment should be marked with an red border.
- //after 3 sec the border should disappear.
- if(markCommentid !== undefined && markCommentid !== null){
- $('#comment_'+markCommentid).addClass('mark');
- markCommentid = undefined;
- setTimeout(function(){
- if(document.querySelector('#comment_'+markCommentid)){
- document.querySelector('#comment_'+markCommentid).style.border = "none";
- }
- },3000);
+ if (_toolbarSettings.use_studentdrawing === '1' || _capabilities.usedrawing) {
+ // Initialize pen.
+ (function () {
+ var penSize = void 0;
+ var penColor = void 0;
+
+ function initPen() {
+ var size = document.querySelector('.toolbar .pen-size');
+ for (var i = 0; i < 20; i++) {
+ size.appendChild(new Option(i + 1, i + 1));
}
- }).catch(notification.exception);
- }
- })(templates, comments);
- return true;
- }
-
- function createSolvedHandler(comment){
- var button = $('#comment_'+comment.uuid+' .comment-solve-a');
- var i = $('#comment_'+comment.uuid+' .comment-solve-a i');
- var span = $('#comment_'+comment.uuid+' .comment-solve-a span.menu-action-text');
- var img = $('#comment_'+comment.uuid+' .comment-solve-a img');
- button.click(function(e) {
- _2.default.getStoreAdapter().markSolved(RENDER_OPTIONS.documentId, comment)
- });
- }
-
- function createSubscriptionHandler(comment){
-
- var button = $('#comment_'+comment.uuid+' .comment-subscribe-a');
- var i = $('#comment_'+comment.uuid+' .comment-subscribe-a i');
- var span = $('#comment_'+comment.uuid+' .comment-subscribe-a span.menu-action-text')
- button.click(function(e) {
- if(comment.issubscribed){
- _2.default.getStoreAdapter().unsubscribeQuestion(RENDER_OPTIONS.documentId, comment.annotation)
- .then(function(data){
- if(data.status === "success") {
- notification.addNotification({
- message: M.util.get_string('successfullyUnsubscribed', 'pdfannotator'),
- type: "success"
- });
- setTimeoutNotification()
- } else if(data.status == 'error') {
- notification.addNotification({
- message: M.util.get_string('error:unsubscribe','pdfannotator'),
- type: "error"
- });
- console.error(M.util.get_string('error:unsubscribe', 'pdfannotator'));
- }
- span.text(M.util.get_string('subscribeQuestion', 'pdfannotator'));
- });
- } else {
- _2.default.getStoreAdapter().subscribeQuestion(RENDER_OPTIONS.documentId, comment.annotation)
- .then(function(data){
- if(data.status === "success") {
- notification.addNotification({
- message: M.util.get_string('successfullySubscribednotify', 'pdfannotator'),
- type: "success"
- });
- setTimeoutNotification();
- } else if(data.status == 'error') {
- notification.addNotification({
- message: M.util.get_string('error:subscribe','pdfannotator'),
- type: "error"
- });
- console.error(M.util.get_string('error:subscribe', 'pdfannotator'));
- }
- span.text(M.util.get_string('unsubscribeQuestion', 'pdfannotator'));
- });
- }
- comment.issubscribed = !comment.issubscribed;
- i.toggleClass("fa-bell");
- i.toggleClass("fa-bell-slash");
- });
- }
-
- function createVoteHandler(comment){
- // Create an element for click.
- var likeButton = $('#comment_'+comment.uuid+' .comment-like-a');
- if (comment.isdeleted == 1 || !comment.usevotes) {
- likeButton.attr("disabled","disabled");
- likeButton.css("visibility", "hidden");
- } else if ((comment.userid == _userid) || (comment.isvoted)) {
- likeButton.attr("disabled","disabled");
- }
-
- likeButton.click(function(e) {
- _2.default.getStoreAdapter().voteComment(RENDER_OPTIONS.documentId, comment.uuid)
- .then(function(data){
- if(data.status == 'error') {
- notification.addNotification({
- message: M.util.get_string('error:voteComment','pdfannotator'),
- type: "error"
- });
- console.error(M.util.get_string('error:voteComment', 'pdfannotator'));
- } else {
- // Update number of votes and disable button.
- var voteDiv = document.querySelector("div#comment_"+comment.uuid+" div.wrappervotessolved");
- var button = voteDiv.querySelector("button");
- var img = button.querySelector("i");
- var div = voteDiv.querySelector(".countVotes");
-
- button.disabled = true;
- div.innerHTML = data.numberVotes;
- if (comment.isquestion==1) {
- button.title = M.util.get_string('likeQuestionForbidden', 'pdfannotator'); //button
- img.title = M.util.get_string('likeQuestionForbidden', 'pdfannotator'); //img
- img.alt = M.util.get_string('likeQuestionForbidden', 'pdfannotator'); //img
- div.title = data.numberVotes + " " + M.util.get_string('likeCountQuestion', 'pdfannotator');
- } else {
- button.title = M.util.get_string('likeAnswerForbidden', 'pdfannotator');
- img.title = M.util.get_string('likeAnswerForbidden', 'pdfannotator'); //img
- img.alt = M.util.get_string('likeAnswerForbidden', 'pdfannotator'); //img
- div.title = data.numberVotes + " " + M.util.get_string('likeCountAnswer', 'pdfannotator');
+
+ setPen(
+ localStorage.getItem(RENDER_OPTIONS.documentId + '/pen/size') || 1,
+ localStorage.getItem(RENDER_OPTIONS.documentId + '/pen/color') || '#000000'
+ );
+
+ (0, _initColorPicker2.default)(
+ document.querySelector('.pen-color'),
+ penColor,
+ function (value) {
+ setPen(penSize, value);
}
- }
- });
- });
- }
+ );
+ }
- /**
- * Function enables managers to hide a comment from participants
- * or to display it to participants once more.
- *
- * @param {type} comment
- * @returns {undefined}
- */
- function createHideHandler(comment){
-
- var button = $('#hideButton'+comment.uuid);
-
- button.click(function(e) {
- var icon = button.children().first();
- var menutext = button.children().last();
- if(comment.ishidden){
- _2.default.getStoreAdapter().redisplayComment(RENDER_OPTIONS.documentId, comment.uuid);
- menutext.html(M.util.get_string('markhidden', 'pdfannotator'));
- } else {
- _2.default.getStoreAdapter().hideComment(RENDER_OPTIONS.documentId, comment.uuid);
- menutext.html(M.util.get_string('removehidden', 'pdfannotator'));
- }
- comment.ishidden = !comment.ishidden;
- icon.toggleClass("fa-eye");
- icon.toggleClass("fa-eye-slash");
- });
- }
+ function setPen(size, color) {
+ var modified = false;
- /**
- * Function handles opening/closing and submitting the edit comment form.
- * @param {type} comment
- * @returns {undefined}
- */
- function createEditFormHandler(comment) {
- // Create an element for click.
- var editButton = $('#editButton'+comment.uuid);
- // Add an event handler to the click element that opens a textarea and fills it with the current comment.
- editButton.click(function(e) {
- UI.loadEditor('edit', comment.uuid, handleClickIfEditorExists);
- function handleClickIfEditorExists() {
- // Add an event handler to the form for submitting any changes to the database.
- let editForm = document.getElementById(`edit${comment.uuid}`);
- editForm.onsubmit = function (e) {
- let editTextarea = document.getElementById(`editarea${comment.uuid}`);
- let editAreaEditable = document.getElementById(`editarea${comment.uuid}editable`);
- let chatMessage = document.getElementById(`chatmessage${comment.uuid}`);
-
- let newContent = editTextarea.value.trim(); // If atto editor is used.
- var iframe = document.getElementById("myarea_ifr"); // If tinymce editor is used.
- if (iframe) {
- let editorArea = iframe.contentWindow.document.getElementById("tinymce");
- newContent = editorArea.innerHTML;
+ if (penSize !== size) {
+ modified = true;
+ penSize = size;
+ localStorage.setItem(RENDER_OPTIONS.documentId + '/pen/size', penSize);
+ document.querySelector('.toolbar .pen-size').value = penSize;
}
- if (newContent.length === 0) {
- // Should be more than one character, otherwise it should not be saved.
- notification.addNotification({
- message: M.util.get_string('min0Chars','pdfannotator'),
- type: "error"
- });
- } else if(newContent === comment.displaycontent) { // No changes.
- editForm.style.display = "none";
- chatMessage.innerHTML = comment.displaycontent;
- renderMathJax(chatMessage);
- } else { // Save changes.
- _2.default.getStoreAdapter().editComment(documentId, comment.uuid, newContent, editForm)
- .then(function(data){
- if (data.status === "success") {
- editForm.style.display = "none";
- $(`edit_comment_editor_wrapper_${comment.uuid}`).remove();
- if (data.modifiedby) {
- $('#comment_' + comment.uuid + ' .edited').html(M.util.get_string('editedComment', 'pdfannotator') + " " + data.timemodified + " " + M.util.get_string('modifiedby', 'pdfannotator') + " " + data.modifiedby);
- } else {
- $('#comment_' + comment.uuid + ' .edited').html( M.util.get_string('editedComment', 'pdfannotator') + " " + data.timemodified);
- }
- newContent = data.newContent;
- chatMessage.innerHTML = newContent;
- comment.content = newContent;
- comment.displaycontent = newContent;
- editTextarea = newContent;
- renderMathJax(chatMessage);
- notification.addNotification({
- message: M.util.get_string('successfullyEdited', 'pdfannotator'),
- type: "success"
- });
- setTimeoutNotification();
- } else {
- notification.addNotification({
- message: M.util.get_string('error:editComment','pdfannotator'),
- type: "error"
- });
- }
- });
+
+ if (penColor !== color) {
+ modified = true;
+ penColor = color;
+ localStorage.setItem(RENDER_OPTIONS.documentId + '/pen/color', penColor);
+
+ var selected = document.querySelector('.toolbar .pen-color.color-selected');
+ if (selected) {
+ selected.classList.remove('color-selected');
+ selected.removeAttribute('aria-selected');
+ }
+
+ selected = document.querySelector('.toolbar .pen-color[data-color="' + color + '"]');
+ if (selected) {
+ selected.classList.add('color-selected');
+ selected.setAttribute('aria-selected', true);
+ }
}
- setTimeout(function(){
- let notificationpanel = document.getElementById("user-notifications");
- while (notificationpanel.hasChildNodes()) {
- notificationpanel.removeChild(notificationpanel.firstChild);
- }
- }, 4000);
-
- return false; // Prevents normal POST and page reload in favour of an asynchronous load.
- };
-
- let cancelBtn = $('#comment_' + comment.uuid + ' #commentCancel');
- cancelBtn.click(function(e){
- let editTextarea = document.getElementById(`editarea${comment.uuid}`);
- let editAreaEditable = document.getElementById(`editarea${comment.uuid}editable`);
- let chatMessage = document.getElementById(`chatmessage${comment.uuid}`);
- editForm.style.display = "none";
- editTextarea.innerHTML = '';
- editTextarea.innerHTML = comment.displaycontent;
- if (editAreaEditable) { // Only exists for atto editor, not tinymce.
- editAreaEditable.innerHTML = '';
- editAreaEditable.innerHTML = comment.displaycontent;
+
+ if (modified) {
+ UI.setPen(penSize, penColor);
}
- chatMessage.innerHTML = comment.displaycontent;
- renderMathJax(chatMessage);
- });
+ }
+
+ function handlePenSizeChange(e) {
+ setPen(e.target.value, penColor);
+ document.querySelector('#pdftoolbar button.pen').click(); // Select pen.
+ }
+
+ document.querySelector('.toolbar .pen-size').addEventListener('change', handlePenSizeChange);
+
+ initPen();
+ })(); // End initialize pen.
+ }
+ // Toolbar buttons (defined in index.mustache) are given event listeners:
+ (function () {
+ //Cursor should always be default selected
+ var tooltype = 'cursor';
+ if (tooltype) {
+ setActiveToolbarItem(
+ tooltype,
+ document.querySelector('.toolbar button[data-tooltype=' + tooltype + ']')
+ );
}
- });
- }
-
- /**
- * This function creates an Node-Element for deleting the comment.
- * @param {type} comment The comment-object for which the deletebutton is.
- * @returns {Element|startIndex.indexstartIndex#L#26.indexstartIndex#L#26#L#72.indexstartIndex#L#26#L#72#L#743.createDeleteButton.deleteSpan}
- */
- function createDeleteHandler(comment) {
- var button = $('#comment_'+comment.uuid+' .comment-delete-a');
- button.click(function(e) {
- var confirmDelete = '';
- if(comment.isquestion==1){
- if (_capabilities.deleteany) {
- confirmDelete = M.util.get_string('deletingQuestion_manager', 'pdfannotator');
- } else {
- confirmDelete = M.util.get_string('deletingQuestion_student', 'pdfannotator');
+
+ function setActiveToolbarItem(type, button) {
+ var active = document.querySelector('.toolbar button.active');
+ if (active) {
+ active.classList.remove('active');
+
+ switch (tooltype) {
+ case 'cursor':
+ UI.disableEdit();
+ break;
+ case 'draw':
+ UI.disablePen();
+ break;
+ case 'text':
+ UI.disableText();
+ break;
+ case 'point':
+ UI.disablePoint();
+ break;
+ case 'area':
+ case 'highlight':
+ case 'strikeout':
+ UI.disableRect();
+ break;
+ }
+ }
+
+ if (button) {
+ button.classList.add('active');
+ }
+ if (tooltype !== type) {
+ localStorage.setItem(RENDER_OPTIONS.documentId + '/tooltype', type);
+ }
+ tooltype = type;
+
+ switch (type) {
+ case 'cursor':
+ UI.enableEdit();
+ break;
+ case 'draw':
+ UI.enablePen();
+ break;
+ case 'text':
+ UI.enableText();
+ break;
+ case 'point':
+ UI.enablePoint();
+ break;
+ case 'area':
+ case 'highlight':
+ case 'strikeout':
+ UI.enableRect(type);
+ break;
}
- } else {
- confirmDelete = M.util.get_string('deletingComment', 'pdfannotator');
}
- var deleteCallback = function() {
- dialogCallbackForDelete.call(this, comment);
- };
- notification.confirm(M.util.get_string('deletingCommentTitle', 'pdfannotator'), confirmDelete, M.util.get_string('yesButton', 'pdfannotator'), M.util.get_string('cancelButton', 'pdfannotator'), deleteCallback, null);
- });
- function dialogCallbackForDelete(args = comment){
- if(args.type === "textbox" || args.type === "drawing"){
- _2.default.getStoreAdapter().deleteAnnotation(documentId, args.annotation).then(function(data){
- if(data.status === "success"){
- var node = document.querySelector('[data-pdf-annotate-id="'+args.annotation+'"]');
- var visiblePageNum = node.parentNode.getAttribute('data-pdf-annotate-page');
- node.parentNode.removeChild(node);
- // Not possible to enter new comments.
- document.querySelector('.comment-list-container').innerHTML = '';
- document.querySelector('.comment-list-form').setAttribute('style','display:none');
- UI.renderQuestions(documentId,visiblePageNum);
+ function handleToolbarClick(e) {
+ var target = e.target;
+ //The content of some buttons are img-tags.
+ //Then the nodeName of the clicked target will be IMG, but we need the outer button element
+ if (
+ (target.nodeName === 'IMG' || target.nodeName === 'I') &&
+ target.parentElement.nodeName === 'BUTTON'
+ ) {
+ target = e.target.parentElement;
+ }
+ if (target.nodeName === 'BUTTON') {
+ //Only setActiveToolbarItem if the button is not disabled! (It is disables, if the annotations are hidden)
+ if (!target.disabled) {
+ setActiveToolbarItem(target.getAttribute('data-tooltype'), target);
}
- },function(err){
- notification.addNotification({
- message: M.util.get_string('error:deleteAnnotation', 'pdfannotator'),
- type: "error"
+ }
+ //clear right side (comment-wrapper), if there are comments of an annotation
+ var form = document.querySelector('.comment-list-form');
+ if (form.style.display !== 'none') {
+ form.style.display = 'none';
+ document.querySelector('.comment-list-container').innerHTML = '';
+ }
+ }
+ document.querySelector('.toolbar').addEventListener('click', handleToolbarClick);
+ })(); //end Toolbar buttons
+
+ // Scale
+
+ (function () {
+ function setScaleRotate(scale, rotate) {
+ scale = parseFloat(scale, 10);
+ rotate = parseInt(rotate, 10);
+
+ if (RENDER_OPTIONS.scale !== scale || RENDER_OPTIONS.rotate !== rotate) {
+ RENDER_OPTIONS.scale = scale;
+ RENDER_OPTIONS.rotate = rotate;
+
+ localStorage.setItem(RENDER_OPTIONS.documentId + '/scale', RENDER_OPTIONS.scale);
+ localStorage.setItem(RENDER_OPTIONS.documentId + '/rotate', RENDER_OPTIONS.rotate % 360);
+ _page = parseInt(document.getElementById('currentPage').value);
+
+ let pagecontainer = document.getElementById('pageContainer' + _page);
+ let loader = document.createElement('div');
+ loader.id = 'loader';
+
+ document.body.appendChild(loader);
+ render().then(function () {
+ $('#content-wrapper').scrollTop(
+ document.getElementById('pageContainer' + _page).offsetTop
+ );
+ document.body.removeChild(loader);
});
- console.error(M.util.get_string('error:deleteAnnotation', 'pdfannotator'));
- });
- } else {
- _2.default.getStoreAdapter().deleteComment(RENDER_OPTIONS.documentId, args.uuid).then(function(data) {
- // If comment was answered so that it is not completly deleted but displayed as deleted.
- // If question: Close If answer: Remove marking as correct
- if(data.wasanswered && ((comment.isquestion && !comment.solved) || (!comment.isquestion && comment.solved))){
- _2.default.getStoreAdapter().markSolved(RENDER_OPTIONS.documentId, args);
- }
- });
- }
-
- }
- }
-
- /**
- * This function is called, when an annotation is clicked. The corresponding comments are rendered and a form to submit a comment.
- * @param {type} target
- * @returns {undefined}
- */
- function handleAnnotationClick(target) {
- if (supportsComments(target)) {
- (function () {
- var documentId = target.parentNode.getAttribute('data-pdf-annotate-document');
- var annotationId = target.getAttribute('data-pdf-annotate-id');
-
- _2.default.getStoreAdapter().getComments(documentId, annotationId)
- .then(function (comments) {
- var title;
- if(comments.comments[0].visibility == "protected") {
- title = M.util.get_string('protected_comments','pdfannotator');
- $("#protectedDiv").hide();
- $("#anonymousDiv").hide();
- $("#privateDiv").hide();
- $("#id_pdfannotator_contenteditable").attr("placeholder", M.util.get_string('add_protected_comment', 'pdfannotator'));
- } else if (comments.comments[0].visibility == "private") {
- title = M.util.get_string('private_comments','pdfannotator');
- $("#privateDiv").hide();
- $("#protectedDiv").hide();
- $("#anonymousDiv").hide();
- $("#id_pdfannotator_contenteditable").attr("placeholder", M.util.get_string('add_private_comment', 'pdfannotator'));
- } else {
- title = M.util.get_string('public_comments','pdfannotator');
- $("#privateDiv").hide();
- $("#protectedDiv").hide();
- $("#anonymousDiv").show();
- $("#id_pdfannotator_contenteditable").attr("placeholder", M.util.get_string('addAComment', 'pdfannotator'));
- }
-
- $('#comment-wrapper h4')[0].innerHTML = title;
- commentList.innerHTML = '';
- commentForm.style.display = 'inherit';
-
- var button1 = document.getElementById('allQuestions'); // to be found in index template
- button1.style.display = 'inline';
- var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
- button2.style.display = 'inline';
-
- commentForm.onsubmit = function (e) {
- document.querySelector('#commentSubmit').disabled = true;
- var commentVisibility= read_visibility_of_checkbox();
- var isquestion = 0; // this is a normal comment, so it is not a question
- var textarea = document.getElementById('id_pdfannotator_content');
- var commentContentElements=textarea.value.trim();
- if (commentContentElements.length === 0) {
- //should be more than one character, otherwise it should not be saved.
- notification.addNotification({
- message: M.util.get_string('min0Chars','pdfannotator'),
- type: "error"
- });
- document.querySelector('#commentSubmit').disabled = false;
- return false;
- }
+ }
+ }
- _2.default.getStoreAdapter().addComment(documentId, annotationId, commentContentElements, commentVisibility, isquestion)
- .then(function (response) {
- var fn = (response) => insertComments(response);
- UI.loadEditor('add', 0, fn, response);
- })
- .then(function (success) {
- if (!success) {
- return false;
- }
- document.querySelector('#commentSubmit').disabled = false;
- })
- .catch(function(err){
- notification.addNotification({
- message: M.util.get_string('error:addComment','pdfannotator'),
- type: "error"
- });
- console.error(M.util.get_string('error:addComment', 'pdfannotator'));
- });
+ function handleScaleChange(e) {
+ setScaleRotate(e.target.value, RENDER_OPTIONS.rotate);
+ }
- return false; // Prevents page reload via POST to enable asynchronous loading
- };
-
- var params = {'comments':comments, 'markCommentid':target.markCommentid};
- var fn = (params) => {
- var comments = params.comments;
- var markCommentid = params.markCommentid;
- //render comments
- insertComments(comments, markCommentid);
- }
- UI.loadEditor('add', 0, fn, params);
-
- })
- .catch(function (err){
- commentList.innerHTML = '';
- commentForm.style.display = 'none';
- commentForm.onsubmit = null;
+ function handleRotateCWClick() {
+ setScaleRotate(RENDER_OPTIONS.scale, RENDER_OPTIONS.rotate + 90);
+ }
- insertComments({ content: M.util.get_string('error:getComments', 'pdfannotator')});
-
- notification.addNotification({
- message: M.util.get_string('error:getComments','pdfannotator'),
- type: "error"
- });
- });
- })();
- }else{
- // Drawing or textbox
- (function () {
- var documentId = target.parentNode.getAttribute('data-pdf-annotate-document');
- var annotationId = target.getAttribute('data-pdf-annotate-id');
-
- _2.default.getStoreAdapter().getInformation(documentId, annotationId)
- .then(function (annotation) {
- UI.hideLoader();
- commentList.innerHTML = '';
- commentForm.style.display = 'none';
- commentForm.onsubmit = null;
-
- var button1 = document.getElementById('allQuestions'); // to be found in index template
- button1.style.display = 'inline';
- var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
- button2.style.display = 'inline';
-
- //render comments
- insertComments(annotation);
-
- }).catch(function (err){
- commentList.innerHTML = '';
- commentForm.style.display = 'none';
- commentForm.onsubmit = null;
+ function handleRotateCCWClick() {
+ setScaleRotate(RENDER_OPTIONS.scale, RENDER_OPTIONS.rotate - 90);
+ }
- insertComments({ content: M.util.get_string('error:getComments', 'pdfannotator')});
+ document.querySelector('.toolbar select.scale').value = RENDER_OPTIONS.scale;
- notification.addNotification({
- message: M.util.get_string('error:getComments','pdfannotator'),
- type: "error"
- });
- });
- })();
- }
- }
+ // Add eventHandlers to select and +/- Button for scaling
+ $('.toolbar select.scale').change(handleScaleChange);
- function handleAnnotationBlur(target) {
- if (supportsComments(target)) {
- commentList.innerHTML = '';
- commentForm.style.display = 'none';
- commentForm.onsubmit = null;
- }
- var visiblePageNum = document.getElementById('currentPage').value;
- UI.renderQuestions(documentId,visiblePageNum);
- }
+ let options = document.querySelector('.toolbar select.scale').options.length;
+ document.querySelector('.toolbar #scalePlus').addEventListener('click', function () {
+ handleScaleButton(1);
+ });
+ document.querySelector('.toolbar #scaleMinus').addEventListener('click', function () {
+ handleScaleButton(-1);
+ });
- UI.addEventListener('annotation:click', handleAnnotationClick);
- UI.addEventListener('annotation:blur', handleAnnotationBlur);
- })(window, document); //end comment annotation.
-
-/***/ },
-/* 1 */
-/***/ function(module, exports, __webpack_require__) {
-
- var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
- (function() {
- if (typeof twttr === "undefined" || twttr === null) {
- var twttr = {};
- }
-
- twttr.txt = {};
- twttr.txt.regexen = {};
-
- var HTML_ENTITIES = {
- '&': '&',
- '>': '>',
- '<': '<',
- '"': '"',
- "'": '''
- };
-
- // HTML escaping
- twttr.txt.htmlEscape = function(text) {
- return text && text.replace(/[&"'><]/g, function(character) {
- return HTML_ENTITIES[character];
- });
- };
-
- // Builds a RegExp
- function regexSupplant(regex, flags) {
- flags = flags || "";
- if (typeof regex !== "string") {
- if (regex.global && flags.indexOf("g") < 0) {
- flags += "g";
- }
- if (regex.ignoreCase && flags.indexOf("i") < 0) {
- flags += "i";
- }
- if (regex.multiline && flags.indexOf("m") < 0) {
- flags += "m";
- }
-
- regex = regex.source;
- }
-
- return new RegExp(regex.replace(/#\{(\w+)\}/g, function(match, name) {
- var newRegex = twttr.txt.regexen[name] || "";
- if (typeof newRegex !== "string") {
- newRegex = newRegex.source;
- }
- return newRegex;
- }), flags);
- }
-
- twttr.txt.regexSupplant = regexSupplant;
-
- // simple string interpolation
- function stringSupplant(str, values) {
- return str.replace(/#\{(\w+)\}/g, function(match, name) {
- return values[name] || "";
- });
- }
-
- twttr.txt.stringSupplant = stringSupplant;
-
- twttr.txt.regexen.spaces_group = /\x09-\x0D\x20\x85\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000/;
- twttr.txt.regexen.spaces = regexSupplant(/[#{spaces_group}]/);
- twttr.txt.regexen.invalid_chars_group = /\uFFFE\uFEFF\uFFFF\u202A-\u202E/;
- twttr.txt.regexen.invalid_chars = regexSupplant(/[#{invalid_chars_group}]/);
- twttr.txt.regexen.punct = /\!'#%&'\(\)*\+,\\\-\.\/:;<=>\?@\[\]\^_{|}~\$/;
- twttr.txt.regexen.rtl_chars = /[\u0600-\u06FF]|[\u0750-\u077F]|[\u0590-\u05FF]|[\uFE70-\uFEFF]/mg;
- twttr.txt.regexen.non_bmp_code_pairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/mg;
-
- twttr.txt.regexen.latinAccentChars = /\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u024F\u0253\u0254\u0256\u0257\u0259\u025B\u0263\u0268\u026F\u0272\u0289\u028B\u02BB\u0300-\u036F\u1E00-\u1EFF/;
-
- // Generated from unicode_regex/unicode_regex_groups.scala, same as objective c's \p{L}\p{M}
- twttr.txt.regexen.bmpLetterAndMarks = /A-Za-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u052f\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u065f\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06ef\u06fa-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07ca-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0-\u08b2\u08e4-\u0963\u0971-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09f0\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a70-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0c00-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c81-\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0cf1\u0cf2\u0d01-\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u103f\u1050-\u108f\u109a-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16f1-\u16f8\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u180b-\u180d\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191e\u1920-\u192b\u1930-\u193b\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f\u1aa7\u1ab0-\u1abe\u1b00-\u1b4b\u1b6b-\u1b73\u1b80-\u1baf\u1bba-\u1bf3\u1c00-\u1c37\u1c4d-\u1c4f\u1c5a-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1cf8\u1cf9\u1d00-\u1df5\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u20d0-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2183\u2184\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005\u3006\u302a-\u302f\u3031-\u3035\u303b\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua672\ua674-\ua67d\ua67f-\ua69d\ua69f-\ua6e5\ua6f0\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua7ad\ua7b0\ua7b1\ua7f7-\ua827\ua840-\ua873\ua880-\ua8c4\ua8e0-\ua8f7\ua8fb\ua90a-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf\ua9e0-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa36\uaa40-\uaa4d\uaa60-\uaa76\uaa7a-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab5f\uab64\uab65\uabc0-\uabea\uabec\uabed\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf870-\uf87f\uf882\uf884-\uf89f\uf8b8\uf8c1-\uf8d6\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe2d\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc/;
- twttr.txt.regexen.astralLetterAndMarks = /\ud800[\udc00-\udc0b\udc0d-\udc26\udc28-\udc3a\udc3c\udc3d\udc3f-\udc4d\udc50-\udc5d\udc80-\udcfa\uddfd\ude80-\ude9c\udea0-\uded0\udee0\udf00-\udf1f\udf30-\udf40\udf42-\udf49\udf50-\udf7a\udf80-\udf9d\udfa0-\udfc3\udfc8-\udfcf]|\ud801[\udc00-\udc9d\udd00-\udd27\udd30-\udd63\ude00-\udf36\udf40-\udf55\udf60-\udf67]|\ud802[\udc00-\udc05\udc08\udc0a-\udc35\udc37\udc38\udc3c\udc3f-\udc55\udc60-\udc76\udc80-\udc9e\udd00-\udd15\udd20-\udd39\udd80-\uddb7\uddbe\uddbf\ude00-\ude03\ude05\ude06\ude0c-\ude13\ude15-\ude17\ude19-\ude33\ude38-\ude3a\ude3f\ude60-\ude7c\ude80-\ude9c\udec0-\udec7\udec9-\udee6\udf00-\udf35\udf40-\udf55\udf60-\udf72\udf80-\udf91]|\ud803[\udc00-\udc48]|\ud804[\udc00-\udc46\udc7f-\udcba\udcd0-\udce8\udd00-\udd34\udd50-\udd73\udd76\udd80-\uddc4\uddda\ude00-\ude11\ude13-\ude37\udeb0-\udeea\udf01-\udf03\udf05-\udf0c\udf0f\udf10\udf13-\udf28\udf2a-\udf30\udf32\udf33\udf35-\udf39\udf3c-\udf44\udf47\udf48\udf4b-\udf4d\udf57\udf5d-\udf63\udf66-\udf6c\udf70-\udf74]|\ud805[\udc80-\udcc5\udcc7\udd80-\uddb5\uddb8-\uddc0\ude00-\ude40\ude44\ude80-\udeb7]|\ud806[\udca0-\udcdf\udcff\udec0-\udef8]|\ud808[\udc00-\udf98]|\ud80c[\udc00-\udfff]|\ud80d[\udc00-\udc2e]|\ud81a[\udc00-\ude38\ude40-\ude5e\uded0-\udeed\udef0-\udef4\udf00-\udf36\udf40-\udf43\udf63-\udf77\udf7d-\udf8f]|\ud81b[\udf00-\udf44\udf50-\udf7e\udf8f-\udf9f]|\ud82c[\udc00\udc01]|\ud82f[\udc00-\udc6a\udc70-\udc7c\udc80-\udc88\udc90-\udc99\udc9d\udc9e]|\ud834[\udd65-\udd69\udd6d-\udd72\udd7b-\udd82\udd85-\udd8b\uddaa-\uddad\ude42-\ude44]|\ud835[\udc00-\udc54\udc56-\udc9c\udc9e\udc9f\udca2\udca5\udca6\udca9-\udcac\udcae-\udcb9\udcbb\udcbd-\udcc3\udcc5-\udd05\udd07-\udd0a\udd0d-\udd14\udd16-\udd1c\udd1e-\udd39\udd3b-\udd3e\udd40-\udd44\udd46\udd4a-\udd50\udd52-\udea5\udea8-\udec0\udec2-\udeda\udedc-\udefa\udefc-\udf14\udf16-\udf34\udf36-\udf4e\udf50-\udf6e\udf70-\udf88\udf8a-\udfa8\udfaa-\udfc2\udfc4-\udfcb]|\ud83a[\udc00-\udcc4\udcd0-\udcd6]|\ud83b[\ude00-\ude03\ude05-\ude1f\ude21\ude22\ude24\ude27\ude29-\ude32\ude34-\ude37\ude39\ude3b\ude42\ude47\ude49\ude4b\ude4d-\ude4f\ude51\ude52\ude54\ude57\ude59\ude5b\ude5d\ude5f\ude61\ude62\ude64\ude67-\ude6a\ude6c-\ude72\ude74-\ude77\ude79-\ude7c\ude7e\ude80-\ude89\ude8b-\ude9b\udea1-\udea3\udea5-\udea9\udeab-\udebb]|\ud840[\udc00-\udfff]|\ud841[\udc00-\udfff]|\ud842[\udc00-\udfff]|\ud843[\udc00-\udfff]|\ud844[\udc00-\udfff]|\ud845[\udc00-\udfff]|\ud846[\udc00-\udfff]|\ud847[\udc00-\udfff]|\ud848[\udc00-\udfff]|\ud849[\udc00-\udfff]|\ud84a[\udc00-\udfff]|\ud84b[\udc00-\udfff]|\ud84c[\udc00-\udfff]|\ud84d[\udc00-\udfff]|\ud84e[\udc00-\udfff]|\ud84f[\udc00-\udfff]|\ud850[\udc00-\udfff]|\ud851[\udc00-\udfff]|\ud852[\udc00-\udfff]|\ud853[\udc00-\udfff]|\ud854[\udc00-\udfff]|\ud855[\udc00-\udfff]|\ud856[\udc00-\udfff]|\ud857[\udc00-\udfff]|\ud858[\udc00-\udfff]|\ud859[\udc00-\udfff]|\ud85a[\udc00-\udfff]|\ud85b[\udc00-\udfff]|\ud85c[\udc00-\udfff]|\ud85d[\udc00-\udfff]|\ud85e[\udc00-\udfff]|\ud85f[\udc00-\udfff]|\ud860[\udc00-\udfff]|\ud861[\udc00-\udfff]|\ud862[\udc00-\udfff]|\ud863[\udc00-\udfff]|\ud864[\udc00-\udfff]|\ud865[\udc00-\udfff]|\ud866[\udc00-\udfff]|\ud867[\udc00-\udfff]|\ud868[\udc00-\udfff]|\ud869[\udc00-\uded6\udf00-\udfff]|\ud86a[\udc00-\udfff]|\ud86b[\udc00-\udfff]|\ud86c[\udc00-\udfff]|\ud86d[\udc00-\udf34\udf40-\udfff]|\ud86e[\udc00-\udc1d]|\ud87e[\udc00-\ude1d]|\udb40[\udd00-\uddef]/;
-
- // Generated from unicode_regex/unicode_regex_groups.scala, same as objective c's \p{Nd}
- twttr.txt.regexen.bmpNumerals = /0-9\u0660-\u0669\u06f0-\u06f9\u07c0-\u07c9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0de6-\u0def\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u1090-\u1099\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\u1a80-\u1a89\u1a90-\u1a99\u1b50-\u1b59\u1bb0-\u1bb9\u1c40-\u1c49\u1c50-\u1c59\ua620-\ua629\ua8d0-\ua8d9\ua900-\ua909\ua9d0-\ua9d9\ua9f0-\ua9f9\uaa50-\uaa59\uabf0-\uabf9\uff10-\uff19/;
- twttr.txt.regexen.astralNumerals = /\ud801[\udca0-\udca9]|\ud804[\udc66-\udc6f\udcf0-\udcf9\udd36-\udd3f\uddd0-\uddd9\udef0-\udef9]|\ud805[\udcd0-\udcd9\ude50-\ude59\udec0-\udec9]|\ud806[\udce0-\udce9]|\ud81a[\ude60-\ude69\udf50-\udf59]|\ud835[\udfce-\udfff]/;
-
- twttr.txt.regexen.hashtagSpecialChars = /_\u200c\u200d\ua67e\u05be\u05f3\u05f4\uff5e\u301c\u309b\u309c\u30a0\u30fb\u3003\u0f0b\u0f0c\xb7/;
-
- // A hashtag must contain at least one unicode letter or mark, as well as numbers, underscores, and select special characters.
- twttr.txt.regexen.hashSigns = /[##]/;
- twttr.txt.regexen.hashtagAlpha = regexSupplant(/(?:[#{bmpLetterAndMarks}]|(?=#{non_bmp_code_pairs})(?:#{astralLetterAndMarks}))/);
- twttr.txt.regexen.hashtagAlphaNumeric = regexSupplant(/(?:[#{bmpLetterAndMarks}#{bmpNumerals}#{hashtagSpecialChars}]|(?=#{non_bmp_code_pairs})(?:#{astralLetterAndMarks}|#{astralNumerals}))/);
- twttr.txt.regexen.endHashtagMatch = regexSupplant(/^(?:#{hashSigns}|:\/\/)/);
- twttr.txt.regexen.codePoint = /(?:[^\uD800-\uDFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF])/;
- twttr.txt.regexen.hashtagBoundary = regexSupplant(/(?:^|$|(?!#{hashtagAlphaNumeric}|&)#{codePoint})/);
- twttr.txt.regexen.validHashtag = regexSupplant(/(#{hashtagBoundary})(#{hashSigns})(?!\uFE0F|\u20E3)(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi);
-
- // Mention related regex collection
- twttr.txt.regexen.validMentionPrecedingChars = /(?:^|[^a-zA-Z0-9_!#$%&*@@]|(?:^|[^a-zA-Z0-9_+~.-])(?:rt|RT|rT|Rt):?)/;
- twttr.txt.regexen.atSigns = /[@@]/;
- twttr.txt.regexen.validMentionOrList = regexSupplant(
- '(#{validMentionPrecedingChars})' + // $1: Preceding character
- '(#{atSigns})' + // $2: At mark
- '([a-zA-Z0-9_]{1,20})' + // $3: Screen name
- '(\/[a-zA-Z][a-zA-Z0-9_\-]{0,24})?' // $4: List (optional)
- , 'g');
- twttr.txt.regexen.validReply = regexSupplant(/^(?:#{spaces})*#{atSigns}([a-zA-Z0-9_]{1,20})/);
- twttr.txt.regexen.endMentionMatch = regexSupplant(/^(?:#{atSigns}|[#{latinAccentChars}]|:\/\/)/);
-
- // URL related regex collection
- twttr.txt.regexen.validUrlPrecedingChars = regexSupplant(/(?:[^A-Za-z0-9@@$###{invalid_chars_group}]|^)/);
- twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars = /[-_.\/]$/;
- twttr.txt.regexen.invalidDomainChars = stringSupplant("#{punct}#{spaces_group}#{invalid_chars_group}", twttr.txt.regexen);
- twttr.txt.regexen.validDomainChars = regexSupplant(/[^#{invalidDomainChars}]/);
- twttr.txt.regexen.validSubdomain = regexSupplant(/(?:(?:#{validDomainChars}(?:[_-]|#{validDomainChars})*)?#{validDomainChars}\.)/);
- twttr.txt.regexen.validDomainName = regexSupplant(/(?:(?:#{validDomainChars}(?:-|#{validDomainChars})*)?#{validDomainChars}\.)/);
- twttr.txt.regexen.validGTLD = regexSupplant(RegExp(
- '(?:(?:' +
- '삼성|닷컴|닷넷|香格里拉|餐厅|食品|飞利浦|電訊盈科|集团|购物|谷歌|诺基亚|联通|网络|网站|网店|网址|组织机构|移动|珠宝|点看|游戏|淡马锡|机构|書籍|时尚|新闻|政府|政务|' +
- '手表|手机|我爱你|慈善|微博|广东|工行|家電|娱乐|大拿|在线|嘉里大酒店|嘉里|商标|商店|商城|公益|公司|八卦|健康|信息|佛山|企业|中文网|中信|世界|ポイント|ファッション|' +
- 'セール|ストア|コム|グーグル|クラウド|みんな|คอม|संगठन|नेट|कॉम|همراه|موقع|موبايلي|كوم|شبكة|بيتك|بازار|العليان|' +
- 'ارامكو|ابوظبي|קום|сайт|рус|орг|онлайн|москва|ком|дети|zuerich|zone|zippo|zip|zero|zara|zappos|' +
- 'yun|youtube|you|yokohama|yoga|yodobashi|yandex|yamaxun|yahoo|yachts|xyz|xxx|xperia|xin|xihuan|' +
- 'xfinity|xerox|xbox|wtf|wtc|world|works|work|woodside|wolterskluwer|wme|wine|windows|win|' +
- 'williamhill|wiki|wien|whoswho|weir|weibo|wedding|wed|website|weber|webcam|weatherchannel|' +
- 'weather|watches|watch|warman|wanggou|wang|walter|wales|vuelos|voyage|voto|voting|vote|' +
- 'volkswagen|vodka|vlaanderen|viva|vistaprint|vista|vision|virgin|vip|vin|villas|viking|vig|video|' +
- 'viajes|vet|versicherung|vermögensberatung|vermögensberater|verisign|ventures|vegas|vana|' +
- 'vacations|ups|uol|uno|university|unicom|ubs|tvs|tushu|tunes|tui|tube|trv|trust|' +
- 'travelersinsurance|travelers|travelchannel|travel|training|trading|trade|toys|toyota|town|tours|' +
- 'total|toshiba|toray|top|tools|tokyo|today|tmall|tirol|tires|tips|tiffany|tienda|tickets|theatre|' +
- 'theater|thd|teva|tennis|temasek|telefonica|telecity|tel|technology|tech|team|tdk|tci|taxi|tax|' +
- 'tattoo|tatar|tatamotors|taobao|talk|taipei|tab|systems|symantec|sydney|swiss|swatch|suzuki|' +
- 'surgery|surf|support|supply|supplies|sucks|style|study|studio|stream|store|storage|stockholm|' +
- 'stcgroup|stc|statoil|statefarm|statebank|starhub|star|stada|srl|spreadbetting|spot|spiegel|' +
- 'space|soy|sony|song|solutions|solar|sohu|software|softbank|social|soccer|sncf|smile|skype|sky|' +
- 'skin|ski|site|singles|sina|silk|shriram|show|shouji|shopping|shop|shoes|shiksha|shia|shell|shaw|' +
- 'sharp|shangrila|sfr|sexy|sex|sew|seven|services|sener|select|seek|security|seat|scot|scor|' +
- 'science|schwarz|schule|school|scholarships|schmidt|schaeffler|scb|sca|sbs|sbi|saxo|save|sas|' +
- 'sarl|sapo|sap|sanofi|sandvikcoromant|sandvik|samsung|salon|sale|sakura|safety|safe|saarland|' +
- 'ryukyu|rwe|run|ruhr|rsvp|room|rodeo|rocks|rocher|rip|rio|ricoh|richardli|rich|rexroth|reviews|' +
- 'review|restaurant|rest|republican|report|repair|rentals|rent|ren|reit|reisen|reise|rehab|' +
- 'redumbrella|redstone|red|recipes|realty|realtor|realestate|read|racing|quest|quebec|qpon|pwc|' +
- 'pub|protection|property|properties|promo|progressive|prof|productions|prod|pro|prime|press|' +
- 'praxi|post|porn|politie|poker|pohl|pnc|plus|plumbing|playstation|play|place|pizza|pioneer|pink|' +
- 'ping|pin|pid|pictures|pictet|pics|piaget|physio|photos|photography|photo|philips|pharmacy|pet|' +
- 'pccw|passagens|party|parts|partners|pars|paris|panerai|pamperedchef|page|ovh|ott|otsuka|osaka|' +
- 'origins|orientexpress|organic|org|orange|oracle|ooo|online|onl|ong|one|omega|ollo|olayangroup|' +
- 'olayan|okinawa|office|obi|nyc|ntt|nrw|nra|nowtv|nowruz|now|norton|northwesternmutual|nokia|' +
- 'nissay|nissan|ninja|nikon|nico|nhk|ngo|nfl|nexus|nextdirect|next|news|new|neustar|network|' +
- 'netflix|netbank|net|nec|navy|natura|name|nagoya|nadex|mutuelle|mutual|museum|mtr|mtpc|mtn|' +
- 'movistar|movie|mov|motorcycles|moscow|mortgage|mormon|montblanc|money|monash|mom|moi|moe|moda|' +
- 'mobily|mobi|mma|mls|mlb|mitsubishi|mit|mini|mil|microsoft|miami|metlife|meo|menu|men|memorial|' +
- 'meme|melbourne|meet|media|med|mba|mattel|marriott|markets|marketing|market|mango|management|man|' +
- 'makeup|maison|maif|madrid|luxury|luxe|lupin|ltda|ltd|love|lotto|lotte|london|lol|locus|locker|' +
- 'loans|loan|lixil|living|live|lipsy|link|linde|lincoln|limo|limited|like|lighting|lifestyle|' +
- 'lifeinsurance|life|lidl|liaison|lgbt|lexus|lego|legal|leclerc|lease|lds|lawyer|law|latrobe|lat|' +
- 'lasalle|lanxess|landrover|land|lancaster|lamer|lamborghini|lacaixa|kyoto|kuokgroup|kred|krd|kpn|' +
- 'kpmg|kosher|komatsu|koeln|kiwi|kitchen|kindle|kinder|kim|kia|kfh|kerryproperties|kerrylogistics|' +
- 'kerryhotels|kddi|kaufen|juegos|jprs|jpmorgan|joy|jot|joburg|jobs|jnj|jmp|jll|jlc|jewelry|jetzt|' +
- 'jcp|jcb|java|jaguar|iwc|itv|itau|istanbul|ist|ismaili|iselect|irish|ipiranga|investments|' +
- 'international|int|insure|insurance|institute|ink|ing|info|infiniti|industries|immobilien|immo|' +
- 'imdb|imamat|ikano|iinet|ifm|icu|ice|icbc|ibm|hyundai|htc|hsbc|how|house|hotmail|hoteles|hosting|' +
- 'host|horse|honda|homes|homedepot|holiday|holdings|hockey|hkt|hiv|hitachi|hisamitsu|hiphop|hgtv|' +
- 'hermes|here|helsinki|help|healthcare|health|hdfcbank|haus|hangout|hamburg|guru|guitars|guide|' +
- 'guge|gucci|guardian|group|gripe|green|gratis|graphics|grainger|gov|got|gop|google|goog|goodyear|' +
- 'goo|golf|goldpoint|gold|godaddy|gmx|gmo|gmbh|gmail|globo|global|gle|glass|giving|gives|gifts|' +
- 'gift|ggee|genting|gent|gea|gdn|gbiz|garden|games|game|gallup|gallo|gallery|gal|fyi|futbol|' +
- 'furniture|fund|fujitsu|ftr|frontier|frontdoor|frogans|frl|fresenius|fox|foundation|forum|' +
- 'forsale|forex|ford|football|foodnetwork|foo|fly|flsmidth|flowers|florist|flir|flights|flickr|' +
- 'fitness|fit|fishing|fish|firmdale|firestone|fire|financial|finance|final|film|ferrero|feedback|' +
- 'fedex|fast|fashion|farmers|farm|fans|fan|family|faith|fairwinds|fail|fage|extraspace|express|' +
- 'exposed|expert|exchange|everbank|events|eus|eurovision|estate|esq|erni|ericsson|equipment|epson|' +
- 'epost|enterprises|engineering|engineer|energy|emerck|email|education|edu|edeka|eat|earth|dvag|' +
- 'durban|dupont|dunlop|dubai|dtv|drive|download|dot|doosan|domains|doha|dog|docs|dnp|discount|' +
- 'directory|direct|digital|diet|diamonds|dhl|dev|design|desi|dentist|dental|democrat|delta|' +
- 'deloitte|dell|delivery|degree|deals|dealer|deal|dds|dclk|day|datsun|dating|date|dance|dad|dabur|' +
- 'cyou|cymru|cuisinella|csc|cruises|crs|crown|cricket|creditunion|creditcard|credit|courses|' +
- 'coupons|coupon|country|corsica|coop|cool|cookingchannel|cooking|contractors|contact|consulting|' +
- 'construction|condos|comsec|computer|compare|company|community|commbank|comcast|com|cologne|' +
- 'college|coffee|codes|coach|clubmed|club|cloud|clothing|clinique|clinic|click|cleaning|claims|' +
- 'cityeats|city|citic|cisco|circle|cipriani|church|chrome|christmas|chloe|chintai|cheap|chat|' +
- 'chase|channel|chanel|cfd|cfa|cern|ceo|center|ceb|cbre|cbn|cba|catering|cat|casino|cash|casa|' +
- 'cartier|cars|careers|career|care|cards|caravan|car|capital|capetown|canon|cancerresearch|camp|' +
- 'camera|cam|call|cal|cafe|cab|bzh|buzz|buy|business|builders|build|bugatti|budapest|brussels|' +
- 'brother|broker|broadway|bridgestone|bradesco|boutique|bot|bostik|bosch|boots|book|boo|bond|bom|' +
- 'boehringer|boats|bnpparibas|bnl|bmw|bms|blue|bloomberg|blog|blanco|blackfriday|black|biz|bio|' +
- 'bingo|bing|bike|bid|bible|bharti|bet|best|berlin|bentley|beer|beats|bcn|bcg|bbva|bbc|bayern|' +
- 'bauhaus|bargains|barefoot|barclays|barclaycard|barcelona|bar|bank|band|baidu|baby|azure|axa|aws|' +
- 'avianca|autos|auto|author|audio|audible|audi|auction|attorney|associates|asia|arte|art|arpa|' +
- 'army|archi|aramco|aquarelle|apple|app|apartments|anz|anquan|android|analytics|amsterdam|amica|' +
- 'alstom|alsace|ally|allfinanz|alipay|alibaba|akdn|airtel|airforce|airbus|aig|agency|agakhan|afl|' +
- 'aetna|aero|aeg|adult|ads|adac|actor|active|aco|accountants|accountant|accenture|academy|' +
- 'abudhabi|abogado|able|abbvie|abbott|abb|aarp|aaa|onion' +
- ')(?=[^0-9a-zA-Z@]|$))'));
- twttr.txt.regexen.validCCTLD = regexSupplant(RegExp(
- '(?:(?:' +
- '한국|香港|澳門|新加坡|台灣|台湾|中國|中国|გე|ไทย|ලංකා|ഭാരതം|ಭಾರತ|భారత్|சிங்கப்பூர்|இலங்கை|இந்தியா|ଭାରତ|ભારત|ਭਾਰਤ|' +
- 'ভাৰত|ভারত|বাংলা|भारत|پاکستان|مليسيا|مصر|قطر|فلسطين|عمان|عراق|سورية|سودان|تونس|بھارت|ایران|' +
- 'امارات|المغرب|السعودية|الجزائر|الاردن|հայ|қаз|укр|срб|рф|мон|мкд|ею|бел|бг|ελ|zw|zm|za|yt|ye|ws|' +
- 'wf|vu|vn|vi|vg|ve|vc|va|uz|uy|us|um|uk|ug|ua|tz|tw|tv|tt|tr|tp|to|tn|tm|tl|tk|tj|th|tg|tf|td|tc|' +
- 'sz|sy|sx|sv|su|st|ss|sr|so|sn|sm|sl|sk|sj|si|sh|sg|se|sd|sc|sb|sa|rw|ru|rs|ro|re|qa|py|pw|pt|ps|' +
- 'pr|pn|pm|pl|pk|ph|pg|pf|pe|pa|om|nz|nu|nr|np|no|nl|ni|ng|nf|ne|nc|na|mz|my|mx|mw|mv|mu|mt|ms|mr|' +
- 'mq|mp|mo|mn|mm|ml|mk|mh|mg|mf|me|md|mc|ma|ly|lv|lu|lt|ls|lr|lk|li|lc|lb|la|kz|ky|kw|kr|kp|kn|km|' +
- 'ki|kh|kg|ke|jp|jo|jm|je|it|is|ir|iq|io|in|im|il|ie|id|hu|ht|hr|hn|hm|hk|gy|gw|gu|gt|gs|gr|gq|gp|' +
- 'gn|gm|gl|gi|gh|gg|gf|ge|gd|gb|ga|fr|fo|fm|fk|fj|fi|eu|et|es|er|eh|eg|ee|ec|dz|do|dm|dk|dj|de|cz|' +
- 'cy|cx|cw|cv|cu|cr|co|cn|cm|cl|ck|ci|ch|cg|cf|cd|cc|ca|bz|by|bw|bv|bt|bs|br|bq|bo|bn|bm|bl|bj|bi|' +
- 'bh|bg|bf|be|bd|bb|ba|az|ax|aw|au|at|as|ar|aq|ao|an|am|al|ai|ag|af|ae|ad|ac' +
- ')(?=[^0-9a-zA-Z@]|$))'));
- twttr.txt.regexen.validPunycode = /(?:xn--[0-9a-z]+)/;
- twttr.txt.regexen.validSpecialCCTLD = /(?:(?:co|tv)(?=[^0-9a-zA-Z@]|$))/;
- twttr.txt.regexen.validDomain = regexSupplant(/(?:#{validSubdomain}*#{validDomainName}(?:#{validGTLD}|#{validCCTLD}|#{validPunycode}))/);
- twttr.txt.regexen.validAsciiDomain = regexSupplant(/(?:(?:[\-a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/gi);
- twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/i);
- twttr.txt.regexen.validSpecialShortDomain = regexSupplant(/^#{validDomainName}#{validSpecialCCTLD}$/i);
- twttr.txt.regexen.validPortNumber = /[0-9]+/;
- twttr.txt.regexen.cyrillicLettersAndMarks = /\u0400-\u04FF/;
- twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(/[a-z#{cyrillicLettersAndMarks}0-9!\*';:=\+,\.\$\/%#\[\]\-_~@\|{latinAccentChars}]/i);
- // Allow URL paths to contain up to two nested levels of balanced parens
- // 1. Used in Wikipedia URLs like /Primer_(film)
- // 2. Used in IIS sessions like /S(dfd346)/
- // 3. Used in Rdio URLs like /track/We_Up_(Album_Version_(Edited))/
- twttr.txt.regexen.validUrlBalancedParens = regexSupplant(
- '\\(' +
- '(?:' +
- '#{validGeneralUrlPathChars}+' +
- '|' +
- // allow one nested level of balanced parentheses
- '(?:' +
- '#{validGeneralUrlPathChars}*' +
- '\\(' +
- '#{validGeneralUrlPathChars}+' +
- '\\)' +
- '#{validGeneralUrlPathChars}*' +
- ')' +
- ')' +
- '\\)'
- , 'i');
- // Valid end-of-path chracters (so /foo. does not gobble the period).
- // 1. Allow = for empty URL parameters and other URL-join artifacts
- twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(/[\+\-a-z#{cyrillicLettersAndMarks}0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i);
- // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/
- twttr.txt.regexen.validUrlPath = regexSupplant('(?:' +
- '(?:' +
- '#{validGeneralUrlPathChars}*' +
- '(?:#{validUrlBalancedParens}#{validGeneralUrlPathChars}*)*' +
- '#{validUrlPathEndingChars}'+
- ')|(?:@#{validGeneralUrlPathChars}+\/)'+
- ')', 'i');
-
- twttr.txt.regexen.validUrlQueryChars = /[a-z0-9!?\*'@\(\);:&=\+\$\/%#\[\]\-_\.,~|]/i;
- twttr.txt.regexen.validUrlQueryEndingChars = /[a-z0-9_&=#\/]/i;
- twttr.txt.regexen.extractUrl = regexSupplant(
- '(' + // $1 total match
- '(#{validUrlPrecedingChars})' + // $2 Preceeding chracter
- '(' + // $3 URL
- '(https?:\\/\\/)?' + // $4 Protocol (optional)
- '(#{validDomain})' + // $5 Domain(s)
- '(?::(#{validPortNumber}))?' + // $6 Port number (optional)
- '(\\/#{validUrlPath}*)?' + // $7 URL Path
- '(\\?#{validUrlQueryChars}*#{validUrlQueryEndingChars})?' + // $8 Query String
- ')' +
- ')'
- , 'gi');
-
- twttr.txt.regexen.validTcoUrl = /^https?:\/\/t\.co\/[a-z0-9]+/i;
- twttr.txt.regexen.urlHasProtocol = /^https?:\/\//i;
- twttr.txt.regexen.urlHasHttps = /^https:\/\//i;
-
- // cashtag related regex
- twttr.txt.regexen.cashtag = /[a-z]{1,6}(?:[._][a-z]{1,2})?/i;
- twttr.txt.regexen.validCashtag = regexSupplant('(^|#{spaces})(\\$)(#{cashtag})(?=$|\\s|[#{punct}])', 'gi');
-
- // These URL validation pattern strings are based on the ABNF from RFC 3986
- twttr.txt.regexen.validateUrlUnreserved = /[a-z\u0400-\u04FF0-9\-._~]/i;
- twttr.txt.regexen.validateUrlPctEncoded = /(?:%[0-9a-f]{2})/i;
- twttr.txt.regexen.validateUrlSubDelims = /[!$&'()*+,;=]/i;
- twttr.txt.regexen.validateUrlPchar = regexSupplant('(?:' +
- '#{validateUrlUnreserved}|' +
- '#{validateUrlPctEncoded}|' +
- '#{validateUrlSubDelims}|' +
- '[:|@]' +
- ')', 'i');
-
- twttr.txt.regexen.validateUrlScheme = /(?:[a-z][a-z0-9+\-.]*)/i;
- twttr.txt.regexen.validateUrlUserinfo = regexSupplant('(?:' +
- '#{validateUrlUnreserved}|' +
- '#{validateUrlPctEncoded}|' +
- '#{validateUrlSubDelims}|' +
- ':' +
- ')*', 'i');
-
- twttr.txt.regexen.validateUrlDecOctet = /(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9]{2})|(?:2[0-4][0-9])|(?:25[0-5]))/i;
- twttr.txt.regexen.validateUrlIpv4 = regexSupplant(/(?:#{validateUrlDecOctet}(?:\.#{validateUrlDecOctet}){3})/i);
-
- // Punting on real IPv6 validation for now
- twttr.txt.regexen.validateUrlIpv6 = /(?:\[[a-f0-9:\.]+\])/i;
-
- // Also punting on IPvFuture for now
- twttr.txt.regexen.validateUrlIp = regexSupplant('(?:' +
- '#{validateUrlIpv4}|' +
- '#{validateUrlIpv6}' +
- ')', 'i');
-
- // This is more strict than the rfc specifies
- twttr.txt.regexen.validateUrlSubDomainSegment = /(?:[a-z0-9](?:[a-z0-9_\-]*[a-z0-9])?)/i;
- twttr.txt.regexen.validateUrlDomainSegment = /(?:[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?)/i;
- twttr.txt.regexen.validateUrlDomainTld = /(?:[a-z](?:[a-z0-9\-]*[a-z0-9])?)/i;
- twttr.txt.regexen.validateUrlDomain = regexSupplant(/(?:(?:#{validateUrlSubDomainSegment]}\.)*(?:#{validateUrlDomainSegment]}\.)#{validateUrlDomainTld})/i);
-
- twttr.txt.regexen.validateUrlHost = regexSupplant('(?:' +
- '#{validateUrlIp}|' +
- '#{validateUrlDomain}' +
- ')', 'i');
-
- // Unencoded internationalized domains - this doesn't check for invalid UTF-8 sequences
- twttr.txt.regexen.validateUrlUnicodeSubDomainSegment = /(?:(?:[a-z0-9]|[^\u0000-\u007f])(?:(?:[a-z0-9_\-]|[^\u0000-\u007f])*(?:[a-z0-9]|[^\u0000-\u007f]))?)/i;
- twttr.txt.regexen.validateUrlUnicodeDomainSegment = /(?:(?:[a-z0-9]|[^\u0000-\u007f])(?:(?:[a-z0-9\-]|[^\u0000-\u007f])*(?:[a-z0-9]|[^\u0000-\u007f]))?)/i;
- twttr.txt.regexen.validateUrlUnicodeDomainTld = /(?:(?:[a-z]|[^\u0000-\u007f])(?:(?:[a-z0-9\-]|[^\u0000-\u007f])*(?:[a-z0-9]|[^\u0000-\u007f]))?)/i;
- twttr.txt.regexen.validateUrlUnicodeDomain = regexSupplant(/(?:(?:#{validateUrlUnicodeSubDomainSegment}\.)*(?:#{validateUrlUnicodeDomainSegment}\.)#{validateUrlUnicodeDomainTld})/i);
-
- twttr.txt.regexen.validateUrlUnicodeHost = regexSupplant('(?:' +
- '#{validateUrlIp}|' +
- '#{validateUrlUnicodeDomain}' +
- ')', 'i');
-
- twttr.txt.regexen.validateUrlPort = /[0-9]{1,5}/;
-
- twttr.txt.regexen.validateUrlUnicodeAuthority = regexSupplant(
- '(?:(#{validateUrlUserinfo})@)?' + // $1 userinfo
- '(#{validateUrlUnicodeHost})' + // $2 host
- '(?::(#{validateUrlPort}))?' //$3 port
- , "i");
-
- twttr.txt.regexen.validateUrlAuthority = regexSupplant(
- '(?:(#{validateUrlUserinfo})@)?' + // $1 userinfo
- '(#{validateUrlHost})' + // $2 host
- '(?::(#{validateUrlPort}))?' // $3 port
- , "i");
-
- twttr.txt.regexen.validateUrlPath = regexSupplant(/(\/#{validateUrlPchar}*)*/i);
- twttr.txt.regexen.validateUrlQuery = regexSupplant(/(#{validateUrlPchar}|\/|\?)*/i);
- twttr.txt.regexen.validateUrlFragment = regexSupplant(/(#{validateUrlPchar}|\/|\?)*/i);
-
- // Modified version of RFC 3986 Appendix B
- twttr.txt.regexen.validateUrlUnencoded = regexSupplant(
- '^' + // Full URL
- '(?:' +
- '([^:/?#]+):\\/\\/' + // $1 Scheme
- ')?' +
- '([^/?#]*)' + // $2 Authority
- '([^?#]*)' + // $3 Path
- '(?:' +
- '\\?([^#]*)' + // $4 Query
- ')?' +
- '(?:' +
- '#(.*)' + // $5 Fragment
- ')?$'
- , "i");
-
-
- // Default CSS class for auto-linked lists (along with the url class)
- var DEFAULT_LIST_CLASS = "tweet-url list-slug";
- // Default CSS class for auto-linked usernames (along with the url class)
- var DEFAULT_USERNAME_CLASS = "tweet-url username";
- // Default CSS class for auto-linked hashtags (along with the url class)
- var DEFAULT_HASHTAG_CLASS = "tweet-url hashtag";
- // Default CSS class for auto-linked cashtags (along with the url class)
- var DEFAULT_CASHTAG_CLASS = "tweet-url cashtag";
- // Options which should not be passed as HTML attributes
- var OPTIONS_NOT_ATTRIBUTES = {'urlClass':true, 'listClass':true, 'usernameClass':true, 'hashtagClass':true, 'cashtagClass':true,
- 'usernameUrlBase':true, 'listUrlBase':true, 'hashtagUrlBase':true, 'cashtagUrlBase':true,
- 'usernameUrlBlock':true, 'listUrlBlock':true, 'hashtagUrlBlock':true, 'linkUrlBlock':true,
- 'usernameIncludeSymbol':true, 'suppressLists':true, 'suppressNoFollow':true, 'targetBlank':true,
- 'suppressDataScreenName':true, 'urlEntities':true, 'symbolTag':true, 'textWithSymbolTag':true, 'urlTarget':true,
- 'invisibleTagAttrs':true, 'linkAttributeBlock':true, 'linkTextBlock': true, 'htmlEscapeNonEntities': true
- };
-
- var BOOLEAN_ATTRIBUTES = {'disabled':true, 'readonly':true, 'multiple':true, 'checked':true};
-
- // Simple object cloning function for simple objects
- function clone(o) {
- var r = {};
- for (var k in o) {
- if (o.hasOwnProperty(k)) {
- r[k] = o[k];
- }
- }
-
- return r;
- }
-
- twttr.txt.tagAttrs = function(attributes) {
- var htmlAttrs = "";
- for (var k in attributes) {
- var v = attributes[k];
- if (BOOLEAN_ATTRIBUTES[k]) {
- v = v ? k : null;
- }
- if (v == null) continue;
- htmlAttrs += " " + twttr.txt.htmlEscape(k) + "=\"" + twttr.txt.htmlEscape(v.toString()) + "\"";
- }
- return htmlAttrs;
- };
-
- twttr.txt.linkToText = function(entity, text, attributes, options) {
- if (!options.suppressNoFollow) {
- attributes.rel = "nofollow";
- }
- // if linkAttributeBlock is specified, call it to modify the attributes
- if (options.linkAttributeBlock) {
- options.linkAttributeBlock(entity, attributes);
- }
- // if linkTextBlock is specified, call it to get a new/modified link text
- if (options.linkTextBlock) {
- text = options.linkTextBlock(entity, text);
- }
- var d = {
- text: text,
- attr: twttr.txt.tagAttrs(attributes)
- };
- return stringSupplant("
#{text}", d);
- };
-
- twttr.txt.linkToTextWithSymbol = function(entity, symbol, text, attributes, options) {
- var taggedSymbol = options.symbolTag ? "<" + options.symbolTag + ">" + symbol + ""+ options.symbolTag + ">" : symbol;
- text = twttr.txt.htmlEscape(text);
- var taggedText = options.textWithSymbolTag ? "<" + options.textWithSymbolTag + ">" + text + ""+ options.textWithSymbolTag + ">" : text;
-
- if (options.usernameIncludeSymbol || !symbol.match(twttr.txt.regexen.atSigns)) {
- return twttr.txt.linkToText(entity, taggedSymbol + taggedText, attributes, options);
- } else {
- return taggedSymbol + twttr.txt.linkToText(entity, taggedText, attributes, options);
- }
- };
-
- twttr.txt.linkToHashtag = function(entity, text, options) {
- var hash = text.substring(entity.indices[0], entity.indices[0] + 1);
- var hashtag = twttr.txt.htmlEscape(entity.hashtag);
- var attrs = clone(options.htmlAttrs || {});
- attrs.href = options.hashtagUrlBase + hashtag;
- attrs.title = "#" + hashtag;
- attrs["class"] = options.hashtagClass;
- if (hashtag.charAt(0).match(twttr.txt.regexen.rtl_chars)){
- attrs["class"] += " rtl";
- }
- if (options.targetBlank) {
- attrs.target = '_blank';
- }
-
- return twttr.txt.linkToTextWithSymbol(entity, hash, hashtag, attrs, options);
- };
-
- twttr.txt.linkToCashtag = function(entity, text, options) {
- var cashtag = twttr.txt.htmlEscape(entity.cashtag);
- var attrs = clone(options.htmlAttrs || {});
- attrs.href = options.cashtagUrlBase + cashtag;
- attrs.title = "$" + cashtag;
- attrs["class"] = options.cashtagClass;
- if (options.targetBlank) {
- attrs.target = '_blank';
- }
-
- return twttr.txt.linkToTextWithSymbol(entity, "$", cashtag, attrs, options);
- };
-
- twttr.txt.linkToMentionAndList = function(entity, text, options) {
- var at = text.substring(entity.indices[0], entity.indices[0] + 1);
- var user = twttr.txt.htmlEscape(entity.screenName);
- var slashListname = twttr.txt.htmlEscape(entity.listSlug);
- var isList = entity.listSlug && !options.suppressLists;
- var attrs = clone(options.htmlAttrs || {});
- attrs["class"] = (isList ? options.listClass : options.usernameClass);
- attrs.href = isList ? options.listUrlBase + user + slashListname : options.usernameUrlBase + user;
- if (!isList && !options.suppressDataScreenName) {
- attrs['data-screen-name'] = user;
- }
- if (options.targetBlank) {
- attrs.target = '_blank';
- }
-
- return twttr.txt.linkToTextWithSymbol(entity, at, isList ? user + slashListname : user, attrs, options);
- };
-
- twttr.txt.linkToUrl = function(entity, text, options) {
- var url = entity.url;
- var displayUrl = url;
- var linkText = twttr.txt.htmlEscape(displayUrl);
-
- // If the caller passed a urlEntities object (provided by a Twitter API
- // response with include_entities=true), we use that to render the display_url
- // for each URL instead of it's underlying t.co URL.
- var urlEntity = (options.urlEntities && options.urlEntities[url]) || entity;
- if (urlEntity.display_url) {
- linkText = twttr.txt.linkTextWithEntity(urlEntity, options);
- }
-
- var attrs = clone(options.htmlAttrs || {});
-
- if (!url.match(twttr.txt.regexen.urlHasProtocol)) {
- url = "http://" + url;
- }
- attrs.href = url;
-
- if (options.targetBlank) {
- attrs.target = '_blank';
- }
-
- // set class only if urlClass is specified.
- if (options.urlClass) {
- attrs["class"] = options.urlClass;
- }
-
- // set target only if urlTarget is specified.
- if (options.urlTarget) {
- attrs.target = options.urlTarget;
- }
-
- if (!options.title && urlEntity.display_url) {
- attrs.title = urlEntity.expanded_url;
- }
-
- return twttr.txt.linkToText(entity, linkText, attrs, options);
- };
-
- twttr.txt.linkTextWithEntity = function (entity, options) {
- var displayUrl = entity.display_url;
- var expandedUrl = entity.expanded_url;
-
- // Goal: If a user copies and pastes a tweet containing t.co'ed link, the resulting paste
- // should contain the full original URL (expanded_url), not the display URL.
- //
- // Method: Whenever possible, we actually emit HTML that contains expanded_url, and use
- // font-size:0 to hide those parts that should not be displayed (because they are not part of display_url).
- // Elements with font-size:0 get copied even though they are not visible.
- // Note that display:none doesn't work here. Elements with display:none don't get copied.
- //
- // Additionally, we want to *display* ellipses, but we don't want them copied. To make this happen we
- // wrap the ellipses in a tco-ellipsis class and provide an onCopy handler that sets display:none on
- // everything with the tco-ellipsis class.
- //
- // Exception: pic.twitter.com images, for which expandedUrl = "https://twitter.com/#!/username/status/1234/photo/1
- // For those URLs, display_url is not a substring of expanded_url, so we don't do anything special to render the elided parts.
- // For a pic.twitter.com URL, the only elided part will be the "https://", so this is fine.
-
- var displayUrlSansEllipses = displayUrl.replace(/…/g, ""); // We have to disregard ellipses for matching
- // Note: we currently only support eliding parts of the URL at the beginning or the end.
- // Eventually we may want to elide parts of the URL in the *middle*. If so, this code will
- // become more complicated. We will probably want to create a regexp out of display URL,
- // replacing every ellipsis with a ".*".
- if (expandedUrl.indexOf(displayUrlSansEllipses) != -1) {
- var displayUrlIndex = expandedUrl.indexOf(displayUrlSansEllipses);
- var v = {
- displayUrlSansEllipses: displayUrlSansEllipses,
- // Portion of expandedUrl that precedes the displayUrl substring
- beforeDisplayUrl: expandedUrl.substr(0, displayUrlIndex),
- // Portion of expandedUrl that comes after displayUrl
- afterDisplayUrl: expandedUrl.substr(displayUrlIndex + displayUrlSansEllipses.length),
- precedingEllipsis: displayUrl.match(/^…/) ? "…" : "",
- followingEllipsis: displayUrl.match(/…$/) ? "…" : ""
- };
- for (var k in v) {
- if (v.hasOwnProperty(k)) {
- v[k] = twttr.txt.htmlEscape(v[k]);
- }
- }
- // As an example: The user tweets "hi http://longdomainname.com/foo"
- // This gets shortened to "hi http://t.co/xyzabc", with display_url = "…nname.com/foo"
- // This will get rendered as:
- //
- // …
- //
- // http://longdomai
- //
- //
- // nname.com/foo
- //
- //
- //
- // …
- //
- v['invisible'] = options.invisibleTagAttrs;
- return stringSupplant("
#{precedingEllipsis} #{beforeDisplayUrl}#{displayUrlSansEllipses}#{afterDisplayUrl} #{followingEllipsis}", v);
- }
- return displayUrl;
- };
-
- twttr.txt.autoLinkEntities = function(text, entities, options) {
- options = clone(options || {});
-
- options.hashtagClass = options.hashtagClass || DEFAULT_HASHTAG_CLASS;
- options.hashtagUrlBase = options.hashtagUrlBase || "https://twitter.com/#!/search?q=%23";
- options.cashtagClass = options.cashtagClass || DEFAULT_CASHTAG_CLASS;
- options.cashtagUrlBase = options.cashtagUrlBase || "https://twitter.com/#!/search?q=%24";
- options.listClass = options.listClass || DEFAULT_LIST_CLASS;
- options.usernameClass = options.usernameClass || DEFAULT_USERNAME_CLASS;
- options.usernameUrlBase = options.usernameUrlBase || "https://twitter.com/";
- options.listUrlBase = options.listUrlBase || "https://twitter.com/";
- options.htmlAttrs = twttr.txt.extractHtmlAttrsFromOptions(options);
- options.invisibleTagAttrs = options.invisibleTagAttrs || "style='position:absolute;left:-9999px;'";
-
- // remap url entities to hash
- var urlEntities, i, len;
- if(options.urlEntities) {
- urlEntities = {};
- for(i = 0, len = options.urlEntities.length; i < len; i++) {
- urlEntities[options.urlEntities[i].url] = options.urlEntities[i];
- }
- options.urlEntities = urlEntities;
- }
-
- var result = "";
- var beginIndex = 0;
-
- // sort entities by start index
- entities.sort(function(a,b){ return a.indices[0] - b.indices[0]; });
-
- var nonEntity = options.htmlEscapeNonEntities ? twttr.txt.htmlEscape : function(text) {
- return text;
- };
-
- for (var i = 0; i < entities.length; i++) {
- var entity = entities[i];
- result += nonEntity(text.substring(beginIndex, entity.indices[0]));
-
- if (entity.url) {
- result += twttr.txt.linkToUrl(entity, text, options);
- } else if (entity.hashtag) {
- result += text;//twttr.txt.linkToHashtag(entity, text, options);
- } else if (entity.screenName) {
- result += text;//twttr.txt.linkToMentionAndList(entity, text, options);
- } else if (entity.cashtag) {
- result += text;//twttr.txt.linkToCashtag(entity, text, options);
- }
- beginIndex = entity.indices[1];
- }
- result += nonEntity(text.substring(beginIndex, text.length));
- return result;
- };
-
- twttr.txt.autoLinkWithJSON = function(text, json, options) {
- // map JSON entity to twitter-text entity
- if (json.user_mentions) {
- for (var i = 0; i < json.user_mentions.length; i++) {
- // this is a @mention
- json.user_mentions[i].screenName = json.user_mentions[i].screen_name;
- }
- }
-
- if (json.hashtags) {
- for (var i = 0; i < json.hashtags.length; i++) {
- // this is a #hashtag
- json.hashtags[i].hashtag = json.hashtags[i].text;
- }
- }
-
- if (json.symbols) {
- for (var i = 0; i < json.symbols.length; i++) {
- // this is a $CASH tag
- json.symbols[i].cashtag = json.symbols[i].text;
- }
- }
-
- // concatenate all entities
- var entities = [];
- for (var key in json) {
- entities = entities.concat(json[key]);
- }
-
- // modify indices to UTF-16
- twttr.txt.modifyIndicesFromUnicodeToUTF16(text, entities);
-
- return twttr.txt.autoLinkEntities(text, entities, options);
- };
-
- twttr.txt.extractHtmlAttrsFromOptions = function(options) {
- var htmlAttrs = {};
- for (var k in options) {
- var v = options[k];
- if (OPTIONS_NOT_ATTRIBUTES[k]) continue;
- if (BOOLEAN_ATTRIBUTES[k]) {
- v = v ? k : null;
- }
- if (v == null) continue;
- htmlAttrs[k] = v;
- }
- return htmlAttrs;
- };
-
- twttr.txt.autoLink = function(text, options) {
- var entities = twttr.txt.extractEntitiesWithIndices(text, {extractUrlsWithoutProtocol: false});
- return twttr.txt.autoLinkEntities(text, entities, options);
- };
-
- twttr.txt.autoLinkUsernamesOrLists = function(text, options) {
- var entities = twttr.txt.extractMentionsOrListsWithIndices(text);
- return twttr.txt.autoLinkEntities(text, entities, options);
- };
-
- twttr.txt.autoLinkHashtags = function(text, options) {
- var entities = twttr.txt.extractHashtagsWithIndices(text);
- return twttr.txt.autoLinkEntities(text, entities, options);
- };
-
- twttr.txt.autoLinkCashtags = function(text, options) {
- var entities = twttr.txt.extractCashtagsWithIndices(text);
- return twttr.txt.autoLinkEntities(text, entities, options);
- };
-
- twttr.txt.autoLinkUrlsCustom = function(text, options) {
- var entities = twttr.txt.extractUrlsWithIndices(text, {extractUrlsWithoutProtocol: false});
- return twttr.txt.autoLinkEntities(text, entities, options);
- };
-
- twttr.txt.removeOverlappingEntities = function(entities) {
- entities.sort(function(a,b){ return a.indices[0] - b.indices[0]; });
-
- var prev = entities[0];
- for (var i = 1; i < entities.length; i++) {
- if (prev.indices[1] > entities[i].indices[0]) {
- entities.splice(i, 1);
- i--;
- } else {
- prev = entities[i];
- }
- }
- };
-
- twttr.txt.extractEntitiesWithIndices = function(text, options) {
- var entities = twttr.txt.extractUrlsWithIndices(text, options)
- .concat(twttr.txt.extractMentionsOrListsWithIndices(text))
- .concat(twttr.txt.extractHashtagsWithIndices(text, {checkUrlOverlap: false}))
- .concat(twttr.txt.extractCashtagsWithIndices(text));
-
- if (entities.length == 0) {
- return [];
- }
-
- twttr.txt.removeOverlappingEntities(entities);
- return entities;
- };
-
- twttr.txt.extractMentions = function(text) {
- var screenNamesOnly = [],
- screenNamesWithIndices = twttr.txt.extractMentionsWithIndices(text);
-
- for (var i = 0; i < screenNamesWithIndices.length; i++) {
- var screenName = screenNamesWithIndices[i].screenName;
- screenNamesOnly.push(screenName);
- }
-
- return screenNamesOnly;
- };
-
- twttr.txt.extractMentionsWithIndices = function(text) {
- var mentions = [],
- mentionOrList,
- mentionsOrLists = twttr.txt.extractMentionsOrListsWithIndices(text);
-
- for (var i = 0 ; i < mentionsOrLists.length; i++) {
- mentionOrList = mentionsOrLists[i];
- if (mentionOrList.listSlug == '') {
- mentions.push({
- screenName: mentionOrList.screenName,
- indices: mentionOrList.indices
- });
- }
- }
-
- return mentions;
- };
-
- /**
- * Extract list or user mentions.
- * (Presence of listSlug indicates a list)
- */
- twttr.txt.extractMentionsOrListsWithIndices = function(text) {
- if (!text || !text.match(twttr.txt.regexen.atSigns)) {
- return [];
- }
-
- var possibleNames = [],
- slashListname;
-
- text.replace(twttr.txt.regexen.validMentionOrList, function(match, before, atSign, screenName, slashListname, offset, chunk) {
- var after = chunk.slice(offset + match.length);
- if (!after.match(twttr.txt.regexen.endMentionMatch)) {
- slashListname = slashListname || '';
- var startPosition = offset + before.length;
- var endPosition = startPosition + screenName.length + slashListname.length + 1;
- possibleNames.push({
- screenName: screenName,
- listSlug: slashListname,
- indices: [startPosition, endPosition]
- });
- }
- });
-
- return possibleNames;
- };
-
-
- twttr.txt.extractReplies = function(text) {
- if (!text) {
- return null;
- }
-
- var possibleScreenName = text.match(twttr.txt.regexen.validReply);
- if (!possibleScreenName ||
- RegExp.rightContext.match(twttr.txt.regexen.endMentionMatch)) {
- return null;
- }
-
- return possibleScreenName[1];
- };
-
- twttr.txt.extractUrls = function(text, options) {
- var urlsOnly = [],
- urlsWithIndices = twttr.txt.extractUrlsWithIndices(text, options);
-
- for (var i = 0; i < urlsWithIndices.length; i++) {
- urlsOnly.push(urlsWithIndices[i].url);
- }
-
- return urlsOnly;
- };
-
- twttr.txt.extractUrlsWithIndices = function(text, options) {
- if (!options) {
- options = {extractUrlsWithoutProtocol: true};
- }
- if (!text || (options.extractUrlsWithoutProtocol ? !text.match(/\./) : !text.match(/:/))) {
- return [];
- }
-
- var urls = [];
-
- while (twttr.txt.regexen.extractUrl.exec(text)) {
- var before = RegExp.$2, url = RegExp.$3, protocol = RegExp.$4, domain = RegExp.$5, path = RegExp.$7;
- var endPosition = twttr.txt.regexen.extractUrl.lastIndex,
- startPosition = endPosition - url.length;
-
- // if protocol is missing and domain contains non-ASCII characters,
- // extract ASCII-only domains.
- if (!protocol) {
- if (!options.extractUrlsWithoutProtocol
- || before.match(twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars)) {
- continue;
- }
- var lastUrl = null,
- asciiEndPosition = 0;
- domain.replace(twttr.txt.regexen.validAsciiDomain, function(asciiDomain) {
- var asciiStartPosition = domain.indexOf(asciiDomain, asciiEndPosition);
- asciiEndPosition = asciiStartPosition + asciiDomain.length;
- lastUrl = {
- url: asciiDomain,
- indices: [startPosition + asciiStartPosition, startPosition + asciiEndPosition]
- };
- if (path
- || asciiDomain.match(twttr.txt.regexen.validSpecialShortDomain)
- || !asciiDomain.match(twttr.txt.regexen.invalidShortDomain)) {
- urls.push(lastUrl);
- }
- });
-
- // no ASCII-only domain found. Skip the entire URL.
- if (lastUrl == null) {
- continue;
- }
-
- // lastUrl only contains domain. Need to add path and query if they exist.
- if (path) {
- lastUrl.url = url.replace(domain, lastUrl.url);
- lastUrl.indices[1] = endPosition;
- }
- } else {
- // In the case of t.co URLs, don't allow additional path characters.
- if (url.match(twttr.txt.regexen.validTcoUrl)) {
- url = RegExp.lastMatch;
- endPosition = startPosition + url.length;
- }
- urls.push({
- url: url,
- indices: [startPosition, endPosition]
- });
- }
- }
-
- return urls;
- };
-
- twttr.txt.extractHashtags = function(text) {
- var hashtagsOnly = [],
- hashtagsWithIndices = twttr.txt.extractHashtagsWithIndices(text);
-
- for (var i = 0; i < hashtagsWithIndices.length; i++) {
- hashtagsOnly.push(hashtagsWithIndices[i].hashtag);
- }
-
- return hashtagsOnly;
- };
-
- twttr.txt.extractHashtagsWithIndices = function(text, options) {
- if (!options) {
- options = {checkUrlOverlap: true};
- }
-
- if (!text || !text.match(twttr.txt.regexen.hashSigns)) {
- return [];
- }
-
- var tags = [];
-
- text.replace(twttr.txt.regexen.validHashtag, function(match, before, hash, hashText, offset, chunk) {
- var after = chunk.slice(offset + match.length);
- if (after.match(twttr.txt.regexen.endHashtagMatch))
- return;
- var startPosition = offset + before.length;
- var endPosition = startPosition + hashText.length + 1;
- tags.push({
- hashtag: hashText,
- indices: [startPosition, endPosition]
- });
- });
-
- if (options.checkUrlOverlap) {
- // also extract URL entities
- var urls = twttr.txt.extractUrlsWithIndices(text);
- if (urls.length > 0) {
- var entities = tags.concat(urls);
- // remove overlap
- twttr.txt.removeOverlappingEntities(entities);
- // only push back hashtags
- tags = [];
- for (var i = 0; i < entities.length; i++) {
- if (entities[i].hashtag) {
- tags.push(entities[i]);
- }
- }
- }
- }
-
- return tags;
- };
-
- twttr.txt.extractCashtags = function(text) {
- var cashtagsOnly = [],
- cashtagsWithIndices = twttr.txt.extractCashtagsWithIndices(text);
-
- for (var i = 0; i < cashtagsWithIndices.length; i++) {
- cashtagsOnly.push(cashtagsWithIndices[i].cashtag);
- }
-
- return cashtagsOnly;
- };
-
- twttr.txt.extractCashtagsWithIndices = function(text) {
- if (!text || text.indexOf("$") == -1) {
- return [];
- }
-
- var tags = [];
-
- text.replace(twttr.txt.regexen.validCashtag, function(match, before, dollar, cashtag, offset, chunk) {
- var startPosition = offset + before.length;
- var endPosition = startPosition + cashtag.length + 1;
- tags.push({
- cashtag: cashtag,
- indices: [startPosition, endPosition]
- });
- });
-
- return tags;
- };
-
- twttr.txt.modifyIndicesFromUnicodeToUTF16 = function(text, entities) {
- twttr.txt.convertUnicodeIndices(text, entities, false);
- };
-
- twttr.txt.modifyIndicesFromUTF16ToUnicode = function(text, entities) {
- twttr.txt.convertUnicodeIndices(text, entities, true);
- };
-
- twttr.txt.getUnicodeTextLength = function(text) {
- return text.replace(twttr.txt.regexen.non_bmp_code_pairs, ' ').length;
- };
-
- twttr.txt.convertUnicodeIndices = function(text, entities, indicesInUTF16) {
- if (entities.length == 0) {
- return;
- }
-
- var charIndex = 0;
- var codePointIndex = 0;
-
- // sort entities by start index
- entities.sort(function(a,b){ return a.indices[0] - b.indices[0]; });
- var entityIndex = 0;
- var entity = entities[0];
-
- while (charIndex < text.length) {
- if (entity.indices[0] == (indicesInUTF16 ? charIndex : codePointIndex)) {
- var len = entity.indices[1] - entity.indices[0];
- entity.indices[0] = indicesInUTF16 ? codePointIndex : charIndex;
- entity.indices[1] = entity.indices[0] + len;
-
- entityIndex++;
- if (entityIndex == entities.length) {
- // no more entity
- break;
- }
- entity = entities[entityIndex];
- }
-
- var c = text.charCodeAt(charIndex);
- if (0xD800 <= c && c <= 0xDBFF && charIndex < text.length - 1) {
- // Found high surrogate char
- c = text.charCodeAt(charIndex + 1);
- if (0xDC00 <= c && c <= 0xDFFF) {
- // Found surrogate pair
- charIndex++;
- }
- }
- codePointIndex++;
- charIndex++;
- }
- };
-
- // this essentially does text.split(/<|>/)
- // except that won't work in IE, where empty strings are ommitted
- // so "<>".split(/<|>/) => [] in IE, but is ["", "", ""] in all others
- // but "<<".split("<") => ["", "", ""]
- twttr.txt.splitTags = function(text) {
- var firstSplits = text.split("<"),
- secondSplits,
- allSplits = [],
- split;
-
- for (var i = 0; i < firstSplits.length; i += 1) {
- split = firstSplits[i];
- if (!split) {
- allSplits.push("");
- } else {
- secondSplits = split.split(">");
- for (var j = 0; j < secondSplits.length; j += 1) {
- allSplits.push(secondSplits[j]);
- }
- }
- }
-
- return allSplits;
- };
-
- twttr.txt.hitHighlight = function(text, hits, options) {
- var defaultHighlightTag = "em";
-
- hits = hits || [];
- options = options || {};
-
- if (hits.length === 0) {
- return text;
- }
-
- var tagName = options.tag || defaultHighlightTag,
- tags = ["<" + tagName + ">", "" + tagName + ">"],
- chunks = twttr.txt.splitTags(text),
- i,
- j,
- result = "",
- chunkIndex = 0,
- chunk = chunks[0],
- prevChunksLen = 0,
- chunkCursor = 0,
- startInChunk = false,
- chunkChars = chunk,
- flatHits = [],
- index,
- hit,
- tag,
- placed,
- hitSpot;
-
- for (i = 0; i < hits.length; i += 1) {
- for (j = 0; j < hits[i].length; j += 1) {
- flatHits.push(hits[i][j]);
- }
- }
-
- for (index = 0; index < flatHits.length; index += 1) {
- hit = flatHits[index];
- tag = tags[index % 2];
- placed = false;
-
- while (chunk != null && hit >= prevChunksLen + chunk.length) {
- result += chunkChars.slice(chunkCursor);
- if (startInChunk && hit === prevChunksLen + chunkChars.length) {
- result += tag;
- placed = true;
- }
-
- if (chunks[chunkIndex + 1]) {
- result += "<" + chunks[chunkIndex + 1] + ">";
- }
-
- prevChunksLen += chunkChars.length;
- chunkCursor = 0;
- chunkIndex += 2;
- chunk = chunks[chunkIndex];
- chunkChars = chunk;
- startInChunk = false;
- }
-
- if (!placed && chunk != null) {
- hitSpot = hit - prevChunksLen;
- result += chunkChars.slice(chunkCursor, hitSpot) + tag;
- chunkCursor = hitSpot;
- if (index % 2 === 0) {
- startInChunk = true;
- } else {
- startInChunk = false;
- }
- } else if(!placed) {
- placed = true;
- result += tag;
- }
- }
-
- if (chunk != null) {
- if (chunkCursor < chunkChars.length) {
- result += chunkChars.slice(chunkCursor);
- }
- for (index = chunkIndex + 1; index < chunks.length; index += 1) {
- result += (index % 2 === 0 ? chunks[index] : "<" + chunks[index] + ">");
- }
- }
-
- return result;
- };
-
- var MAX_LENGTH = 140;
-
- // Returns the length of Tweet text with consideration to t.co URL replacement
- // and chars outside the basic multilingual plane that use 2 UTF16 code points
- twttr.txt.getTweetLength = function(text, options) {
- if (!options) {
- options = {
- // These come from https://api.twitter.com/1/help/configuration.json
- // described by https://dev.twitter.com/docs/api/1/get/help/configuration
- short_url_length: 23,
- short_url_length_https: 23
- };
- }
- var textLength = twttr.txt.getUnicodeTextLength(text),
- urlsWithIndices = twttr.txt.extractUrlsWithIndices(text);
- twttr.txt.modifyIndicesFromUTF16ToUnicode(text, urlsWithIndices);
-
- for (var i = 0; i < urlsWithIndices.length; i++) {
- // Subtract the length of the original URL
- textLength += urlsWithIndices[i].indices[0] - urlsWithIndices[i].indices[1];
-
- // Add 23 characters for URL starting with https://
- // http:// URLs still use https://t.co so they are 23 characters as well
- if (urlsWithIndices[i].url.toLowerCase().match(twttr.txt.regexen.urlHasHttps)) {
- textLength += options.short_url_length_https;
- } else {
- textLength += options.short_url_length;
- }
- }
-
- return textLength;
- };
-
- // Check the text for any reason that it may not be valid as a Tweet. This is meant as a pre-validation
- // before posting to api.twitter.com. There are several server-side reasons for Tweets to fail but this pre-validation
- // will allow quicker feedback.
- //
- // Returns false if this text is valid. Otherwise one of the following strings will be returned:
- //
- // "too_long": if the text is too long
- // "empty": if the text is nil or empty
- // "invalid_characters": if the text contains non-Unicode or any of the disallowed Unicode characters
- twttr.txt.isInvalidTweet = function(text) {
- if (!text) {
- return "empty";
- }
-
- // Determine max length independent of URL length
- if (twttr.txt.getTweetLength(text) > MAX_LENGTH) {
- return "too_long";
- }
-
- if (twttr.txt.hasInvalidCharacters(text)) {
- return "invalid_characters";
- }
-
- return false;
- };
-
- twttr.txt.hasInvalidCharacters = function(text) {
- return twttr.txt.regexen.invalid_chars.test(text);
- };
-
- twttr.txt.isValidTweetText = function(text) {
- return !twttr.txt.isInvalidTweet(text);
- };
-
- twttr.txt.isValidUsername = function(username) {
- if (!username) {
- return false;
- }
-
- var extracted = twttr.txt.extractMentions(username);
-
- // Should extract the username minus the @ sign, hence the .slice(1)
- return extracted.length === 1 && extracted[0] === username.slice(1);
- };
-
- var VALID_LIST_RE = regexSupplant(/^#{validMentionOrList}$/);
-
- twttr.txt.isValidList = function(usernameList) {
- var match = usernameList.match(VALID_LIST_RE);
-
- // Must have matched and had nothing before or after
- return !!(match && match[1] == "" && match[4]);
- };
-
- twttr.txt.isValidHashtag = function(hashtag) {
- if (!hashtag) {
- return false;
- }
-
- var extracted = twttr.txt.extractHashtags(hashtag);
-
- // Should extract the hashtag minus the # sign, hence the .slice(1)
- return extracted.length === 1 && extracted[0] === hashtag.slice(1);
- };
-
- twttr.txt.isValidUrl = function(url, unicodeDomains, requireProtocol) {
- if (unicodeDomains == null) {
- unicodeDomains = true;
- }
-
- if (requireProtocol == null) {
- requireProtocol = true;
- }
-
- if (!url) {
- return false;
- }
-
- var urlParts = url.match(twttr.txt.regexen.validateUrlUnencoded);
-
- if (!urlParts || urlParts[0] !== url) {
- return false;
- }
-
- var scheme = urlParts[1],
- authority = urlParts[2],
- path = urlParts[3],
- query = urlParts[4],
- fragment = urlParts[5];
-
- if (!(
- (!requireProtocol || (isValidMatch(scheme, twttr.txt.regexen.validateUrlScheme) && scheme.match(/^https?$/i))) &&
- isValidMatch(path, twttr.txt.regexen.validateUrlPath) &&
- isValidMatch(query, twttr.txt.regexen.validateUrlQuery, true) &&
- isValidMatch(fragment, twttr.txt.regexen.validateUrlFragment, true)
- )) {
- return false;
- }
-
- return (unicodeDomains && isValidMatch(authority, twttr.txt.regexen.validateUrlUnicodeAuthority)) ||
- (!unicodeDomains && isValidMatch(authority, twttr.txt.regexen.validateUrlAuthority));
- };
-
- function isValidMatch(string, regex, optional) {
- if (!optional) {
- // RegExp["$&"] is the text of the last match
- // blank strings are ok, but are falsy, so we check stringiness instead of truthiness
- return ((typeof string === "string") && string.match(regex) && RegExp["$&"] === string);
- }
-
- // RegExp["$&"] is the text of the last match
- return (!string || (string.match(regex) && RegExp["$&"] === string));
- }
-
- if (typeof module != 'undefined' && module.exports) {
- module.exports = twttr.txt;
- }
-
- if (true) {
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (twttr.txt), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
- }
-
- if (typeof window != 'undefined') {
- if (window.twttr) {
- for (var prop in twttr) {
- window.twttr[prop] = twttr[prop];
- }
- } else {
- window.twttr = twttr;
- }
- }
- })();
-
-
-/***/ },
-/* 2 */
-/***/ function(module, exports, __webpack_require__) {
-
- var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module) {'use strict';var _typeof2=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj;}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol?"symbol":typeof obj;};(function webpackUniversalModuleDefinition(root,factory){if(( false?'undefined':_typeof2(exports))==='object'&&( false?'undefined':_typeof2(module))==='object')module.exports=factory();else if(true)!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));else if((typeof exports==='undefined'?'undefined':_typeof2(exports))==='object')exports["PDFAnnotate"]=factory();else root["PDFAnnotate"]=factory();})(undefined,function(){return(/******/function(modules){// webpackBootstrap
- /******/// The module cache
- /******/var installedModules={};/******//******/// The require function
- /******/function __webpack_require__(moduleId){/******//******/// Check if module is in cache
- /******/if(installedModules[moduleId])/******/return installedModules[moduleId].exports;/******//******/// Create a new module (and put it into the cache)
- /******/var module=installedModules[moduleId]={/******/exports:{},/******/id:moduleId,/******/loaded:false/******/};/******//******/// Execute the module function
- /******/modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);/******//******/// Flag the module as loaded
- /******/module.loaded=true;/******//******/// Return the exports of the module
- /******/return module.exports;/******/}/******//******//******/// expose the modules object (__webpack_modules__)
- /******/__webpack_require__.m=modules;/******//******/// expose the module cache
- /******/__webpack_require__.c=installedModules;/******//******/// __webpack_public_path__
- /******/__webpack_require__.p="";/******//******/// Load entry module and return exports
- /******/return __webpack_require__(0);/******/}(/************************************************************************//******/
- [/* 0 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
- function _interopRequireDefault(obj){
- return obj&&obj.__esModule?obj:{default:obj};
- }
- exports.default=_PDFJSAnnotate2.default;
- module.exports=exports['default'];/***/},
- /* 1 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- var _StoreAdapter=__webpack_require__(2);
- var _StoreAdapter2=_interopRequireDefault(_StoreAdapter);
- var _LocalStoreAdapter=__webpack_require__(8);
- var _LocalStoreAdapter2=_interopRequireDefault(_LocalStoreAdapter);
- var _render=__webpack_require__(10);
- var _render2=_interopRequireDefault(_render);
- var _UI=__webpack_require__(28);
- var _UI2=_interopRequireDefault(_UI);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- exports.default={/**
- * Abstract class that needs to be defined so PDFJSAnnotate
- * knows how to communicate with your server.
- */StoreAdapter:_StoreAdapter2.default,/**
- * Implementation of StoreAdapter that stores annotation data to localStorage.
- */LocalStoreAdapter:_LocalStoreAdapter2.default,/**
- * Abstract instance of StoreAdapter
- */__storeAdapter:new _StoreAdapter2.default(),/**
- * Getter for the underlying StoreAdapter property
- *
- * @return {StoreAdapter}
- */getStoreAdapter:function getStoreAdapter(){return this.__storeAdapter;},/**
- * Setter for the underlying StoreAdapter property
- *
- * @param {StoreAdapter} adapter The StoreAdapter implementation to be used.
- */setStoreAdapter:function setStoreAdapter(adapter){// TODO this throws an error when bundled
- // if (!(adapter instanceof StoreAdapter)) {
- // throw new Error('adapter must be an instance of StoreAdapter');
- // }
- this.__storeAdapter=adapter;},/**
- * UI is a helper for instrumenting UI interactions for creating,
- * editing, and deleting annotations in the browser.
- */UI:_UI2.default,/**
- * Render the annotations for a page in the PDF Document
- *
- * @param {SVGElement} svg The SVG element that annotations should be rendered to
- * @param {PageViewport} viewport The PDFPage.getViewport data
- * @param {Object} data The StoreAdapter.getAnnotations data
- * @return {Promise}
- */render:_render2.default,/**
- * Convenience method for getting annotation data
- *
- * @alias StoreAdapter.getAnnotations
- * @param {String} documentId The ID of the document
- * @param {String} pageNumber The page number
- * @return {Promise}
- */getAnnotations:function getAnnotations(documentId,pageNumber){
- var _getStoreAdapter;
- return(_getStoreAdapter=this.getStoreAdapter()).getAnnotations.apply(_getStoreAdapter,arguments);
- }
- };
- module.exports=exports['default'];/***/},
- /* 2 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- var _createClass=function(){
- function defineProperties(target,props){
- for(var i=0;i
= 0 && index < options) {
+ document.querySelector('.toolbar select.scale').selectedIndex = index;
+ }
+ $('.toolbar select.scale').change();
+ setTimeout(function () {
+ document.getElementById('pdfannotator_cursor').click();
+ }, 100);
}
- }
- return function(Constructor,protoProps,staticProps){
- if(protoProps)defineProperties(Constructor.prototype,protoProps);
- if(staticProps)defineProperties(Constructor,staticProps);
- return Constructor;
- };
- }();
- var _abstractFunction=__webpack_require__(3);
- var _abstractFunction2=_interopRequireDefault(_abstractFunction);
- var _event=__webpack_require__(4);
- function _interopRequireDefault(obj){
- return obj&&obj.__esModule?obj:{default:obj};
- }
- function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
- // Adapter should never be invoked publicly
- var StoreAdapter=function(){/**
- * Create a new StoreAdapter instance
- *
- * @param {Object} [definition] The definition to use for overriding abstract methods
- */function StoreAdapter(){var _this=this;var definition=arguments.length<=0||arguments[0]===undefined?{}:arguments[0];_classCallCheck(this,StoreAdapter);// Copy each function from definition if it is a function we know about
- Object.keys(definition).forEach(function(key){if(typeof definition[key]==='function'&&typeof _this[key]==='function'){_this[key]=definition[key];}});}
- _createClass(StoreAdapter,[
-
- /**
- * Get all the annotations for a given document and page number.
- *
- * @param {String} documentId The ID for the document the annotations belong to
- * @param {Number} pageNumber The number of the page the annotations belong to
- * @return {Promise}
- */
- {key:'__getAnnotations',value:function __getAnnotations(documentId,pageNumber){
- (0,_abstractFunction2.default)('getAnnotations');
- }
- },
- /**
- * Get the definition for a specific annotation.
- *
- * @param {String} documentId The ID for the document the annotation belongs to
- * @param {String} annotationId The ID for the annotation
- * @return {Promise}
- */
- {key:'getAnnotation',value:function getAnnotation(documentId,annotationId){
- (0,_abstractFunction2.default)('getAnnotation');
- }
- },
- /**
- * Add an annotation
- *
- * @param {String} documentId The ID for the document to add the annotation to
- * @param {String} pageNumber The page number to add the annotation to
- * @param {Object} annotation The definition for the new annotation
- * @return {Promise}
- */
- {key:'__addAnnotation',value:function __addAnnotation(documentId,pageNumber,annotation){
- (0,_abstractFunction2.default)('addAnnotation');
- }
- },
- /**
- * Edit an annotation
- *
- * @param {String} documentId The ID for the document
- * @param {String} pageNumber the page number of the annotation
- * @param {Object} annotation The definition of the modified annotation
- * @return {Promise}
- */
- {key:'__editAnnotation',value:function __editAnnotation(documentId,page,annotationId,annotation){
- (0,_abstractFunction2.default)('editAnnotation');
- }
- },
- // Original:
-// {key:'__editAnnotation',value:function __editAnnotation(documentId,pageNumber,annotation){
-// (0,_abstractFunction2.default)('editAnnotation');
-// }
-// },
- /**
- * Delete an annotation
- *
- * @param {String} documentId The ID for the document
- * @param {String} annotationId The ID for the annotation
- * @return {Promise}
- */
- {key:'__deleteAnnotation',value:function __deleteAnnotation(documentId,annotationId){
- (0,_abstractFunction2.default)('deleteAnnotation');
- }
- },
- /**
- * Get all the comments for an annotation
- *
- * @param {String} documentId The ID for the document
- * @param {String} annotationId The ID for the annotation
- * @return {Promise}
- */
- {key:'getComments',value:function getComments(documentId,annotationId){
- (0,_abstractFunction2.default)('getComments');
- }
- },
-
- /**
- * Get all the questions of one page
- *
- * @param {String} documentId The ID for the document
- * @param {String} pageNumber The number of the requested page
- * @return {Promise}
- */
- {key:'getQuestions',value:function getQuestions(documentId,pageNumber,pattern){
- (0,_abstractFunction2.default)('getQuestions');
- }
- },
- /**
- * Get all the questions of one page
- *
- * @param {String} documentId The ID for the document
- * @param {String} pageNumber The number of the requested page
- * @return {Promise}
- */
- {key:'__getQuestions',value:function getQuestions(documentId,pageNumber,pattern){
- (0,_abstractFunction2.default)('getQuestions');
- }
- },
- /**
- * Add a new comment
- *
- * @param {String} documentId The ID for the document
- * @param {String} annotationId The ID for the annotation
- * @param {Object} content The definition of the comment
- * @return {Promise}
- *
- */
- {key:'__addComment',value:function __addComment(documentId,annotationId,content){
- (0,_abstractFunction2.default)('addComment');
- }
- },
- /**
- * Report a new comment
- *
- * @param {String} documentId The ID for the document
- * @param {String} commentId The id of the comment that is to be reported
- * @param {String} reason for reporting the comment: 'inaccurate', 'inappropriate' or 'other'
- * @param {Object} content The definition of the complaint
- * @return {Promise}
- *
- */
- {key:'__reportComment',value:function reportComment(documentId,commentId,reason,content){
- (0,_abstractFunction2.default)('reportComment');
- }
- },
- /**
- * Delete a comment
- *
- * @param {String} documentId The ID for the document
- * @param {String} commentId The ID for the comment
- * @return {Promise}
- */
- {key:'__deleteComment',value:function __deleteComment(documentId,commentId){
- (0,_abstractFunction2.default)('deleteComment');
- }
- },
- /**
- * Hide a comment from participants view (i.e. display it as deleted)
- *
- * @param {String} documentId The ID for the document
- * @param {String} commentId The ID for the comment
- * @return {Promise}
- */
- {key:'__hideComment',value:function __hideComment(documentId,commentId){
- (0,_abstractFunction2.default)('hideComment');
- }
- },
- /**
- * Redisplay a comment for participants
- *
- * @param {String} documentId The ID for the document
- * @param {String} commentId The ID for the comment
- * @return {Promise}
- */
- {key:'__redisplayComment',value:function __redisplayComment(documentId,commentId){
- (0,_abstractFunction2.default)('redisplayComment');
- }
- },
- /**
- * Vote for a comment
- * @param {String} documentId The ID for the document
- * @param {String} commentId The ID for the comment
- * @return {Promise}
- */
- {key:'__getInformation',value:function __getInformation(documentId,annotationId){
- (0,_abstractFunction2.default)('getInformation');
- }
- },
-
- /**
- * Vote for a comment
- * @param {String} documentId The ID for the document
- * @param {String} commentId The ID for the comment
- * @return {Promise}
- */
- {key:'__voteComment',value:function __voteComment(documentId,commentId){
- (0,_abstractFunction2.default)('voteComment');
- }
- },
-
- /**
- * Edit a comment
- * @param {String} documentId The ID for the document
- * @param {String} commentId The ID for the comment
- * @return {Promise}
- */
- {key:'__editComment',value:function __editComment(documentId,commentId){
- (0,_abstractFunction2.default)('editComment');
- }
- },
-
- /**
- * Subscribe to a question
- * @param {String} documentId The ID for the document
- * @param {String} commentId The ID for the comment
- * @return {Promise}
- */
- {key:'__subscribeQuestion',value:function __subscribeQuestion(documentId,annotationId){
- (0,_abstractFunction2.default)('subscribeQuestion');
- }
- },
-
- {key:'__unsubscribeQuestion',value:function __unsubscribeQuestion(documentId,annotationId){
- (0,_abstractFunction2.default)('unsubscribeQuestion');
- }
- },
-
- {key:'__markSolved',value:function __markSolved(documentId,comment){
- (0,_abstractFunction2.default)('markSolved');
- }
- },
-
- {key:'__getCommentsToPrint',value:function __getCommentsToPrint(documentId){
- (0,_abstractFunction2.default)('getCommentsToPrint');
- }
- },
-
- {key:'getAnnotations',get:function get(){
- return this.__getAnnotations;
- },
- set:function set(fn){
- this.__getAnnotations=function getAnnotations(documentId,pageNumber){
- return fn.apply(undefined,arguments).then(function(annotations){// TODO may be best to have this happen on the server
- if(annotations.annotations){
- annotations.annotations.forEach(function(a){
- a.documentId=documentId;
- });
- }
- return annotations;
- });};}},
- {key:'addAnnotation',get:function get(){
- return this.__addAnnotation;
- },
- set:function set(fn){this.__addAnnotation=function addAnnotation(documentId,pageNumber,annotation){return fn.apply(undefined,arguments).then(function(annotation){(0,_event.fireEvent)('annotation:add',documentId,pageNumber,annotation);return annotation;});};}},
- {key:'editAnnotation',get:function get(){
- return this.__editAnnotation;
- },set:function set(fn){
- this.__editAnnotation=function editAnnotation(documentId,page,annotationId,annotation){
- return fn.apply(undefined,arguments).then(function(annotation){
- (0,_event.fireEvent)('annotation:edit',documentId,annotationId,annotation);
- return annotation;
- });
- };
- }
- },
- {key:'deleteAnnotation',get:function get(){return this.__deleteAnnotation;},set:function set(fn){this.__deleteAnnotation=function deleteAnnotation(documentId,annotationId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('annotation:delete',documentId,annotationId);}return success;});};}},
- {key:'addComment',get:function get(){return this.__addComment;},set:function set(fn){this.__addComment=function addComment(documentId,annotationId,content){return fn.apply(undefined,arguments).then(function(comment){(0,_event.fireEvent)('comment:add',documentId,annotationId,comment);return comment;});};}},
- {key:'reportComment',get:function get(){return this.__reportComment;},set:function set(fn){this.__reportComment=function reportComment(documentId,commentId,reason,content){return fn.apply(undefined,arguments).then(function(comment){(0,_event.fireEvent)('comment:report',documentId,commentId,reason,content);return comment;});};}},
- {key:'deleteComment',get:function get(){return this.__deleteComment;},set:function set(fn){this.__deleteComment=function deleteComment(documentId,commentId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('comment:delete',documentId,commentId);}return success;});};}},
- {key:'hideComment',get:function get(){return this.__hideComment;},set:function set(fn){this.__hideComment=function hideComment(documentId,commentId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('comment:hide',documentId,commentId);}return success;});};}},
- {key:'redisplayComment',get:function get(){return this.__redisplayComment;},set:function set(fn){this.__redisplayComment=function redisplayComment(documentId,commentId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('comment:redisplay',documentId,commentId);}return success;});};}},
- {key:'getInformation',get:function get(){return this.__getInformation;},set:function set(fn){this.__getInformation=function getInformation(documentId,annotationId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('annotation:getInformation',documentId,annotationId);}return success;});};}},
- {key:'voteComment',get:function get(){return this.__voteComment;},set:function set(fn){this.__voteComment=function voteComment(documentId,commentId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('comment:vote',documentId,commentId);}return success;});};}},
- {key:'editComment',get:function get(){return this.__editComment;},set:function set(fn){this.__editComment=function editComment(documentId,commentId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('comment:edit',documentId,commentId);}return success;});};}},
- {key:'subscribeQuestion',get:function get(){return this.__subscribeQuestion;},set:function set(fn){this.__subscribeQuestion=function subscribeQuestion(documentId,annotationId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('comment:subscribe',documentId,annotationId);}return success;});};}},
- {key:'unsubscribeQuestion',get:function get(){return this.__unsubscribeQuestion;},set:function set(fn){this.__unsubscribeQuestion=function unsubscribeQuestion(documentId,annotationId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('comment:unsubscribe',documentId,annotationId);}return success;});};}},
- {key:'markSolved',get:function get(){return this.__markSolved;},set:function set(fn){this.__markSolved=function markSolved(documentId,comment){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('comment:markSolved',documentId,comment);}return success;});};}},
- {key:'getCommentsToPrint',get:function get(){return this.__getCommentsToPrint;},set:function set(fn){this.__getCommentsToPrint=function getCommentsToPrint(documentId){return fn.apply(undefined,arguments).then(function(success){if(success){(0,_event.fireEvent)('document:printannotations',documentId);}return success;});};}}
-
- ]);return StoreAdapter;
- }(); //Ende StoreAdapter
- exports.default=StoreAdapter;
- module.exports=exports['default'];
- /***/},
- /* 3 */
- /***/function(module,exports){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.default=abstractFunction;/**
- * Throw an Error for an abstract function that hasn't been implemented.
- *
- * @param {String} name The name of the abstract function
- */
- function abstractFunction(name){throw new Error(name+' is not implemented');}
- module.exports=exports['default'];/***/
- },
- /* 4 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.fireEvent=fireEvent;
- exports.addEventListener=addEventListener;
- exports.removeEventListener=removeEventListener;
- exports.handleDocClick = handleDocumentClickFunction;
- var _events=__webpack_require__(5);
- var _events2=_interopRequireDefault(_events);
- var _utils=__webpack_require__(6);
- var _editoverlay = __webpack_require__(29);
- function _interopRequireDefault(obj){
- return obj&&obj.__esModule?obj:{default:obj};
- }
- var emitter=new _events2.default();
- var clickNode=void 0;
- var count = 0;
-
- /**
- * This function handles the document click. It looks for annotations under the click point.
- * If there are more than one annotation, a modal window pops up and the user can select, which one he/she wanted to click.
- * @param {type} e the event object of the click
- * @param {type} commid
- * @returns {undefined}
- */
- function handleDocumentClickFunction(e,commid = null){
- let tar = $('#' + e.target.id);
- if (tar.hasClass('moodle-dialogue') || tar.parents('.moodle-dialogue').length > 0) {
- return; //Dialog (for example from atto-editor) was clicked.
- }
- //the last parameter is true to get an array instead of the first annotation found.
- var target=(0,_utils.findAnnotationAtPoint)(e.clientX,e.clientY,true);
-
- if (target != null && Object.prototype.toString.call( target ) === '[object Array]' && target.length>1) {
- //creats a modal window to select which one of the overlapping annotation should be selected.
- var modal = document.createElement('div');
- modal.id= "myModal";
- modal.className = "modal hide fade";
- modal.setAttribute('tabindex', -1);
- modal.setAttribute('role', "dialog");
- modal.setAttribute('aria-labelledby', "myModalLabel");
- modal.setAttribute('aria-hidden', "true");
- var modaldialog = document.createElement('div');
- modaldialog.className = "modal-dialog";
- var modalcontent = document.createElement('div');
- modalcontent.className = "modal-content";
- var modalheader = document.createElement('div');
- modalheader.className = "modal-header";
- var headerClose = document.createElement('button');
- headerClose.setAttribute('type', "button");
- headerClose.className = "close";
- headerClose.setAttribute('data-dismiss', "modal");
- headerClose.setAttribute('aria-hidden', "true");
- headerClose.innerHTML = "x";
-
- headerClose.addEventListener("click",function(){
- $('body').removeClass('modal-open');
- $('#myModal').remove();
- });
-
- var headertitle = document.createElement('h3');
- headertitle.id = "myModalLabel";
- headertitle.innerHTML = M.util.get_string('decision','pdfannotator');
- headertitle.style.display = "inline-block";
- modalheader.appendChild(headertitle);
- modalheader.appendChild(headerClose);
-
-
- var modalbody = document.createElement('div');
- modalbody.className = "modal-body";
- var bodytext = document.createElement('p');
- bodytext.innerHTML = M.util.get_string('decision:overlappingAnnotation','pdfannotator');
- modalbody.appendChild(bodytext);
-
- modalcontent.appendChild(modalheader);
- modalcontent.appendChild(modalbody);
-
- modaldialog.appendChild(modalcontent);
- modal.appendChild(modaldialog);
-
- $('#body-wrapper').append(modal);
- $('#myModal').modal({backdrop:false});
- for(var i=0;i0&&this._events[type].length>m){this._events[type].warned=true;console.error('(node) warning: possible EventEmitter memory '+'leak detected. %d listeners added. '+'Use emitter.setMaxListeners() to increase limit.',this._events[type].length);if(typeof console.trace==='function'){// not supported in IE 10
- console.trace();}}}return this;
- };
- EventEmitter.prototype.on=EventEmitter.prototype.addListener;
- EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError('listener must be a function');var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments);}}g.listener=listener;this.on(type,g);return this;};
- // emits a 'removeListener' event iff the listener was removed
- EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError('listener must be a function');if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit('removeListener',type,listener);}else if(isObject(list)){for(i=length;i-->0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break;}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type];}else{list.splice(position,1);}if(this._events.removeListener)this.emit('removeListener',type,listener);}return this;};
- EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;// not listening for removeListener, no need to emit
- if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this;}// emit removeListener for all listeners on all events
- if(arguments.length===0){for(key in this._events){if(key==='removeListener')continue;this.removeAllListeners(key);}this.removeAllListeners('removeListener');this._events={};return this;}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners);}else if(listeners){// LIFO order
- while(listeners.length){this.removeListener(type,listeners[listeners.length-1]);}}delete this._events[type];return this;};
- EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret;};
- EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length;}return 0;};
- EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type);};
- function isFunction(arg){return typeof arg==='function';}
- function isNumber(arg){return typeof arg==='number';}
- function isObject(arg){return(typeof arg==='undefined'?'undefined':_typeof2(arg))==='object'&&arg!==null;}
- function isUndefined(arg){return arg===void 0;}
- /***/},
- /* 6 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.BORDER_COLOR=undefined;
- exports.findSVGContainer=findSVGContainer;
- exports.findSVGAtPoint=findSVGAtPoint;
- exports.findAnnotationAtPoint=findAnnotationAtPoint;
- exports.pointIntersectsRect=pointIntersectsRect;
- exports.getOffsetAnnotationRect=getOffsetAnnotationRect;
- exports.getAnnotationRect=getAnnotationRect;
- exports.scaleUp=scaleUp;
- exports.scaleDown=scaleDown;
- exports.getScroll=getScroll;
- exports.getOffset=getOffset;
- exports.disableUserSelect=disableUserSelect;
- exports.enableUserSelect=enableUserSelect;
- exports.getMetadata=getMetadata;
- //R: Function to round digits
- exports.roundDigits = roundDigits;
- var _createStylesheet=__webpack_require__(7);
- var _createStylesheet2=_interopRequireDefault(_createStylesheet);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- var BORDER_COLOR=exports.BORDER_COLOR='#00BFFF';
- var userSelectStyleSheet=(0,_createStylesheet2.default)({body:{'-webkit-user-select':'none','-moz-user-select':'none','-ms-user-select':'none','user-select':'none'}});
- userSelectStyleSheet.setAttribute('data-pdf-annotate-user-select','true');
- /**
- * Find the SVGElement that contains all the annotations for a page
- *
- * @param {Element} node An annotation within that container
- * @return {SVGElement} The container SVG or null if it can't be found
- */function findSVGContainer(node){
- var parentNode=node;
- while((parentNode=parentNode.parentNode)&&parentNode!==document){
- if(parentNode.nodeName.toUpperCase()==='SVG'&&parentNode.getAttribute('data-pdf-annotate-container')==='true'){
- return parentNode;
- }
- }
- return null;
- }/**
- * Find an SVGElement container at a given point
- *
- * @param {Number} x The x coordinate of the point
- * @param {Number} y The y coordinate of the point
- * @param {Boolean} array If the return value should be an array or a single svg object.
- * @return {SVGElement} The container SVG or null if one can't be found. If more than one and array=true the return value is an array of SVGs.
- */function findSVGAtPoint(x,y,array){
- var elements=document.querySelectorAll('svg[data-pdf-annotate-container="true"]');
- if(array){
- var ret = [];
- //end R
- for(var i=0,l=elements.length;i0){
- return ret;
- }
- }else{
- for(var i=0,l=elements.length;i0){
- return ret;
- }
- }else{
- elements = svg.querySelectorAll('[data-pdf-annotate-type]');
- for(var i=0,l=elements.length;i=rect.top&&y<=rect.bottom&&x>=rect.left&&x<=rect.right;}/**
- * Get the rect of an annotation element accounting for offset.
- *
- * @param {Element} el The element to get the rect of
- * @return {Object} The dimensions of the element
- */function getOffsetAnnotationRect(el){
- var rect=getAnnotationRect(el);
- var _getOffset=getOffset(el);
- var offsetLeft=_getOffset.offsetLeft;
- var offsetTop=_getOffset.offsetTop;
- return {
- top:rect.top+offsetTop,
- left:rect.left+offsetLeft,
- right:rect.right+offsetLeft,
- bottom:rect.bottom+offsetTop
- };
- }/**
- * Get the rect of an annotation element.
- *
- * @param {Element} el The element to get the rect of
- * @return {Object} The dimensions of the element
- */function getAnnotationRect(el){
- var h=0,w=0,x=0,y=0;
- var rect=el.getBoundingClientRect();
- // TODO this should be calculated somehow
- var LINE_OFFSET=16;
- var isFirefox = /firefox/i.test(navigator.userAgent);
- switch(el.nodeName.toLowerCase()){
- case'path':
- var minX=void 0,maxX=void 0,minY=void 0,maxY=void 0;
- el.getAttribute('d').replace(/Z/,'').split('M').splice(1).forEach(function(p){var s=p.split(' ').map(function(i){return parseInt(i,10);});if(typeof minX==='undefined'||s[0]maxX){maxX=s[2];}if(typeof minY==='undefined'||s[1]maxY){maxY=s[3];}});
- h=maxY-minY;
- w=maxX-minX;
- x=minX;
- y=minY;
- break;
- case'line':
- h=parseInt(el.getAttribute('y2'),10)-parseInt(el.getAttribute('y1'),10);
- w=parseInt(el.getAttribute('x2'),10)-parseInt(el.getAttribute('x1'),10);
- x=parseInt(el.getAttribute('x1'),10);
- y=parseInt(el.getAttribute('y1'),10);
- if(h===0){
- h+=LINE_OFFSET;
- y-=LINE_OFFSET/2;
- }
- break;
- case'text':
- h=rect.height;
- w=rect.width;
- x=parseInt(el.getAttribute('x'),10);
- y=parseInt(el.getAttribute('y'),10)-h;
- break;
- case'g':
- var _getOffset2=getOffset(el);
- var offsetLeft=_getOffset2.offsetLeft;
- var offsetTop=_getOffset2.offsetTop;
- h=rect.height;
- w=rect.width;
- x=rect.left-offsetLeft;
- y=rect.top-offsetTop;
- if(el.getAttribute('data-pdf-annotate-type')==='strikeout'){
- h+=LINE_OFFSET;
- y-=LINE_OFFSET/2;
+ document.querySelector('a.hideComments').addEventListener('click', handleHideClick);
+ })(); //end hide/show annotations button
+
+ // Jump to Page
+ (function () {
+ var currentPageInput = $('#currentPage');
+ var oldPage = currentPageInput.val();
+
+ function jumpToPage() {
+ var numPages = parseInt($('#sumPages').html(), 10);
+ var newPage = parseInt(currentPageInput.val(), 10);
+
+ var inputValid = false;
+ if (Number.isInteger(newPage)) {
+ if (newPage >= 1 && newPage <= numPages) {
+ inputValid = true;
}
- break;
- case'rect':
- case'svg':
- h=parseInt(el.getAttribute('height'),10);
- w=parseInt(el.getAttribute('width'),10);
- x=parseInt(el.getAttribute('x'),10);
- y=parseInt(el.getAttribute('y'),10);
- break;
- }// Result provides same properties as getBoundingClientRect
- var result={top:y,left:x,width:w,height:h,right:x+w,bottom:y+h};// For the case of nested SVG (point annotations) and grouped
- // lines or rects no adjustment needs to be made for scale.
- // I assume that the scale is already being handled
- // natively by virtue of the `transform` attribute.
- if(!['svg','g'].includes(el.nodeName.toLowerCase())){
- result=scaleUp(findSVGAtPoint(rect.left,rect.top),result);
- }
- // FF scales nativly and uses always the 100%-Attributes, so the svg has to be scaled up to proof, if it is on the same position.
- if(isFirefox && ['svg'].includes(el.nodeName.toLowerCase())){
- var svgTMP;
- if((svgTMP = findSVGAtPoint(rect.left,rect.top)) !== null){
- result=scaleUp(svgTMP,result);
}
+
+ if (!inputValid) {
+ currentPageInput.val(oldPage);
+ return;
+ }
+
+ oldPage = newPage;
+ $('#content-wrapper').scrollTop(document.getElementById('pageContainer' + newPage).offsetTop);
}
- return result;
- }
- /**
- * Adjust scale from normalized scale (100%) to rendered scale.
- *
- * @param {SVGElement} svg The SVG to gather metadata from
- * @param {Object} rect A map of numeric values to scale
- * @return {Object} A copy of `rect` with values scaled up
- */function scaleUp(svg,rect){
- if(svg === null){
- return rect;
- }
- var result={};
- var _getMetadata=getMetadata(svg);
- var viewport=_getMetadata.viewport;
- Object.keys(rect).forEach(function(key){result[key]=rect[key]*viewport.scale;});
- return result;
- }/**
- * Adjust scale from rendered scale to a normalized scale (100%).
- *
- * @param {SVGElement} svg The SVG to gather metadata from
- * @param {Object} rect A map of numeric values to scale
- * @return {Object} A copy of `rect` with values scaled down
- */function scaleDown(svg,rect){var result={};var _getMetadata2=getMetadata(svg);var viewport=_getMetadata2.viewport;Object.keys(rect).forEach(function(key){result[key]=rect[key]/viewport.scale;});return result;}/**
- * Get the scroll position of an element, accounting for parent elements
- *
- * @param {Element} el The element to get the scroll position for
- * @return {Object} The scrollTop and scrollLeft position
- */function getScroll(el){var scrollTop=0;var scrollLeft=0;var parentNode=el;while((parentNode=parentNode.parentNode)&&parentNode!==document){scrollTop+=parentNode.scrollTop;scrollLeft+=parentNode.scrollLeft;}return{scrollTop:scrollTop,scrollLeft:scrollLeft};}/**
- * Get the offset position of an element, accounting for parent elements
- *
- * @param {Element} el The element to get the offset position for
- * @return {Object} The offsetTop and offsetLeft position
- */function getOffset(el){var parentNode=el;while((parentNode=parentNode.parentNode)&&parentNode!==document){if(parentNode.nodeName.toUpperCase()==='SVG'){break;}}var rect=parentNode.getBoundingClientRect();return{offsetLeft:rect.left,offsetTop:rect.top};}/**
- * Disable user ability to select text on page
- */function disableUserSelect(){if(!userSelectStyleSheet.parentNode){document.head.appendChild(userSelectStyleSheet);}}/**
- * Enable user ability to select text on page
- */function enableUserSelect(){if(userSelectStyleSheet.parentNode){userSelectStyleSheet.parentNode.removeChild(userSelectStyleSheet);}}/**
- * Get the metadata for a SVG container
- *
- * @param {SVGElement} svg The SVG container to get metadata for
- */function getMetadata(svg){return{documentId:svg.getAttribute('data-pdf-annotate-document'),pageNumber:parseInt(svg.getAttribute('data-pdf-annotate-page'),10),viewport:JSON.parse(svg.getAttribute('data-pdf-annotate-viewport'))};}
-
- /*
- * This function rounds a digit
- * @param {type} num digit, which should be rounded
- * @param {type} places
- * @return {undefined}
- */
- function roundDigits(num, places){
- return +(Math.round(num + "e+" + places) + "e-" + places);
- }
- /***/},
- /* 7 */
- /***/function(module,exports){
- module.exports=function createStyleSheet(blocks){var style=document.createElement('style');var text=Object.keys(blocks).map(function(selector){return processRuleSet(selector,blocks[selector]);}).join('\n');style.setAttribute('type','text/css');style.appendChild(document.createTextNode(text));return style;};
- function processRuleSet(selector,block){return selector+' {\n'+processDeclarationBlock(block)+'\n}';}
- function processDeclarationBlock(block){return Object.keys(block).map(function(prop){return processDeclaration(prop,block[prop]);}).join('\n');}
- function processDeclaration(prop,value){if(!isNaN(value)&&value!=0){value=value+'px';}return hyphenate(prop)+': '+value+';';}
- function hyphenate(prop){return prop.replace(/[A-Z]/g,function(match){return'-'+match.toLowerCase();});}
- /***/},
- /* 8 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- var _uuid=__webpack_require__(9);
- var _uuid2=_interopRequireDefault(_uuid);
- var _StoreAdapter2=__webpack_require__(2);
- var _StoreAdapter3=_interopRequireDefault(_StoreAdapter2);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}
- function _possibleConstructorReturn(self,call){if(!self){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return call&&((typeof call==='undefined'?'undefined':_typeof2(call))==="object"||typeof call==="function")?call:self;}
- function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function, not "+(typeof superClass==='undefined'?'undefined':_typeof2(superClass)));}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,enumerable:false,writable:true,configurable:true}});if(superClass)Object.setPrototypeOf?Object.setPrototypeOf(subClass,superClass):subClass.__proto__=superClass;}
- // StoreAdapter for working with localStorage
- // This is ideal for testing, examples, and prototyping
- var LocalStoreAdapter=function(_StoreAdapter){_inherits(LocalStoreAdapter,_StoreAdapter);function LocalStoreAdapter(){_classCallCheck(this,LocalStoreAdapter);return _possibleConstructorReturn(this,Object.getPrototypeOf(LocalStoreAdapter).call(this,{getAnnotations:function getAnnotations(documentId,pageNumber){return new Promise(function(resolve,reject){var annotations=_getAnnotations(documentId).filter(function(i){return i.page===pageNumber&&i.class==='Annotation';});resolve({documentId:documentId,pageNumber:pageNumber,annotations:annotations});});},getAnnotation:function getAnnotation(documentId,annotationId){return Promise.resolve(_getAnnotations(documentId)[findAnnotation(documentId,annotationId)]);},addAnnotation:function addAnnotation(documentId,pageNumber,annotation){return new Promise(function(resolve,reject){annotation.class='Annotation';annotation.uuid=(0,_uuid2.default)();annotation.page=pageNumber;var annotations=_getAnnotations(documentId);annotations.push(annotation);updateAnnotations(documentId,annotations);resolve(annotation);});},editAnnotation:function editAnnotation(documentId,annotationId,annotation){return new Promise(function(resolve,reject){var annotations=_getAnnotations(documentId);annotations[findAnnotation(documentId,annotationId)]=annotation;updateAnnotations(documentId,annotations);resolve(annotation);});},deleteAnnotation:function deleteAnnotation(documentId,annotationId){return new Promise(function(resolve,reject){var index=findAnnotation(documentId,annotationId);if(index>-1){var annotations=_getAnnotations(documentId);annotations.splice(index,1);updateAnnotations(documentId,annotations);}resolve(true);});},getComments:function getComments(documentId,annotationId){return new Promise(function(resolve,reject){resolve(_getAnnotations(documentId).filter(function(i){return i.class==='Comment'&&i.annotation===annotationId;}));});},addComment:function addComment(documentId,annotationId,content){return new Promise(function(resolve,reject){var comment={class:'Comment',uuid:(0,_uuid2.default)(),annotation:annotationId,content:content};var annotations=_getAnnotations(documentId);annotations.push(comment);updateAnnotations(documentId,annotations);resolve(comment);});},deleteComment:function deleteComment(documentId,commentId){return new Promise(function(resolve,reject){_getAnnotations(documentId);var index=-1;var annotations=_getAnnotations(documentId);for(var i=0,l=annotations.length;i-1){annotations.splice(index,1);updateAnnotations(documentId,annotations);}resolve(true);});}}));}return LocalStoreAdapter;}(_StoreAdapter3.default);
- exports.default=LocalStoreAdapter;
- function _getAnnotations(documentId){return JSON.parse(localStorage.getItem(documentId+'/annotations'))||[];}
- function updateAnnotations(documentId,annotations){localStorage.setItem(documentId+'/annotations',JSON.stringify(annotations));}
- function findAnnotation(documentId,annotationId){var index=-1;var annotations=_getAnnotations(documentId);for(var i=0,l=annotations.length;i div')));
- y=(0,_utils.scaleUp)(svg,{y:y}).y+rect.top;
- x=(0,_utils.scaleUp)(svg,{x:x}).x+rect.left;// Find the best node to insert before
- for(var i=0,l=nodes.length;i'){
- while(head.length){
- tail.unshift(head.pop());
- if(tail[0]==='<'){
- break;
+ })();
+
+ // Make toolbar responsive: Elements that can't be displayed in one row, are in a dropdown.
+ (function () {
+ // Set width as attribute because width of elements in dropdown is 0 if dropdown is collapsed.
+ $('#toolbarContent')
+ .children()
+ .each(function () {
+ $(this).attr('visibleWidth', $(this).outerWidth());
+ });
+
+ function responsiveToolbar() {
+ let changed = false;
+ do {
+ changed = false;
+ let lastElement = $('#toolbarContent').children(':not(.pdf-annotator-hidden)').last(); // Last visible element in toolbar.
+ let firstDropdownElement = $('#toolbar-dropdown-content').children().first(); // First element in dropdown.
+ let firstWidth = parseInt(firstDropdownElement.attr('visibleWidth')); // Width of first element in dropdown.
+ // If lastElem is displayed in a second row because screen isn't wide enough.
+ if (lastElement.offset().top > $('#toolbarContent').offset().top + 10) {
+ // Move last element (not dropdown-button) into dropdown and display button.
+ let toolbarElements = $('#toolbarContent').children(':not(#toolbar-dropdown-button)');
+ if (toolbarElements.length > 0) {
+ lastElement = toolbarElements.last();
+ $('#toolbar-dropdown-content').prepend(lastElement);
+ $('#toolbar-dropdown-button').removeClass('pdf-annotator-hidden');
+ changed = true;
+ }
+ // If there is enough space to display the next hidden element.
+ } else if (
+ firstDropdownElement.length !== 0 &&
+ lastElement.offset().left + lastElement.outerWidth() + firstWidth + 20 <
+ $('#toolbarContent').offset().left + $('#toolbarContent').width()
+ ) {
+ firstDropdownElement.insertBefore('#toolbar-dropdown-button'); // Move element from dropdown to toolbar.
+ // Hide button if all elements are shown.
+ if ($('#toolbar-dropdown-content').children().length === 0) {
+ $('#toolbar-dropdown-button').addClass('pdf-annotator-hidden');
+ }
+ changed = true;
}
- }
- }// Check if width of temp based on current head value satisfies x
- temp.innerHTML=head.join('');
- var width=(0,_utils.scaleDown)(svg,{width:temp.getBoundingClientRect().width}).width;
- if(left+width<=x){
- break;
- }
- tail.unshift(head.pop());
- }// Update original node with new markup, including element to be inserted
- node.innerHTML=head.join('')+el.outerHTML+tail.join('');temp.parentNode.removeChild(temp);return true;
- }/**
- * Get a text layer element at a given point on a page
- *
- * @param {Number} x The x coordinate of the point
- * @param {Number} y The y coordinate of the point
- * @param {Number} pageNumber The page to limit elements to
- * @return {Element} First text layer element found at the point
- */function textLayerElementFromPoint(x,y,pageNumber){
- var svg=document.querySelector('svg[data-pdf-annotate-page="'+pageNumber+'"]');
- var rect=svg.getBoundingClientRect();
- y=(0,_utils.scaleUp)(svg,{y:y}).y+rect.top;
- x=(0,_utils.scaleUp)(svg,{x:x}).x+rect.left;
- return[].concat(_toConsumableArray(svg.parentNode.querySelectorAll('.textLayer [data-canvas-width]'))).filter(function(el){return(0,_utils.pointIntersectsRect)(x,y,el.getBoundingClientRect());})[0];
- }
- module.exports=exports['default'];
- /***/},
- /* 25 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.default=renderScreenReaderComments;
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
- var _insertScreenReaderComment=__webpack_require__(26);
- var _insertScreenReaderComment2=_interopRequireDefault(_insertScreenReaderComment);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}/**
- * Insert the comments into the DOM to be available by screen reader
- *
- * Example output:
- *
- *
Begin highlight 1
- *
- * - Foo
- * - Bar
- * - Baz
- * - Qux
- *
- *
- * Some highlighted text goes here...
- * End highlight 1
- *
- * NOTE: `screenReaderOnly` is not a real class, just used for brevity
- *
- * @param {String} documentId The ID of the document
- * @param {String} annotationId The ID of the annotation
- * @param {Array} [comments] Optionally preloaded comments to be rendered
- * @return {Promise}
- */function renderScreenReaderComments(documentId,annotationId,comments){
- var promise=void 0;
- if(Array.isArray(comments)){
- promise=Promise.resolve(comments);
- }else{
- promise=_PDFJSAnnotate2.default.getStoreAdapter().getComments(documentId,annotationId);
- }
- return promise.then(function(comments){// Node needs to be found by querying DOM as it may have been inserted as innerHTML
- // leaving `screenReaderNode` as an invalid reference (see `insertElementWithinElement`).
- var node=document.getElementById('pdf-annotate-screenreader-'+annotationId);
- if(node){
- var list=document.createElement('ol');
- list.setAttribute('id','pdf-annotate-screenreader-comment-list-'+annotationId);
- list.setAttribute('aria-label','Comments');node.appendChild(list);
- // comments.forEach(_insertScreenReaderComment2.default);
-
- for (var i=0; i < comments.length; i++) {
- _insertScreenReaderComment2.default(comments[i]);
- }
-
- }});}
- module.exports=exports['default'];
- /***/},
- /* 26 */
- /***/function(module,exports){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.default=insertScreenReaderComment;/**
- * Insert a comment into the DOM to be available by screen reader
- *
- * @param {Object} comment The comment to be inserted
- */function insertScreenReaderComment(comment){if(!comment){return;}var list=document.querySelector('#pdf-annotate-screenreader-'+comment.annotation+' ol');if(list){var item=document.createElement('li');item.setAttribute('id','pdf-annotate-screenreader-comment-'+comment.uuid);item.appendChild(document.createTextNode(''+comment.content));list.appendChild(item);}}
- module.exports=exports['default'];
- /***/},
- /* 27 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.default=initEventHandlers;
- var _insertScreenReaderHint=__webpack_require__(21);
- var _insertScreenReaderHint2=_interopRequireDefault(_insertScreenReaderHint);
- var _renderScreenReaderHints=__webpack_require__(20);
- var _renderScreenReaderHints2=_interopRequireDefault(_renderScreenReaderHints);
- var _insertScreenReaderComment=__webpack_require__(26);
- var _insertScreenReaderComment2=_interopRequireDefault(_insertScreenReaderComment);
- var _renderScreenReaderComments=__webpack_require__(25);
- var _renderScreenReaderComments2=_interopRequireDefault(_renderScreenReaderComments);
- var _event=__webpack_require__(4);
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
-
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- /**
- * Initialize the event handlers for keeping screen reader hints synced with data
- */function initEventHandlers(){(0,_event.addEventListener)('annotation:add',function(documentId,pageNumber,annotation){reorderAnnotationsByType(documentId,pageNumber,annotation.type);});(0,_event.addEventListener)('annotation:edit',function(documentId,annotationId,annotation){reorderAnnotationsByType(documentId,annotation.page,annotation.type);});(0,_event.addEventListener)('annotation:delete',removeAnnotation);(0,_event.addEventListener)('comment:add',insertComments);(0,_event.addEventListener)('comment:delete',removeComment);}/**
- * Reorder the annotation numbers by annotation type
- *
- * @param {String} documentId The ID of the document
- * @param {Number} pageNumber The page number of the annotations
- * @param {Strig} type The annotation type
- */function reorderAnnotationsByType(documentId,pageNumber,type){_PDFJSAnnotate2.default.getStoreAdapter().getAnnotations(documentId,pageNumber).then(function(annotations){return annotations.annotations.filter(function(a){return a.type===type;});}).then(function(annotations){annotations.forEach(function(a){removeAnnotation(documentId,a.uuid);});return annotations;}).then(/*_renderScreenReaderHints2.default*/);}/**
- * Remove the screen reader hint for an annotation
- *
- * @param {String} documentId The ID of the document
- * @param {String} annotationId The Id of the annotation
- */function removeAnnotation(documentId,annotationId){removeElementById('pdf-annotate-screenreader-'+annotationId);removeElementById('pdf-annotate-screenreader-'+annotationId+'-end');}/**
- * Insert a screen reader hint for a comment
- *
- * @param {String} documentId The ID of the document
- * @param {String} annotationId The ID of tha assocated annotation
- * @param {Object} comment The comment to insert a hint for
- */function insertComments(documentId,annotationId,comment){
- var list=document.querySelector('pdf-annotate-screenreader-comment-list-'+annotationId);
- var promise=void 0;
- if(!list){
- promise=(0,_renderScreenReaderComments2.default)(documentId,annotationId,[]).then(function(){
- list=document.querySelector('pdf-annotate-screenreader-comment-list-'+annotationId);return true;
- });
- }
- else{
- promise=Promise.resolve(true);}promise.then(function(){
- (0,_insertScreenReaderComment2.default)(comment);
- });
- }/**
- * Remove a screen reader hint for a comment
- *
- * @param {String} documentId The ID of the document
- * @param {String} commentId The ID of the comment
- */function removeComment(documentId,commentId){removeElementById('pdf-annotate-screenreader-comment-'+commentId);}/**
- * Remove an element from the DOM by it's ID if it exists
- *
- * @param {String} elementID The ID of the element to be removed
- */function removeElementById(elementId){
- var el=document.getElementById(elementId);
- if(el){
- el.parentNode.removeChild(el);
- }
- }module.exports=exports['default'];
- /***/},
- /* 28 */ /* Combines the UI functions to export for parent-module 1 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- var _event=__webpack_require__(4);
- var _edit=__webpack_require__(29);
- var _pen=__webpack_require__(30);
- var _point=__webpack_require__(31);
- var _rect=__webpack_require__(32);
- var _text=__webpack_require__(33);
- var _page=__webpack_require__(34);
- var _pickAnno=__webpack_require__(37);
- var _questionsRenderer = __webpack_require__(38);
- var _shortText = __webpack_require__(39);
- var _newAnnotations = __webpack_require__(40);
- var _ajaxloader=__webpack_require__(36);
- var _commentWrapper=__webpack_require__(35);
- exports.default={addEventListener:_event.addEventListener,removeEventListener:_event.removeEventListener,fireEvent:_event.fireEvent,disableEdit:_edit.disableEdit,enableEdit:_edit.enableEdit,disablePen:_pen.disablePen,enablePen:_pen.enablePen,setPen:_pen.setPen,disablePoint:_point.disablePoint,enablePoint:_point.enablePoint,disableRect:_rect.disableRect,enableRect:_rect.enableRect,disableText:_text.disableText,enableText:_text.enableText,setText:_text.setText,createPage:_page.createPage,renderPage:_page.renderPage,showLoader:_ajaxloader.showLoader,hideLoader:_ajaxloader.hideLoader,pickAnnotation:_pickAnno.pickAnnotation, renderQuestions:_questionsRenderer.renderQuestions, renderAllQuestions: _questionsRenderer.renderAllQuestions, shortenTextDynamic:_shortText.shortenTextDynamic, mathJaxAndShortenText:_shortText.mathJaxAndShortenText, loadNewAnnotations : _newAnnotations.load, loadEditor: _commentWrapper.loadEditor};
- module.exports=exports['default'];
- /***/},
- /** 29 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- var _slicedToArray=function(){
- function sliceIterator(arr,i){
- var _arr=[];
- var _n=true;
- var _d=false;
- var _e=undefined;
- try{
- for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){
- _arr.push(_s.value);
- if(i&&_arr.length===i)break;
- }
- }catch(err){_d=true;_e=err;}
- finally{
- try{if(!_n&&_i["return"])_i["return"]();}
- finally{if(_d)throw _e;}
+ } while (changed);
}
- return _arr;
- }
- return function(arr,i){
- if(Array.isArray(arr)){
- return arr;
- }else if(Symbol.iterator in Object(arr)){
- return sliceIterator(arr,i);
- }else{
- throw new TypeError("Invalid attempt to destructure non-iterable instance");
- }
- };
- }();
- exports.enableEdit=enableEdit;
- exports.disableEdit=disableEdit;
- exports.createEditOverlay=createEditOverlay;
- exports.destroyEditOverlay = destroyEditOverlay;
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
- var _appendChild=__webpack_require__(11);
- var _appendChild2=_interopRequireDefault(_appendChild);
- var _event=__webpack_require__(4);
- var _utils=__webpack_require__(6);
- var _ajaxloader= __webpack_require__(36);
- var _renderPoint= __webpack_require__(17);
- var _questionsRenderer = __webpack_require__(38);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- function _toConsumableArray(arr){if(Array.isArray(arr)){for(var i=0,arr2=Array(arr.length);i -1;
}
- destroyEditOverlay();
- }
- isMoved = false;
- }
- /**
- * Handle document.keyup event
- *
- * @param {Event} e The DOM event that needs to be handled
- */function handleDocumentKeyup(e){
- if (overlay&&e.keyCode === 46 && !e.target.closest('.edit-comment-form') && !e.target.closest('.comment-list-form')) {
- deleteAnnotation();
- }
- }
- /**
- * Handle document.mousedown event
- *
- * @param {Event} e The DOM event that needs to be handled
- */function handleDocumentMousedown(e){
- if(e.target!==overlay){return;}// Highlight and strikeout annotations are bound to text within the document.
- // It doesn't make sense to allow repositioning these types of annotations.
- var annotationId=overlay.getAttribute('data-target-id');
- var target=document.querySelector('[data-pdf-annotate-id="'+annotationId+'"]');
- var type=target.getAttribute('data-pdf-annotate-type');
- if(type==='highlight' || type==='strikeout'){
- return;
- }
- isDragging=true;
- dragOffsetX=e.clientX;
- dragOffsetY=e.clientY;
- dragStartX=overlay.offsetLeft;
- dragStartY=overlay.offsetTop;
- overlay.style.background='rgba(255, 255, 255, 0.7)';
- overlay.style.setProperty('cursor', 'move', 'important');
- overlay.querySelector('a').style.display='none';
- document.addEventListener('mousemove', handleDocumentMousemove);
- document.addEventListener('mouseup', handleDocumentMouseup);
- (0,_utils.disableUserSelect)();
- }/**
- * Handle document.mousemove event
- *
- *
- * @param {Event} e The DOM event that needs to be handled
- */function handleDocumentMousemove(e){
- var annotationId=overlay.getAttribute('data-target-id');
- var parentNode=overlay.parentNode;
- var rect=parentNode.getBoundingClientRect();
- var y=dragStartY+(e.clientY-dragOffsetY);
- var x=dragStartX+(e.clientX-dragOffsetX);
- var minY=0;
- var maxY=rect.height;
- var minX=0;
- var maxX=rect.width;
- if(y>minY&&y+overlay.offsetHeightminX&&x+overlay.offsetWidth-1){
- (function(){
- var _getDelta=getDelta('x','y');
- var deltaX=_getDelta.deltaX;
- var deltaY=_getDelta.deltaY;
- [].concat(_toConsumableArray(target)).forEach(function(t,i){
- // adjust y coordinate if necessary
- if(deltaY!==0){
- var modelY=parseInt(t.getAttribute('y'),10)+deltaY;
- viewY=modelY;
- if(type==='point'){
- //+SIZE, because the pin should not be rendered right under the click point, instead it should be rendered centered above the click point
- modelY += SIZE;
- }
- if(type==='textbox'){
- viewY+=parseInt(annotation['annotation'].size,10);
- }if(type==='point' && !isFirefox){
- viewY=(0,_utils.scaleUp)(svg,{viewY:viewY}).viewY;
- }
- if(isFirefox){
- viewY -= 6;
- }
- if(annotation.rectangles){
- annotation.rectangles[i].y=modelY;
- }else {
- annotation['annotation'].y=modelY; // .toString();
- }
- }
- // adjust x coordinate if necessary
- if(deltaX!==0){
- var modelX=parseInt(t.getAttribute('x'),10)+deltaX;
- viewX=modelX;
- //+(1/4)Size, because the pin should be rendered centered of the click point not on the righthand side.
- if(type==='point'){
- modelX += (SIZE/4);
- }
- if(type==='point' && !isFirefox){
- viewX=(0,_utils.scaleUp)(svg,{viewX:viewX}).viewX;
+ /*
+ * Function inserts a comment into the HTML DOM for display.
+ * A comment consists of its content as well as a delete button, wrapped up in a shared div.
+ *
+ * @return {Element}
+ */
+ function insertComments(comments, markCommentid = undefined) {
+ if (!comments) {
+ return false;
+ }
+ if (!comments.comments) {
+ comments = { comments: [comments] };
+ }
- }
- if(isFirefox ){
- viewX -= 6;
- }
- //t.setAttribute('x',viewX);
- if(annotation.rectangles){
- annotation.rectangles[i].x=modelX;
- } else {
- annotation['annotation'].x = modelX; // .toString();
- }
+ (function (templates, data) {
+ if (data.comments[0] !== false) {
+ templates
+ .render('mod_pdfannotator/comment', data)
+ .then(function (html, js) {
+ if (data.comments.length === 1 && !data.comments[0].isquestion) {
+ $('.comment-list-container').append(html);
+ } else {
+ templates.replaceNodeContents('.comment-list-container', html, js);
}
- });
- })();
- } else if(type==='drawing'){
- (function(){
- var rect=(0,_utils.scaleDown)(svg,(0,_utils.getAnnotationRect)(target[0]));
+ })
+ .then(function () {
+ data.comments.forEach(function (comment) {
+ createVoteHandler(comment);
+ createEditFormHandler(comment);
+ createSubscriptionHandler(comment);
+ createHideHandler(comment);
+ createDeleteHandler(comment);
+ createSolvedHandler(comment);
+ let pattern = $('#searchPattern').val();
+ if (
+ pattern !== '' &&
+ comment.content.search(new RegExp(pattern, 'i')) !== -1
+ ) {
+ $('#comment_' + comment.uuid).addClass('mark');
+ }
- var _annotation$lines$=_slicedToArray(annotation['annotation'].lines[0],2);
+ let selector = '#comment_' + comment.uuid + ' .chat-message-text p';
+ let element = document.querySelector(selector);
+ //renderMathJax(element);
+ });
- var originX=_annotation$lines$[0];
- var originY=_annotation$lines$[1];
+ //if the target has the attribute markCommentid a specific comment should be marked with an red border.
+ //after 3 sec the border should disappear.
+ if (markCommentid !== undefined && markCommentid !== null) {
+ $('#comment_' + markCommentid).addClass('mark');
+ markCommentid = undefined;
+ setTimeout(function () {
+ if (document.querySelector('#comment_' + markCommentid)) {
+ document.querySelector('#comment_' + markCommentid).style.border =
+ 'none';
+ }
+ }, 3000);
+ }
+ })
+ .catch(notification.exception);
+ }
+ })(templates, comments);
+ return true;
+ }
- var _calcDelta=calcDelta(originX,originY);
+ function createSolvedHandler(comment) {
+ var button = $('#comment_' + comment.uuid + ' .comment-solve-a');
+ var i = $('#comment_' + comment.uuid + ' .comment-solve-a i');
+ var span = $('#comment_' + comment.uuid + ' .comment-solve-a span.menu-action-text');
+ var img = $('#comment_' + comment.uuid + ' .comment-solve-a img');
+ button.click(function (e) {
+ _2.default.getStoreAdapter().markSolved(RENDER_OPTIONS.documentId, comment);
+ });
+ }
- var deltaX=_calcDelta.deltaX;
+ function createSubscriptionHandler(comment) {
+ var button = $('#comment_' + comment.uuid + ' .comment-subscribe-a');
+ var i = $('#comment_' + comment.uuid + ' .comment-subscribe-a i');
+ var span = $('#comment_' + comment.uuid + ' .comment-subscribe-a span.menu-action-text');
+ button.click(function (e) {
+ if (comment.issubscribed) {
+ _2.default
+ .getStoreAdapter()
+ .unsubscribeQuestion(RENDER_OPTIONS.documentId, comment.annotation)
+ .then(function (data) {
+ if (data.status === 'success') {
+ notification.addNotification({
+ message: M.util.get_string('successfullyUnsubscribed', 'pdfannotator'),
+ type: 'success',
+ });
+ setTimeoutNotification();
+ } else if (data.status == 'error') {
+ notification.addNotification({
+ message: M.util.get_string('error:unsubscribe', 'pdfannotator'),
+ type: 'error',
+ });
+ console.error(M.util.get_string('error:unsubscribe', 'pdfannotator'));
+ }
+ span.text(M.util.get_string('subscribeQuestion', 'pdfannotator'));
+ });
+ } else {
+ _2.default
+ .getStoreAdapter()
+ .subscribeQuestion(RENDER_OPTIONS.documentId, comment.annotation)
+ .then(function (data) {
+ if (data.status === 'success') {
+ notification.addNotification({
+ message: M.util.get_string('successfullySubscribednotify', 'pdfannotator'),
+ type: 'success',
+ });
+ setTimeoutNotification();
+ } else if (data.status == 'error') {
+ notification.addNotification({
+ message: M.util.get_string('error:subscribe', 'pdfannotator'),
+ type: 'error',
+ });
+ console.error(M.util.get_string('error:subscribe', 'pdfannotator'));
+ }
+ span.text(M.util.get_string('unsubscribeQuestion', 'pdfannotator'));
+ });
+ }
+ comment.issubscribed = !comment.issubscribed;
+ i.toggleClass('fa-bell');
+ i.toggleClass('fa-bell-slash');
+ });
+ }
- var deltaY=_calcDelta.deltaY;// origin isn't necessarily at 0/0 in relation to overlay x/y
- // adjust the difference between overlay and drawing coords
+ function createVoteHandler(comment) {
+ // Create an element for click.
+ var likeButton = $('#comment_' + comment.uuid + ' .comment-like-a');
+ if (comment.isdeleted == 1 || !comment.usevotes) {
+ likeButton.attr('disabled', 'disabled');
+ likeButton.css('visibility', 'hidden');
+ } else if (comment.userid == _userid || comment.isvoted) {
+ likeButton.attr('disabled', 'disabled');
+ }
- deltaY+=originY-rect.top;
- deltaX+=originX-rect.left;
+ likeButton.click(function (e) {
+ _2.default
+ .getStoreAdapter()
+ .voteComment(RENDER_OPTIONS.documentId, comment.uuid)
+ .then(function (data) {
+ if (data.status == 'error') {
+ notification.addNotification({
+ message: M.util.get_string('error:voteComment', 'pdfannotator'),
+ type: 'error',
+ });
+ console.error(M.util.get_string('error:voteComment', 'pdfannotator'));
+ } else {
+ // Update number of votes and disable button.
+ var voteDiv = document.querySelector(
+ 'div#comment_' + comment.uuid + ' div.wrappervotessolved'
+ );
+ var button = voteDiv.querySelector('button');
+ var img = button.querySelector('i');
+ var div = voteDiv.querySelector('.countVotes');
+
+ button.disabled = true;
+ div.innerHTML = data.numberVotes;
+ if (comment.isquestion == 1) {
+ button.title = M.util.get_string('likeQuestionForbidden', 'pdfannotator'); //button
+ img.title = M.util.get_string('likeQuestionForbidden', 'pdfannotator'); //img
+ img.alt = M.util.get_string('likeQuestionForbidden', 'pdfannotator'); //img
+ div.title =
+ data.numberVotes +
+ ' ' +
+ M.util.get_string('likeCountQuestion', 'pdfannotator');
+ } else {
+ button.title = M.util.get_string('likeAnswerForbidden', 'pdfannotator');
+ img.title = M.util.get_string('likeAnswerForbidden', 'pdfannotator'); //img
+ img.alt = M.util.get_string('likeAnswerForbidden', 'pdfannotator'); //img
+ div.title =
+ data.numberVotes +
+ ' ' +
+ M.util.get_string('likeCountAnswer', 'pdfannotator');
+ }
+ }
+ });
+ });
+ }
- annotation['annotation'].lines.forEach(function(line,i){
- var _annotation$lines$i=_slicedToArray(annotation['annotation'].lines[i],2);
- var x=_annotation$lines$i[0];
- var y=_annotation$lines$i[1];
- annotation['annotation'].lines[i][0]=(0,_utils.roundDigits)(x+deltaX,4);
- annotation['annotation'].lines[i][1]=(0,_utils.roundDigits)(y+deltaY,4);
- });
- })();
+ /**
+ * Function enables managers to hide a comment from participants
+ * or to display it to participants once more.
+ *
+ * @param {type} comment
+ * @returns {undefined}
+ */
+ function createHideHandler(comment) {
+ var button = $('#hideButton' + comment.uuid);
+
+ button.click(function (e) {
+ var icon = button.children().first();
+ var menutext = button.children().last();
+ if (comment.ishidden) {
+ _2.default.getStoreAdapter().redisplayComment(RENDER_OPTIONS.documentId, comment.uuid);
+ menutext.html(M.util.get_string('markhidden', 'pdfannotator'));
+ } else {
+ _2.default.getStoreAdapter().hideComment(RENDER_OPTIONS.documentId, comment.uuid);
+ menutext.html(M.util.get_string('removehidden', 'pdfannotator'));
}
- (function editAnnotation(){
- if(!overlay){
- return;
- }
- if(dragStartX === viewX && dragStartY === viewY) {
- return;
- }
- annoId=overlay.getAttribute('data-target-id');
- notification.confirm(M.util.get_string('editAnnotationTitle','pdfannotator'),M.util.get_string('editAnnotation','pdfannotator'),M.util.get_string('yesButton', 'pdfannotator'), M.util.get_string('cancelButton', 'pdfannotator'), editAnnotationCallback, overlayToOldPlace);
-
- })();
-
- function overlayToOldPlace() {
- // Overlay back to old place.
- overlay.style.top = overlayOld.x;
- overlay.style.left = overlayOld.y;
- // Show comments.
- _event.fireEvent('annotation:click',target[0]);
+ comment.ishidden = !comment.ishidden;
+ icon.toggleClass('fa-eye');
+ icon.toggleClass('fa-eye-slash');
+ });
}
+
/**
- * Is called if the user confirms to move the annotation.
- * This function destroys the annotation and deletes it from the database
+ * Function handles opening/closing and submitting the edit comment form.
+ * @param {type} comment
* @returns {undefined}
*/
- function editAnnotationCallback(){
- _PDFJSAnnotate2.default.getStoreAdapter().editAnnotation(documentId,pageNumber,annotationId,annotation).then(function(success){
- (0,_ajaxloader.hideLoader)();
- if(!success) {
- overlayToOldPlace();
+ function createEditFormHandler(comment) {
+ // Create an element for click.
+ var editButton = $('#editButton' + comment.uuid);
+ // Add an event handler to the click element that opens a textarea and fills it with the current comment.
+ editButton.click(function (e) {
+ UI.loadEditor('edit', comment.uuid, handleClickIfEditorExists);
+ function handleClickIfEditorExists() {
+ // Add an event handler to the form for submitting any changes to the database.
+ let editForm = document.getElementById(`edit${comment.uuid}`);
+ editForm.onsubmit = function (e) {
+ let editTextarea = document.getElementById(`editarea${comment.uuid}`);
+ let editAreaEditable = document.getElementById(`editarea${comment.uuid}editable`);
+ let chatMessage = document.getElementById(`chatmessage${comment.uuid}`);
+
+ let newContent = editTextarea.value.trim(); // If atto editor is used.
+ var iframe = document.getElementById('myarea_ifr'); // If tinymce editor is used.
+ if (iframe) {
+ let editorArea = iframe.contentWindow.document.getElementById('tinymce');
+ newContent = editorArea.innerHTML;
+ }
+ if (newContent.length === 0) {
+ // Should be more than one character, otherwise it should not be saved.
+ notification.addNotification({
+ message: M.util.get_string('min0Chars', 'pdfannotator'),
+ type: 'error',
+ });
+ } else if (newContent === comment.displaycontent) {
+ // No changes.
+ editForm.style.display = 'none';
+ chatMessage.innerHTML = comment.displaycontent;
+ //renderMathJax(chatMessage);
+ } else {
+ // Save changes.
+ _2.default
+ .getStoreAdapter()
+ .editComment(documentId, comment.uuid, newContent, editForm)
+ .then(function (data) {
+ if (data.status === 'success') {
+ editForm.style.display = 'none';
+ $(`edit_comment_editor_wrapper_${comment.uuid}`).remove();
+ if (data.modifiedby) {
+ $('#comment_' + comment.uuid + ' .edited').html(
+ M.util.get_string('editedComment', 'pdfannotator') +
+ ' ' +
+ data.timemodified +
+ ' ' +
+ M.util.get_string('modifiedby', 'pdfannotator') +
+ ' ' +
+ data.modifiedby
+ );
+ } else {
+ $('#comment_' + comment.uuid + ' .edited').html(
+ M.util.get_string('editedComment', 'pdfannotator') +
+ ' ' +
+ data.timemodified
+ );
+ }
+ newContent = data.newContent;
+ chatMessage.innerHTML = newContent;
+ comment.content = newContent;
+ comment.displaycontent = newContent;
+ editTextarea = newContent;
+ //renderMathJax(chatMessage);
+ notification.addNotification({
+ message: M.util.get_string(
+ 'successfullyEdited',
+ 'pdfannotator'
+ ),
+ type: 'success',
+ });
+ setTimeoutNotification();
+ } else {
+ notification.addNotification({
+ message: M.util.get_string('error:editComment', 'pdfannotator'),
+ type: 'error',
+ });
+ }
+ });
+ }
+ setTimeout(function () {
+ let notificationpanel = document.getElementById('user-notifications');
+ while (notificationpanel.hasChildNodes()) {
+ notificationpanel.removeChild(notificationpanel.firstChild);
+ }
+ }, 4000);
- // Notification, that the annotation could not be edited.
- notification.addNotification({
- message: M.util.get_string('editNotAllowed','pdfannotator'),
- type: "error"
+ return false; // Prevents normal POST and page reload in favour of an asynchronous load.
+ };
+
+ let cancelBtn = $('#comment_' + comment.uuid + ' #commentCancel');
+ cancelBtn.click(function (e) {
+ let editTextarea = document.getElementById(`editarea${comment.uuid}`);
+ let editAreaEditable = document.getElementById(`editarea${comment.uuid}editable`);
+ let chatMessage = document.getElementById(`chatmessage${comment.uuid}`);
+ editForm.style.display = 'none';
+ editTextarea.innerHTML = '';
+ editTextarea.innerHTML = comment.displaycontent;
+ if (editAreaEditable) {
+ // Only exists for atto editor, not tinymce.
+ editAreaEditable.innerHTML = '';
+ editAreaEditable.innerHTML = comment.displaycontent;
+ }
+ chatMessage.innerHTML = comment.displaycontent;
+ //renderMathJax(chatMessage);
});
- setTimeout(function(){
- let notificationpanel = document.getElementById("user-notifications");
- while (notificationpanel.hasChildNodes()) {
- notificationpanel.removeChild(notificationpanel.firstChild);
- }
- }, 4000);
- }else{
- if(['area','point','textbox'].indexOf(type)>-1){
- (function(){
- [].concat(_toConsumableArray(target)).forEach(function(t,i){
- t.setAttribute('y',viewY);
- t.setAttribute('x',viewX);
- });
- })();
- }else if(type==='drawing'){
- target[0].parentNode.removeChild(target[0]);
- (0,_appendChild2.default)(svg,annotation['annotation']);
- }
- //_renderPoint(annotation['annotation']);
- _event.fireEvent('annotation:click',target[0]);
}
- }, function (err){
- overlayToOldPlace();
-
- notification.addNotification({
- message: M.util.get_string('error:editAnnotation','pdfannotator'),
- type: "error"
- });
});
-
}
- }, function (err){
- notification.addNotification({
- message: M.util.get_string('error:getAnnotation','pdfannotator'),
- type: "error"
- });
- });
-// getComments(_fileid, annotationId);
- setTimeout(function(){isDragging=false;},0);
- overlay.style.background='';
- overlay.style.cursor='';
- document.removeEventListener('mousemove',handleDocumentMousemove);
- document.removeEventListener('mouseup',handleDocumentMouseup);
- (0,_utils.enableUserSelect)();
- }
-
- /**
- * Handle annotation.click event
- *
- * @param {Element} e The annotation element that was clicked
- */function handleAnnotationClick(target){
- if(isDragging){
- return;
- }
- createEditOverlay(target);
- }/**
- * Enable edit mode behavior.
- */function enableEdit(){
- if(_enabled){return;}
- _enabled=true;
- document.getElementById('content-wrapper').classList.add('cursor-edit');
- (0,_event.addEventListener)('annotation:click',handleAnnotationClick);
- };/**
- * Disable edit mode behavior.
- */function disableEdit(){
- destroyEditOverlay();
- if(!_enabled){return;}
- _enabled=false;document.getElementById('content-wrapper').classList.remove('cursor-edit');(0,_event.removeEventListener)('annotation:click',handleAnnotationClick);
- };
- /***/},
- /* 30 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.setPen=setPen;
- exports.enablePen=enablePen;
- exports.disablePen=disablePen;
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
- var _appendChild=__webpack_require__(11);
- var _appendChild2=_interopRequireDefault(_appendChild);
- var _utils=__webpack_require__(6);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- var _enabled=false;
- var _penSize=void 0;
- var _penColor=void 0;
- var path=void 0;
- var lines=void 0;
- var _svg=void 0;/**
-
- * Handle document.mousedown event
- */function handleDocumentMousedown(){
- path=null;
- lines=[];
- document.addEventListener('mousemove',handleDocumentMousemove);
- document.addEventListener('mouseup',handleDocumentMouseup);
- }
- /**
- * Handle document.mouseup event
- *
- * @param {Event} e The DOM event to be handled
- */function handleDocumentMouseup(e){
- var svg=void 0;
- if(lines.length>1&&(svg=(0,_utils.findSVGAtPoint)(e.clientX,e.clientY))){
- var _getMetadata=(0,_utils.getMetadata)(svg);
- var documentId=_getMetadata.documentId;
- var pageNumber=_getMetadata.pageNumber;
- _PDFJSAnnotate2.default.getStoreAdapter().addAnnotation(documentId,pageNumber,{type:'drawing',width:_penSize,color:_penColor,lines:lines})
- .then(function(annotation){
- if(path){svg.removeChild(path);}
- (0,_appendChild2.default)(svg,annotation);
- }, function (err){
- // Remove path
- if(path){svg.removeChild(path);}
- notification.addNotification({
- message: M.util.get_string('error:addAnnotation','pdfannotator'),
- type: "error"
- });
- });
- }
- document.removeEventListener('mousemove',handleDocumentMousemove);
- document.removeEventListener('mouseup',handleDocumentMouseup);
- }/**
- * Handle document.mousemove event
- *
- * @param {Event} e The DOM event to be handled
- */function handleDocumentMousemove(e){
- savePoint(e.clientX,e.clientY);}/**
- * Handle document.keyup event
- *
- * @param {Event} e The DOM event to be handled
- */function handleDocumentKeyup(e){// Cancel rect if Esc is pressed
- if(e.keyCode===27){
- lines=null;
- path.parentNode.removeChild(path);
- document.removeEventListener('mousemove',handleDocumentMousemove);
- document.removeEventListener('mouseup',handleDocumentMouseup);
- }
- }/**
- * Save a point to the line being drawn.
- *
- * @param {Number} x The x coordinate of the point
- * @param {Number} y The y coordinate of the point
- */
- function savePoint(x,y){
- var svg=(0,_utils.findSVGAtPoint)(x,y);
- if(!svg){return;}
- var rect=svg.getBoundingClientRect();
- var point=(0,_utils.scaleDown)(svg,{x:(0,_utils.roundDigits)(x-rect.left,4),y:(0,_utils.roundDigits)(y-rect.top,4)});
- lines.push([point.x,point.y]);
- if(lines.length<=1){return;}
- if(path){svg.removeChild(path);}
- path=(0,_appendChild2.default)(svg,{type:'drawing',color:_penColor,width:_penSize,lines:lines});
- }
- function handleContentTouchstart(e) {
- path=null;
- lines=[];
- _svg = (0, _utils.findSVGAtPoint)(e.touches[0].clientX, e.touches[0].clientY);
- saveTouchPoint(e.touches[0].clientX,e.touches[0].clientY);
- }
- function handleContentTouchmove(e) {
- e.preventDefault();
- saveTouchPoint(e.touches[0].clientX,e.touches[0].clientY);
- }
- function handleContentTouchend(e) {
- if (lines.length > 1){
- var _getMetadata=(0,_utils.getMetadata)(_svg);
- var documentId=_getMetadata.documentId;
- var pageNumber=_getMetadata.pageNumber;
- _PDFJSAnnotate2.default.getStoreAdapter().addAnnotation(documentId,pageNumber,{type:'drawing',width:_penSize,color:_penColor,lines:lines})
- .then(function(annotation){
- if(path){_svg.removeChild(path);}
- (0,_appendChild2.default)(_svg,annotation);
- }, function (err){
- // Remove path
- if(path){_svg.removeChild(path);}
- notification.addNotification({
- message: M.util.get_string('error:addAnnotation','pdfannotator'),
- type: "error"
- });
- });
- }
- }
- function handleContentTouchcancel(e) {
- lines=null;
- path.parentNode.removeChild(path);
- }
-
- /* Save a touchpoint to the line being drawn.
- *
- * @param {Number} x The x coordinate of the point
- * @param {Number} y The y coordinate of the point
- */function saveTouchPoint(x,y){
- if(!_svg){return;}
- var rect=_svg.getBoundingClientRect();
- var point=(0,_utils.scaleDown)(_svg,{x:(0,_utils.roundDigits)(x-rect.left,4),y:(0,_utils.roundDigits)(y-rect.top,4)});
- lines.push([point.x,point.y]);
- if(lines.length<=1){return;}
- if(path){_svg.removeChild(path);}
- path=(0,_appendChild2.default)(_svg,{type:'drawing',color:_penColor,width:_penSize,lines:lines});
- }
-
- /**
- * Set the attributes of the pen.
- *
- * @param {Number} penSize The size of the lines drawn by the pen
- * @param {String} penColor The color of the lines drawn by the pen
- */function setPen(){var penSize=arguments.length<=0||arguments[0]===undefined?1:arguments[0];var penColor=arguments.length<=1||arguments[1]===undefined?'000000':arguments[1];_penSize=parseInt(penSize,10);_penColor=penColor;}/**
- * Enable the pen behavior
- */function enablePen(){
- if(_enabled){
- return;
- }
- _enabled=true;
- var contentWrapper = document.getElementById('content-wrapper');
- contentWrapper.classList.add('cursor-pen');
- document.addEventListener('mousedown',handleDocumentMousedown);
- document.addEventListener('keyup',handleDocumentKeyup);
- contentWrapper.addEventListener('touchstart',handleContentTouchstart);
- contentWrapper.addEventListener('touchmove',handleContentTouchmove);
- contentWrapper.addEventListener('touchend',handleContentTouchend);
- contentWrapper.addEventListener('touchcancel',handleContentTouchcancel);
- (0,_utils.disableUserSelect)();
- }/**
- * Disable the pen behavior
- */function disablePen(){
- if(!_enabled){
- return;
- }
- _enabled=false;
- var contentWrapper = document.getElementById('content-wrapper');
- contentWrapper.classList.remove('cursor-pen');
- document.removeEventListener('mousedown',handleDocumentMousedown);
- document.removeEventListener('keyup',handleDocumentKeyup);
- contentWrapper.removeEventListener('touchstart',handleContentTouchstart);
- contentWrapper.removeEventListener('touchmove',handleContentTouchmove);
- contentWrapper.removeEventListener('touchend',handleContentTouchend);
- contentWrapper.removeEventListener('touchcancel',handleContentTouchcancel);
- (0,_utils.enableUserSelect)();
- }
- /***/},
- /* 31 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- var _typeof=typeof Symbol==="function"&&_typeof2(Symbol.iterator)==="symbol"?function(obj){return typeof obj==='undefined'?'undefined':_typeof2(obj);}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol?"symbol":typeof obj==='undefined'?'undefined':_typeof2(obj);};
- exports.enablePoint=enablePoint;
- exports.disablePoint=disablePoint;
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
- var _appendChild=__webpack_require__(11);
- var _appendChild2=_interopRequireDefault(_appendChild);
- var _utils=__webpack_require__(6);
- var _commentWrapper = __webpack_require__(35);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- var _enabled=false;
- var data=void 0;
- var _svg=void 0;
- var _rect=void 0;
- var dragging=false;
- //Test
- var textarea = void 0;
- var submitbutton = void 0;
- var form = void 0;
- var annotationObj;
- var documentId = -1;
- var pageNumber = 1;
-
- /**
- * Handle document.mouseup event
- *
- * @param {Event} The DOM event to be handled
- */function handleDocumentMouseup(e){
- //if the click is in comment wrapper area nothing should happen.
- var commentWrapperNodes = document.querySelectorAll('div#comment-wrapper')[0];
- var clickedElement;
- if(e.target.id) {
- clickedElement = '#' + e.target.id;
- } else if(e.target.className[0]) {
- clickedElement = '.' + e.target.className;
- } else {
- clickedElement = '';
- }
- if(clickedElement && commentWrapperNodes.querySelector(clickedElement)) {
- return;
- }
-
- //If Modal Dialogue beeing clicked.
- var clickedMoodleDialogue = e.target.closest('.moodle-dialogue-base');
- if(clickedMoodleDialogue) {
- return;
- }
+ /**
+ * This function creates an Node-Element for deleting the comment.
+ * @param {type} comment The comment-object for which the deletebutton is.
+ * @returns {Element|startIndex.indexstartIndex#L#26.indexstartIndex#L#26#L#72.indexstartIndex#L#26#L#72#L#743.createDeleteButton.deleteSpan}
+ */
+ function createDeleteHandler(comment) {
+ var button = $('#comment_' + comment.uuid + ' .comment-delete-a');
+ button.click(function (e) {
+ var confirmDelete = '';
+ if (comment.isquestion == 1) {
+ if (_capabilities.deleteany) {
+ confirmDelete = M.util.get_string('deletingQuestion_manager', 'pdfannotator');
+ } else {
+ confirmDelete = M.util.get_string('deletingQuestion_student', 'pdfannotator');
+ }
+ } else {
+ confirmDelete = M.util.get_string('deletingComment', 'pdfannotator');
+ }
+ var deleteCallback = function () {
+ dialogCallbackForDelete.call(this, comment);
+ };
+ notification.confirm(
+ M.util.get_string('deletingCommentTitle', 'pdfannotator'),
+ confirmDelete,
+ M.util.get_string('yesButton', 'pdfannotator'),
+ M.util.get_string('cancelButton', 'pdfannotator'),
+ deleteCallback,
+ null
+ );
+ });
- //if the click is on the Commentlist nothing should happen.
- if(((typeof e.target.getAttribute('id')=='string') && e.target.id.indexOf('comment') !== -1) || e.target.className.indexOf('comment') !== -1 || e.target.parentNode.className.indexOf('comment') !== -1 || e.target.parentNode.className.indexOf('chat') !== -1 || e.target.tagName == 'INPUT' || e.target.tagName == 'LABEL'){
- return;
- }
- _svg = (0,_utils.findSVGAtPoint)(e.clientX,e.clientY);
- if(!_svg){
- return;
- }
- var _getMetadata=(0,_utils.getMetadata)(_svg);
- documentId=_getMetadata.documentId;
- pageNumber=_getMetadata.pageNumber;
- deleteUndefinedPin();
- var fn = () => {
- [textarea,data] = (0,_commentWrapper.openComment)(e,handleCancelClick,handleSubmitClick,handleToolbarClick,handleSubmitBlur,'pin');
- renderPin();
- }
- _commentWrapper.loadEditor('add', 0, fn);
- }
-
- // Reset dragging to false.
- function handleContentTouchstart(e){
- dragging = false;
- }
- // Set dragging to true, so we stop the handleContentTouchend function from running.
- function handleContentTouchmove(e){
- dragging = true;
- }
- /**
- * Handle content.touchend event
- *
- * @param {Event} The DOM event to be handled
- */function handleContentTouchend(e){
- // If the mobile user was scrolling return from this function.
- if (dragging) {
- return;
- }
- //if the click is on the Commentlist nothing should happen.
- if(((typeof e.target.getAttribute('id')=='string') && e.target.id.indexOf('comment') !== -1) || e.target.className.indexOf('comment') !== -1 || e.target.parentNode.className.indexOf('comment') !== -1 || e.target.parentNode.className.indexOf('chat') !== -1 || e.target.tagName == 'INPUT' || e.target.tagName == 'LABEL'){
- return;
- }
- let svg = (0,_utils.findSVGAtPoint)(e.changedTouches[0].clientX,e.changedTouches[0].clientY);
- if(!svg){
- return;
- }
- var _getMetadata=(0,_utils.getMetadata)(svg);
- documentId=_getMetadata.documentId;
- pageNumber=_getMetadata.pageNumber;
- deleteUndefinedPin();
- var coordinates = {x: e.changedTouches[0].clientX, y: e.changedTouches[0].clientY};
- renderPinTouchscreen(coordinates);
- [textarea,data] = (0,_commentWrapper.openCommentTouchscreen)(e,handleCancelClick,handleSubmitClick,handleToolbarClick,handleSubmitBlur,'pin');
- }
-
- /**
- * If the toolbar is clicked, the point tool should be disabled and the commentswrapper should be closed
- * @param {type} e
- * @returns {undefined}
- */
- function handleToolbarClick(e){
- disablePoint();
- document.querySelector('.toolbar').removeEventListener('click',handleToolbarClick);
-
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,false);
- deleteUndefinedPin();
- textarea = void 0;
- }
-
- function handleSubmitClick(e){
- savePoint(_svg);
- return false;
- }
- function handleCancelClick(e){
- textarea = void 0;
- //delete the temporay rendered Pin
- deleteUndefinedPin();
- enablePoint();
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,false);
- }
- function handleSubmitBlur(){
- disablePoint();
- textarea = void 0;
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,false);
- }
- /**
- * Handle input.blur event
- */function handleInputBlur(){/*disablePoint();*/savePoint();}/**
- * Handle input.keyup event
- *
- * @param {Event} e The DOM event to handle
- */function handleInputKeyup(e){if(e.keyCode===27){disablePoint();closeInput();}else if(e.keyCode===13){/*disablePoint();*/savePoint();}}
-
- function renderPin(){
- var clientX=(0,_utils.roundDigits)(data.x,4);
- var clientY=(0,_utils.roundDigits)(data.y,4);
- var content=textarea.value.trim();
- var svg=(0,_utils.findSVGAtPoint)(clientX,clientY);
- if(!svg){
- return{v:void 0};
- }
- _rect=svg.getBoundingClientRect();
- var annotation = initializeAnnotation(_rect,svg);
- annotationObj = annotation;
- annotation.color = true;
- (0,_appendChild2.default)(svg,annotation);
- }
- function renderPinTouchscreen(coordinates){
- var clientX=(0,_utils.roundDigits)(coordinates.x,4);
- var clientY=(0,_utils.roundDigits)(coordinates.y,4);
- var svg=(0,_utils.findSVGAtPoint)(clientX,clientY);
- if(!svg){
- return{v:void 0};
- }
- _rect=svg.getBoundingClientRect();
- var annotation = initializeAnnotationTouchscreen(_rect,svg,coordinates);
- annotationObj = annotation;
- annotation.color = true;
- (0,_appendChild2.default)(svg,annotation);
- }
-
- /**
- * This function deletes all annotations which data-pdf-annotate-id is undefined. An annotation is undefined, if it is only temporarily displayed.
- * @returns {undefined}
- */
- function deleteUndefinedPin(){
- let n = document.querySelector('[data-pdf-annotate-id="undefined"]');
- if(n){
- n.parentNode.removeChild(n);
- }
- }
-
- function initializeAnnotation(rect,svg){
- var clientX=(0,_utils.roundDigits)(data.x,4);
- var clientY=(0,_utils.roundDigits)(data.y,4);
- return Object.assign({type:'point'},(0,_utils.scaleDown)(svg,{x:clientX-((0,_utils.roundDigits)(rect.left,4)),y:clientY-((0,_utils.roundDigits)(rect.top,4))}));
- }
- function initializeAnnotationTouchscreen(rect,svg,coordinates){
- var clientX=(0,_utils.roundDigits)(coordinates.x,4);
- var clientY=(0,_utils.roundDigits)(coordinates.y,4);
- return Object.assign({type:'point'},(0,_utils.scaleDown)(svg,{x:clientX-((0,_utils.roundDigits)(rect.left,4)),y:clientY-((0,_utils.roundDigits)(rect.top,4))}));
- }
- /**
- * Save a new point annotation from input
- */
- function savePoint(svg = null){
- if(textarea.value.trim().length > 0){
- disablePoint();
- var page = pageNumber;
- if (!svg) {
- var elements=document.querySelectorAll('svg[data-pdf-annotate-container="true"]');
- var svg=elements[page-1];
- }
- var _ret=function(){
- var clientX=(0,_utils.roundDigits)(data.x,4);
- var clientY=(0,_utils.roundDigits)(data.y,4);
- var content=textarea.value.trim();
- if(!svg){
- return{v:void 0};
- }
- var rect=svg.getBoundingClientRect();
-
- var _getMetadata=(0,_utils.getMetadata)(svg);
- var documentId=_getMetadata.documentId;
- var pageNumber=page;
- var annotation=Object.assign({type:'point'},(0,_utils.scaleDown)(svg,{x:clientX-((0,_utils.roundDigits)(_rect.left,4)),y:clientY-((0,_utils.roundDigits)(_rect.top,4))}));
- var commentVisibility= read_visibility_of_checkbox();
- var isquestion = 1; //The Point was created so the comment is a question
- _PDFJSAnnotate2.default.getStoreAdapter().addAnnotation(documentId,pageNumber,annotation)
- .then(function(annotation){
- _PDFJSAnnotate2.default.getStoreAdapter().addComment(documentId,annotation.uuid,content,commentVisibility,isquestion)
- .then(function(msg){
- if(!msg) { throw new Error(); }
- deleteUndefinedPin();
- //get old y-koordniate, because of scrolling
- annotation.y = annotationObj.y;
- (0,_appendChild2.default)(svg,annotation);
- document.querySelector('.toolbar').removeEventListener('click',handleToolbarClick);
- document.querySelector('button.cursor').click();
- (0,_commentWrapper.showCommentsAfterCreation)(annotation.uuid);
- })
- .catch(function(err){
- /*if there is an error in addComment, the annotation will be deleted!*/
- var annotationid = annotation.uuid;
- _PDFJSAnnotate2.default.getStoreAdapter().deleteAnnotation(documentId,annotationid, false);
+ function dialogCallbackForDelete(args = comment) {
+ if (args.type === 'textbox' || args.type === 'drawing') {
+ _2.default
+ .getStoreAdapter()
+ .deleteAnnotation(documentId, args.annotation)
+ .then(
+ function (data) {
+ if (data.status === 'success') {
+ var node = document.querySelector(
+ '[data-pdf-annotate-id="' + args.annotation + '"]'
+ );
+ var visiblePageNum =
+ node.parentNode.getAttribute('data-pdf-annotate-page');
+ node.parentNode.removeChild(node);
+ // Not possible to enter new comments.
+ document.querySelector('.comment-list-container').innerHTML = '';
+ document
+ .querySelector('.comment-list-form')
+ .setAttribute('style', 'display:none');
+ UI.renderQuestions(documentId, visiblePageNum);
+ }
+ },
+ function (err) {
+ notification.addNotification({
+ message: M.util.get_string('error:deleteAnnotation', 'pdfannotator'),
+ type: 'error',
+ });
+ console.error(M.util.get_string('error:deleteAnnotation', 'pdfannotator'));
+ }
+ );
+ } else {
+ _2.default
+ .getStoreAdapter()
+ .deleteComment(RENDER_OPTIONS.documentId, args.uuid)
+ .then(function (data) {
+ // If comment was answered so that it is not completly deleted but displayed as deleted.
+ // If question: Close If answer: Remove marking as correct
+ if (
+ data.wasanswered &&
+ ((comment.isquestion && !comment.solved) ||
+ (!comment.isquestion && comment.solved))
+ ) {
+ _2.default.getStoreAdapter().markSolved(RENDER_OPTIONS.documentId, args);
+ }
});
- }, function (err){
- deleteUndefinedPin();
- notification.addNotification({
- message: M.util.get_string('error:addAnnotation','pdfannotator'),
- type: "error"
- });
- });
- }();
- if((typeof _ret==='undefined'?'undefined':_typeof(_ret))==="object"){
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,true);
- return _ret.v;
- }
- textarea = void 0;
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,true);
- }else{
- notification.addNotification({
- message: M.util.get_string('min0Chars', 'pdfannotator'),
- type: "error"
- });
- textarea.focus();
- }
- }
- function closeInput(){data.removeEventListener('blur',handleInputBlur);data.removeEventListener('keyup',handleInputKeyup);document.body.removeChild(data);data=null;}/**
- * Enable point annotation behavior
- */function enablePoint(){
- if(_enabled){
- return;
- }
- _enabled=true;
- document.getElementById('content-wrapper').classList.add('cursor-point');
- document.addEventListener('mouseup',handleDocumentMouseup);
- document.addEventListener('touchstart', handleContentTouchstart);
- document.addEventListener('touchmove', handleContentTouchmove);
- document.addEventListener('touchend',handleContentTouchend);
- }
- /**
- * Disable point annotation behavior
- */function disablePoint(){
- _enabled=false;
- document.getElementById('content-wrapper').classList.remove('cursor-point');
- document.removeEventListener('mouseup',handleDocumentMouseup);
- document.removeEventListener('touchstart', handleContentTouchstart);
- document.removeEventListener('touchmove', handleContentTouchmove);
- document.removeEventListener('touchend',handleContentTouchend);
- }
- /***/},
- /* 32 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.enableRect=enableRect;
- exports.disableRect=disableRect;
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
- var _appendChild=__webpack_require__(11);
- var _appendChild2=_interopRequireDefault(_appendChild);
- var _setAttributes=__webpack_require__(14);
- var _setAttributes2=_interopRequireDefault(_setAttributes);
- var _utils=__webpack_require__(6);
- var _event = __webpack_require__(4);
-
- var _commentWrapper = __webpack_require__(35);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- function _toConsumableArray(arr){if(Array.isArray(arr)){for(var i=0,arr2=Array(arr.length);i0&&rects[0].width>0&&rects[0].height>0){
- return rects;
+ }
+ }
}
- }catch(e){
-
- }
- return null;
- }
- /**
- * Handle document.mousedown event
- *
- * @param {Event} e The DOM event to handle
- */
- function handleDocumentMousedown(e){
- if(!(_svg=(0,_utils.findSVGAtPoint)(e.clientX,e.clientY))|| _type!=='area'){
- return;
- }
- rect=_svg.getBoundingClientRect();
- originY=e.clientY;
- originX=e.clientX;
- overlay=document.createElement('div');
- overlay.style.position='absolute';
- overlay.id = 'overlay-rect';
- overlay.style.top=originY-rect.top+'px';
- overlay.style.left=originX-rect.left+'px';
- overlay.style.border='3px solid '+_utils.BORDER_COLOR;
- overlay.style.borderRadius='3px';
- _svg.parentNode.appendChild(overlay);
- document.addEventListener('mousemove',handleDocumentMousemove);
- (0,_utils.disableUserSelect)();
- }
-
- // Handle document.touchstart event
- function handleDocumentTouchstart(e){
- if(_type =='highlight' || _type == 'strikeout'){
- // Dont show the contextmenu for highlighting and strikeout.
- document.getElementById('content-wrapper').addEventListener('contextmenu', event => {
- event.preventDefault();
- event.stopPropagation();
- event.stopImmediatePropagation();
- return false;
- });
- }
-
- if(!(_svg=(0,_utils.findSVGAtPoint)(e.touches[0].clientX,e.touches[0].clientY)) || _type!=='area'){
- return;
- }
- // Disable scrolling on the page.
- document.documentElement.style.overflow = 'hidden';
- document.getElementById('content-wrapper').style.overflow = 'hidden';
-
- rect=_svg.getBoundingClientRect();
- originY=e.touches[0].clientY;
- originX=e.touches[0].clientX;
- overlay=document.createElement('div');
- overlay.style.position='absolute';
- overlay.style.top=originY-rect.top+'px';
- overlay.style.left=originX-rect.left+'px';
- overlay.style.border='3px solid '+_utils.BORDER_COLOR;
- overlay.style.borderRadius='3px';
- _svg.parentNode.appendChild(overlay);
- document.addEventListener('touchmove',handleDocumentTouchmove);
-
- (0,_utils.disableUserSelect)();
- }
-
- /**
- * Handle document.mousemove event
- *
- * @param {Event} e The DOM event to handle
- */
- function handleDocumentMousemove(e){
- if(originX+(e.clientX-originX) {
- [textarea,data] = (0,_commentWrapper.openComment)(e,handleCancelClick,handleSubmitClick,handleToolbarClick,handleSubmitBlur,_type);
- }
- _commentWrapper.loadEditor('add', 0, fn);
- }else if((rectsSelection=getSelectionRects()) && _type!=='area'){
- renderRect(_type,[].concat(_toConsumableArray(rectsSelection)).map(function(r){return{top:r.top,left:r.left,width:r.width,height:r.height};}),null);
-
- let fn = () => {
- [textarea,data] = (0,_commentWrapper.openComment)(e,handleCancelClick,handleSubmitClick,handleToolbarClick,handleSubmitBlur,_type);
- }
- _commentWrapper.loadEditor('add', 0, fn);
- }else{
- enableRect(_type);
- //Do nothing!
- }
- }
- }
- // Handle document.touchend event
- function handleDocumentTouchend(e){
- // Enable the scrolling again
- document.documentElement.style.overflow = 'auto';
- document.getElementById('content-wrapper').style.overflow = 'auto';
-
- //if the cursor is clicked nothing should happen!
- if((typeof e.target.getAttribute('className')!='string') && e.target.className.indexOf('cursor') === -1){
- document.removeEventListener('touchmove',handleDocumentTouchmove);
- disableRect();
- if(_type==='area'&&overlay){
- if(isOverlayTooSmall(overlay)){
- overlay.parentNode.removeChild(overlay);
- overlay=null;
- enableRect(_type);
- return;
- }
- var _svg=overlay.parentNode.querySelector('svg.annotationLayer');
- renderRect(_type,[{top:parseInt(overlay.style.top,10)+rect.top,left:parseInt(overlay.style.left,10)+rect.left,width:parseInt(overlay.style.width,10),height:parseInt(overlay.style.height,10)}],null);
-
- [textarea,data] = (0,_commentWrapper.openComment)(e,handleCancelTouch,handleSubmitClick,handleToolbarClick,handleSubmitBlur,_type);
- }else if((rectsSelection=getSelectionRects()) && _type!=='area'){
- renderRect(_type,[].concat(_toConsumableArray(rectsSelection)).map(function(r){return{top:r.top,left:r.left,width:r.width,height:r.height};}),null);
- [textarea,data] = (0,_commentWrapper.openComment)(e,handleCancelTouch,handleSubmitClick,handleToolbarClick,handleSubmitBlur,_type);
- }else{
- enableRect(_type);
- //Do nothing!
- }
- }
- }
+ /**
+ * This function is called, when an annotation is clicked. The corresponding comments are rendered and a form to submit a comment.
+ * @param {type} target
+ * @returns {undefined}
+ */
+ function handleAnnotationClick(target) {
+ if (supportsComments(target)) {
+ (function () {
+ var documentId = target.parentNode.getAttribute('data-pdf-annotate-document');
+ var annotationId = target.getAttribute('data-pdf-annotate-id');
+
+ _2.default
+ .getStoreAdapter()
+ .getComments(documentId, annotationId)
+ .then(function (comments) {
+ var title;
+ if (comments.comments[0].visibility == 'protected') {
+ title = M.util.get_string('protected_comments', 'pdfannotator');
+ $('#protectedDiv').hide();
+ $('#anonymousDiv').hide();
+ $('#privateDiv').hide();
+ $('#id_pdfannotator_contenteditable').attr(
+ 'placeholder',
+ M.util.get_string('add_protected_comment', 'pdfannotator')
+ );
+ } else if (comments.comments[0].visibility == 'private') {
+ title = M.util.get_string('private_comments', 'pdfannotator');
+ $('#privateDiv').hide();
+ $('#protectedDiv').hide();
+ $('#anonymousDiv').hide();
+ $('#id_pdfannotator_contenteditable').attr(
+ 'placeholder',
+ M.util.get_string('add_private_comment', 'pdfannotator')
+ );
+ } else {
+ title = M.util.get_string('public_comments', 'pdfannotator');
+ $('#privateDiv').hide();
+ $('#protectedDiv').hide();
+ $('#anonymousDiv').show();
+ $('#id_pdfannotator_contenteditable').attr(
+ 'placeholder',
+ M.util.get_string('addAComment', 'pdfannotator')
+ );
+ }
- function handleToolbarClick(e){
- //delete Overlay
- if(_type==='area'&&overlay){
- if(overlay.parentNode) {
- overlay.parentNode.removeChild(overlay);
- overlay=null;
- }
- }
- document.querySelector('.toolbar').removeEventListener('click',handleToolbarClick);
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,false);
- deleteUndefinedRect();
- }
+ $('#comment-wrapper h4')[0].innerHTML = title;
+ commentList.innerHTML = '';
+ commentForm.style.display = 'inherit';
+
+ var button1 = document.getElementById('allQuestions'); // to be found in index template
+ button1.style.display = 'inline';
+ var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
+ button2.style.display = 'inline';
+
+ commentForm.onsubmit = function (e) {
+ document.querySelector('#commentSubmit').disabled = true;
+ var commentVisibility = read_visibility_of_checkbox();
+ var isquestion = 0; // this is a normal comment, so it is not a question
+ var textarea = document.getElementById('id_pdfannotator_content');
+ var commentContentElements = textarea.value.trim();
+ if (commentContentElements.length === 0) {
+ //should be more than one character, otherwise it should not be saved.
+ notification.addNotification({
+ message: M.util.get_string('min0Chars', 'pdfannotator'),
+ type: 'error',
+ });
+ document.querySelector('#commentSubmit').disabled = false;
+ return false;
+ }
-
- function handleSubmitClick(e){
- var rects=void 0;
- if(_type!=='area'&&(rects=rectsSelection)){
- saveRect(_type,[].concat(_toConsumableArray(rects)).map(function(r){return{top:r.top,left:r.left,width:r.width,height:r.height};}),null,e);
- }else if(_type==='area'&&overlay){
- saveRect(_type,[{top:parseInt(overlay.style.top,10)+rect.top,left:parseInt(overlay.style.left,10)+rect.left,width:parseInt(overlay.style.width,10),height:parseInt(overlay.style.height,10)}],null,e,overlay);
- }
- return false;
- }
-
- function handleCancelClick(e){
- //delete Overlay
- if(_type==='area'&&overlay){
- overlay.parentNode.removeChild(overlay);
- overlay=null;
- }
- //Hide the form for Comments
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,false);
- deleteUndefinedRect();
- //register EventListeners to allow new Annotations
- enableRect(_type);
- (0,_utils.enableUserSelect)();
- }
+ _2.default
+ .getStoreAdapter()
+ .addComment(
+ documentId,
+ annotationId,
+ commentContentElements,
+ commentVisibility,
+ isquestion
+ )
+ .then(function (response) {
+ var fn = (response) => insertComments(response);
+ UI.loadEditor('add', 0, fn, response);
+ })
+ .then(function (success) {
+ if (!success) {
+ return false;
+ }
+ document.querySelector('#commentSubmit').disabled = false;
+ })
+ .catch(function (err) {
+ notification.addNotification({
+ message: M.util.get_string('error:addComment', 'pdfannotator'),
+ type: 'error',
+ });
+ console.error(
+ M.util.get_string('error:addComment', 'pdfannotator')
+ );
+ });
- function handleCancelTouch(e){
- // When using on mobile devices scrolling will be prevented, here we have to allow it again.
- document.documentElement.style.overflow = 'auto';
- document.getElementById('content-wrapper').style.overflow = 'auto';
+ return false; // Prevents page reload via POST to enable asynchronous loading
+ };
+
+ var params = { comments: comments, markCommentid: target.markCommentid };
+ var fn = (params) => {
+ var comments = params.comments;
+ var markCommentid = params.markCommentid;
+ //render comments
+ insertComments(comments, markCommentid);
+ };
+ UI.loadEditor('add', 0, fn, params);
+ })
+ .catch(function (err) {
+ commentList.innerHTML = '';
+ commentForm.style.display = 'none';
+ commentForm.onsubmit = null;
- //delete Overlay
- if(_type==='area'&&overlay){
- overlay.parentNode.removeChild(overlay);
- overlay=null;
- }
- //Hide the form for Comments
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,false);
- deleteUndefinedRect();
-
- // Because of a scrolling issue we have to disable the area annotation after canceling the annotation.
- if (_type ==='area') {
- disableRect();
- document.querySelector('button.cursor').click();
- } else {
- enableRect(_type);
- (0,_utils.enableUserSelect)();
- }
- }
-
- function handleSubmitBlur(){
- if(overlay){
- overlay.parentNode.removeChild(overlay);
- overlay=null;
- }
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,false);
- deleteUndefinedRect();
- }
+ insertComments({
+ content: M.util.get_string('error:getComments', 'pdfannotator'),
+ });
- /**
- * Handle document.keyup event
- *
- * @param {Event} e The DOM event to handle
- */
- function handleDocumentKeyup(e){// Cancel rect if Esc is pressed
- if(e.keyCode===27){var selection=window.getSelection();selection.removeAllRanges();if(overlay&&overlay.parentNode){overlay.parentNode.removeChild(overlay);overlay=null;document.removeEventListener('mousemove',handleDocumentMousemove);}}
- }
-
- function renderRect(type,rects,color){
- rect=_svg.getBoundingClientRect();
- var _getMetadata=(0,_utils.getMetadata)(_svg);
- documentId=_getMetadata.documentId;
- pageNumber=_getMetadata.pageNumber;
- var annotation = initializeAnnotation(type,rects,'rgb(255,237,0)',_svg);
- rectObj = [_svg,annotation];
- (0,_appendChild2.default)(_svg,annotation);
- }
- /**
- * This function deletes all annotations which data-pdf-annotate-id is undefined. An annotation is undefined, if it is only temporarily displayed.
- * @returns {undefined}
- */
- function deleteUndefinedRect(){
- let n = document.querySelector('[data-pdf-annotate-id="undefined"]');
- if(n){
- n.parentNode.removeChild(n);
- }
- }
+ notification.addNotification({
+ message: M.util.get_string('error:getComments', 'pdfannotator'),
+ type: 'error',
+ });
+ });
+ })();
+ } else {
+ // Drawing or textbox
+ (function () {
+ var documentId = target.parentNode.getAttribute('data-pdf-annotate-document');
+ var annotationId = target.getAttribute('data-pdf-annotate-id');
+
+ _2.default
+ .getStoreAdapter()
+ .getInformation(documentId, annotationId)
+ .then(function (annotation) {
+ UI.hideLoader();
+ commentList.innerHTML = '';
+ commentForm.style.display = 'none';
+ commentForm.onsubmit = null;
+
+ var button1 = document.getElementById('allQuestions'); // to be found in index template
+ button1.style.display = 'inline';
+ var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
+ button2.style.display = 'inline';
+
+ //render comments
+ insertComments(annotation);
+ })
+ .catch(function (err) {
+ commentList.innerHTML = '';
+ commentForm.style.display = 'none';
+ commentForm.onsubmit = null;
-
- function initializeAnnotation(type,rects,color,svg){
-
- var node=void 0;
- var annotation=void 0;
- if(!svg){return;}
- if(!color){
- if(type==='highlight'){
- color='rgb(142,186,229)';
- }else if(type==='strikeout'){
- color='rgb(0,84,159)';
- }
- }
- // Initialize the annotation
- annotation={type:type,color:color,rectangles:[].concat(_toConsumableArray(rects)).map(function(r){var offset=0;if(type==='strikeout'){offset=r.height/2;}return(0,_utils.scaleDown)(svg,{y:r.top+offset-rect.top,x:r.left-rect.left,width:r.width,height:r.height});}).filter(function(r){return r.width>0&&r.height>0&&r.x>-1&&r.y>-1;})};// Short circuit if no rectangles exist
- if(annotation.rectangles.length===0){
- return;
- }// Special treatment for area as it only supports a single rect
- if(type==='area'){
- var _rect=annotation.rectangles[0];
- delete annotation.rectangles;
- annotation.x=(0,_utils.roundDigits)(_rect.x,4);
- annotation.y=(0,_utils.roundDigits)(_rect.y,4);
- annotation.width=(0,_utils.roundDigits)(_rect.width,4);
- annotation.height=(0,_utils.roundDigits)(_rect.height,4);
- }else{
- annotation.rectangles = annotation.rectangles.map(function(elem, index, array){
- return {x:(0,_utils.roundDigits)(elem.x,4),y:(0,_utils.roundDigits)(elem.y,4),width:(0,_utils.roundDigits)(elem.width,4),height:(0,_utils.roundDigits)(elem.height,4)};
- });
- }
- return annotation;
- }
-
- /**
- * Save a rect annotation
- *
- * @param {String} type The type of rect (area, highlight, strikeout)
- * @param {Array} rects The rects to use for annotation
- * @param {String} color The color of the rects
- */
- function saveRect(type,rects,color,e,overlay){
- var annotation = initializeAnnotation(type,rects,color,_svg);
- var _getMetadata=(0,_utils.getMetadata)(_svg);
- var documentId=_getMetadata.documentId;
- var pageNumber=_getMetadata.pageNumber;
- var content=textarea.value.trim();
- if(textarea.value.trim().length > 0){
-
- (0,_commentWrapper.closeComment)(documentId,pageNumber,handleSubmitClick,handleCancelClick,null,true);
-
- if(_type==='area'&&overlay){
- overlay.parentNode.removeChild(overlay);
- overlay=null;
- document.removeEventListener('mousemove',handleDocumentMousemove);
- (0,_utils.enableUserSelect)();
- }
- // Add the annotation
- _PDFJSAnnotate2.default.getStoreAdapter()
- .addAnnotation(documentId,pageNumber,annotation)
- .then(function(annotation){
- var commentVisibility= read_visibility_of_checkbox();
- var isquestion = 1; //The annotation was created, so this comment has to be a question;
- _PDFJSAnnotate2.default.getStoreAdapter().addComment(documentId,annotation.uuid,content,commentVisibility,isquestion)
- .then(function(msg){
- if(!msg) throw new Error();
- //delete previous annotation to render new one with the right id
- deleteUndefinedRect();
- //get Old rectangles because of scrolling
- annotation.rectangles = rectObj[1].rectangles;
-
- (0,_appendChild2.default)(_svg,annotation);
- document.querySelector('.toolbar').removeEventListener('click',handleToolbarClick);
- //simulate an click on cursor
- document.querySelector('button.cursor').click();
- (0,_commentWrapper.showCommentsAfterCreation)(annotation.uuid);
- })
- .catch(function(){
- //if there is an error in addComment, the annotation should be deleted!
- var annotationid = annotation.uuid;
- _PDFJSAnnotate2.default.getStoreAdapter().deleteAnnotation(documentId,annotationid, false);
- });
- }, function (err){
- deleteUndefinedRect();
- notification.addNotification({
- message: M.util.get_string('error:addAnnotation','pdfannotator'),
- type: "error"
- });
- });
- }else{
- notification.addNotification({
- message: M.util.get_string('min0Chars', 'pdfannotator'),
- type: "error"
- });
- handleCancelClick(e);
- textarea.focus();
- }
- }
- /**
- * Enable rect behavior
- */
- function enableRect(type){
- _type=type;
- if(_enabled){return;}
-
- if(_type === 'area'){
- document.getElementById('content-wrapper').classList.add('cursor-area');
- }else if(_type === 'highlight'){
- document.getElementById('content-wrapper').classList.add('cursor-highlight');
- }else if(_type === 'strikeout'){
- document.getElementById('content-wrapper').classList.add('cursor-strikeout');
- }
-
- _enabled=true;
- document.addEventListener('mouseup',handleDocumentMouseup);
- document.addEventListener('mousedown',handleDocumentMousedown);
- document.addEventListener('keyup',handleDocumentKeyup);
-
- document.addEventListener('touchstart', handleDocumentTouchstart);
- document.addEventListener('touchend', handleDocumentTouchend);
- }
- /**
- * Disable rect behavior
- */
- function disableRect(){
- if(!_enabled){return;}
- _enabled=false;
- if(_type === 'area'){
- document.getElementById('content-wrapper').classList.remove('cursor-area');
- }else if(_type === 'highlight'){
- document.getElementById('content-wrapper').classList.remove('cursor-highlight');
- }else if(_type === 'strikeout'){
- document.getElementById('content-wrapper').classList.remove('cursor-strikeout');
- }
- document.removeEventListener('mouseup',handleDocumentMouseup);
- document.removeEventListener('mousedown',handleDocumentMousedown);
- document.removeEventListener('keyup',handleDocumentKeyup);
+ insertComments({
+ content: M.util.get_string('error:getComments', 'pdfannotator'),
+ });
- document.removeEventListener('touchstart', handleDocumentTouchstart);
- document.removeEventListener('touchend', handleDocumentTouchend);
- }
-/***/},
-/* 33 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- var _typeof=typeof Symbol==="function"&&_typeof2(Symbol.iterator)==="symbol"?function(obj){return typeof obj==='undefined'?'undefined':_typeof2(obj);}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol?"symbol":typeof obj==='undefined'?'undefined':_typeof2(obj);};
- exports.setText=setText;
- exports.enableText=enableText;
- exports.disableText=disableText;
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
- var _appendChild=__webpack_require__(11);
- var _appendChild2=_interopRequireDefault(_appendChild);
- var _utils=__webpack_require__(6);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- var _enabled=false;
- var input=void 0;
- var pos = void 0;
- var _textSize=void 0;
- var _textColor=void 0;
- var svg=void 0;
- var rect=void 0;/**
- * Handle document.mouseup event
- *
- *
- * @param {Event} e The DOM event to handle
- */function handleDocumentMouseup(e){ // betrifft textbox
- if(input||!(svg=(0,_utils.findSVGAtPoint)(e.clientX,e.clientY))){
- return;
- }
- let scrollTop = window.pageYOffset;
- input=document.createElement('input');
- input.setAttribute('id','pdf-annotate-text-input');
- input.setAttribute('placeholder',M.util.get_string('enterText','pdfannotator'));
- input.style.border='3px solid '+_utils.BORDER_COLOR;
- input.style.borderRadius='3px';
- input.style.position='absolute';
- input.style.top=(e.clientY+scrollTop)+'px';
- input.style.left=e.clientX+'px';
- input.style.fontSize=_textSize+'px';
- input.addEventListener('blur',handleInputBlur);
- input.addEventListener('keyup',handleInputKeyup);
- document.body.appendChild(input);
- input.focus();
- rect=svg.getBoundingClientRect();
- pos = {x: e.clientX, y: e.clientY };
- }
- /**
- * Handle input.blur event
- */function handleInputBlur(){
- saveText();
- }/**
- * Handle input.keyup event
- *
- * @param {Event} e The DOM event to handle
- */function handleInputKeyup(e){if(e.keyCode===27){closeInput();}else if(e.keyCode===13){saveText();}}/**
- * Save a text annotation from input
- */function saveText(){
- if(input.value.trim().length>0){
- var _ret=function(){
- var clientX=parseInt(pos.x,10);
- //text size additional to y to render the text right under the mouse click
- var clientY=parseInt(pos.y,10);
- //var svg=(0,_utils.findSVGAtPoint)(clientX,clientY);
- if(!svg){
- return{v:void 0};
- }
- var _getMetadata=(0,_utils.getMetadata)(svg);
- var documentId=_getMetadata.documentId;
- var pageNumber=_getMetadata.pageNumber;
-
- var annotation=Object.assign({type:'textbox',size:_textSize,color:_textColor,content:input.value.trim()},(0,_utils.scaleDown)(svg,{x:(0,_utils.roundDigits)(clientX-rect.left,4),y:(0,_utils.roundDigits)(clientY-rect.top,4),width:(0,_utils.roundDigits)(input.offsetWidth,4),height:(0,_utils.roundDigits)(input.offsetHeight,4)}));
- _PDFJSAnnotate2.default.getStoreAdapter().addAnnotation(documentId,pageNumber,annotation)
- .then(function(annotation){
- //annotation.y = annotation.y +parseInt(annotation.size,10);
- (0,_appendChild2.default)(svg,annotation);
- document.querySelector('button.cursor').click();
- }, function (err){
- notification.addNotification({
- message: M.util.get_string('error:addAnnotation', 'pdfannotator'),
- type: "error"
+ notification.addNotification({
+ message: M.util.get_string('error:getComments', 'pdfannotator'),
+ type: 'error',
+ });
});
- });
- }();
- if((typeof _ret==='undefined'?'undefined':_typeof(_ret))==="object")
- return _ret.v;
- }
- closeInput();
- }/**
- * Close the input
- */function closeInput(){try{if(input){input.removeEventListener('blur',handleInputBlur);input.removeEventListener('keyup',handleInputKeyup);document.body.removeChild(input);input=null; pos = null;}}catch{}}/**
- * Set the text attributes
- *
- * @param {Number} textSize The size of the text
- * @param {String} textColor The color of the text
- */function setText(){var textSize=arguments.length<=0||arguments[0]===undefined?12:arguments[0];var textColor=arguments.length<=1||arguments[1]===undefined?'000000':arguments[1];_textSize=parseInt(textSize,10);_textColor=textColor;}/**
- * Enable text behavior
- */function enableText(){
- if(_enabled){
- return;
- }
- _enabled=true;
- document.getElementById('content-wrapper').classList.add('cursor-text');
- document.addEventListener('mouseup',handleDocumentMouseup);
- }/**
- * Disable text behavior
- */function disableText(){
- if(!_enabled){return;
- }
- _enabled=false;
- document.getElementById('content-wrapper').classList.remove('cursor-text');
- document.removeEventListener('mouseup',handleDocumentMouseup);
- }
- /***/},
- /* 34 */
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- var _slicedToArray=function(){
- function sliceIterator(arr,i){
- var _arr=[];
- var _n=true;
- var _d=false;
- var _e=undefined;
- try{
- for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){
- _arr.push(_s.value);
- if(i&&_arr.length===i)break;
- }
- }catch(err){
- _d=true;
- _e=err;
- }finally{
- try{
- if(!_n&&_i["return"])_i["return"]();
- }finally{
- if(_d)throw _e;
+ })();
}
}
- return _arr;
- }
- return function(arr,i){
- if(Array.isArray(arr)){
- return arr;
- }else if(Symbol.iterator in Object(arr)){
- return sliceIterator(arr,i);
- }else{
- throw new TypeError("Invalid attempt to destructure non-iterable instance");
+
+ function handleAnnotationBlur(target) {
+ if (supportsComments(target)) {
+ commentList.innerHTML = '';
+ commentForm.style.display = 'none';
+ commentForm.onsubmit = null;
+ }
+ var visiblePageNum = document.getElementById('currentPage').value;
+ UI.renderQuestions(documentId, visiblePageNum);
}
- };
- }();
-
- exports.createPage=createPage;
- exports.renderPage=renderPage;
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
- var _renderScreenReaderHints=__webpack_require__(20);
- var _renderScreenReaderHints2=_interopRequireDefault(_renderScreenReaderHints);
- var _appendChild=__webpack_require__(11);
- var _appendChild2=_interopRequireDefault(_appendChild);
- var _utils=__webpack_require__(6);
- var _renderQuestions = __webpack_require__(38);
- function _interopRequireDefault(obj){
- return obj&&obj.__esModule?obj:{default:obj};
- }
- var SIZE = 20;
- // Template for creating a new page
- //helper Layer as a Child of Textlayer added, because in firefox the handleDocumentClick only fires, if the click is outside of Textlayer or is on a child of Textlayer
- var PAGE_TEMPLATE='\n \n';/**
- * Create a new page to be appended to the DOM.
- *
- * @param {Number} pageNumber The page number that is being created
- * @return {HTMLElement}
- */function createPage(pageNumber){
- var temp=document.createElement('div');
- temp.innerHTML=PAGE_TEMPLATE;
- var page=temp.children[0];
- var canvas=page.querySelector('canvas');
- page.setAttribute('id','pageContainer'+pageNumber);
- page.setAttribute('data-page-number',pageNumber);
- canvas.mozOpaque=true;
- canvas.setAttribute('id','page'+pageNumber);
- return page;
- }
-
- let listOfPagesLoaded = [];
- /**
- * Render a page that has already been created.
- *
- * @param {Number} pageNumber The page number to be rendered
- * @param {Object} renderOptions The options for rendering
- * @return {Promise} Settled once rendering has completed
- * A settled Promise will be either:
- * - fulfilled: [pdfPage, annotations]
- * - rejected: Error
- */function renderPage(pageNumber,renderOptions, reset = false){
- if(reset){
- listOfPagesLoaded = [];
- currentAnnotations = [];
- }
- if(listOfPagesLoaded.indexOf(pageNumber) !== -1){
- return;
- }
- listOfPagesLoaded.push(pageNumber);
-
- var documentId=renderOptions.documentId;
- var pdfDocument=renderOptions.pdfDocument;
- var scale=renderOptions.scale;
- var _rotate=renderOptions.rotate;// Load the page and annotations
- return Promise.all([pdfDocument.getPage(pageNumber),_PDFJSAnnotate2.default.getAnnotations(documentId,pageNumber)])
- .then(function(_ref){
- var _ref2=_slicedToArray(_ref,2);
- var pdfPage=_ref2[0];
- var annotations=_ref2[1];
- currentAnnotations[pageNumber] = annotations.annotations;
-
- var page=document.getElementById('pageContainer'+pageNumber);
- var svg=page.querySelector('.annotationLayer');
- var canvas=page.querySelector('.canvasWrapper canvas');
- var canvasContext=canvas.getContext('2d',{alpha:false});
- var viewport=pdfPage.getViewport({scale:scale,rotation:_rotate});
- var viewportWithoutRotate=pdfPage.getViewport({scale:scale,rotation:0});
- var transform=scalePage(pageNumber,viewport,canvasContext);// Render the page
- return Promise.all([pdfPage.render({canvasContext:canvasContext,viewport:viewport,transform:transform}),_PDFJSAnnotate2.default.render(svg,viewportWithoutRotate,annotations)])
- .then(function(){
- // Text content is needed for a11y, but is also necessary for creating
- // highlight and strikeout annotations which require selecting text.
- return pdfPage.getTextContent({normalizeWhitespace:true})
- .then(function(textContent){
- return new Promise(function(resolve,reject){
- require(['mod_pdfannotator/pdf_viewer'], function(pdfjsViewer) {
- // Render text layer for a11y of text content
- var textLayer=page.querySelector('.textLayer');
- var textLayerFactory=new pdfjsViewer.DefaultTextLayerFactory();
- var eventBus=new pdfjsViewer.EventBus();
- // (Optionally) enable hyperlinks within PDF files.
- var pdfLinkService=new pdfjsViewer.PDFLinkService({
- eventBus,
- });
- // (Optionally) enable find controller.
- var pdfFindController=new pdfjsViewer.PDFFindController({
- linkService: pdfLinkService,
- eventBus,
- });
- var pageIdx=pageNumber-1;
- var highlighter = new pdfjsViewer.TextHighlighter({
- pdfFindController,
- eventBus,
- pageIdx
- });
- var textLayerBuilder=textLayerFactory.createTextLayerBuilder(
- textLayer,
- pageIdx,
- viewport,
- true,
- eventBus,
- highlighter,
- );
- pdfLinkService.setViewer(textLayerBuilder);
- textLayerBuilder.setTextContent(textContent);
- textLayerBuilder.render();// Enable a11y for annotations
-
- // Timeout is needed to wait for `textLayerBuilder.render`
- //setTimeout(function(){try{(0,_renderScreenReaderHints2.default)(annotations.annotations);resolve();}catch(e){reject(e);}});
- //ur weil setTimeout auskommentiert ist!!!!!
- resolve();
- });
- });
- });
- }).then(function(){// Indicate that the page was loaded
- page.setAttribute('data-loaded','true');
-
- return[pdfPage,annotations];
- });
- }, function (err){
- notification.addNotification({
- message: M.util.get_string('error:renderPage', 'pdfannotator'),
- type: "error"
- });
- });
- }/**
- * Scale the elements of a page.
- *
- * @param {Number} pageNumber The page number to be scaled
- * @param {Object} viewport The viewport of the PDF page (see pdfPage.getViewport(scale, rotation))
- * @param {Object} context The canvas context that the PDF page is rendered to
- * @return {Array} The transform data for rendering the PDF page
- */function scalePage(pageNumber,viewport,context){var page=document.getElementById('pageContainer'+pageNumber);var canvas=page.querySelector('.canvasWrapper canvas');var svg=page.querySelector('.annotationLayer');var wrapper=page.querySelector('.canvasWrapper');var textLayer=page.querySelector('.textLayer');var outputScale=getOutputScale(context);var transform=!outputScale.scaled?null:[outputScale.sx,0,0,outputScale.sy,0,0];var sfx=approximateFraction(outputScale.sx);var sfy=approximateFraction(outputScale.sy);// Adjust width/height for scale
- page.style.visibility='';canvas.width=roundToDivide(viewport.width*outputScale.sx,sfx[0]);canvas.height=roundToDivide(viewport.height*outputScale.sy,sfy[0]);canvas.style.width=roundToDivide(viewport.width,sfx[1])+'px';canvas.style.height=roundToDivide(viewport.height,sfx[1])+'px';svg.setAttribute('width',viewport.width);svg.setAttribute('height',viewport.height);svg.style.width=viewport.width+'px';svg.style.height=viewport.height+'px';page.style.width=viewport.width+'px';page.style.height=viewport.height+'px';wrapper.style.width=viewport.width+'px';wrapper.style.height=viewport.height+'px';textLayer.style.width=viewport.width+'px';textLayer.style.height=viewport.height+'px';return transform;}/**
- * Approximates a float number as a fraction using Farey sequence (max order of 8).
- *
- * @param {Number} x Positive float number
- * @return {Array} Estimated fraction: the first array item is a numerator,
- * the second one is a denominator.
- */function approximateFraction(x){// Fast path for int numbers or their inversions.
- if(Math.floor(x)===x){return[x,1];}var xinv=1/x;var limit=8;if(xinv>limit){return[1,limit];}else if(Math.floor(xinv)===xinv){return[1,xinv];}var x_=x>1?xinv:x;// a/b and c/d are neighbours in Farey sequence.
- var a=0,b=1,c=1,d=1;// Limit search to order 8.
- while(true){// Generating next term in sequence (order of q).
- var p=a+c,q=b+d;if(q>limit){break;}if(x_<=p/q){c=p;d=q;}else{a=p;b=q;}}// Select closest of neighbours to x.
- if(x_-a/b';
- form = document.querySelector('.comment-list-form');
- $(document).ready(function(){
- form.setAttribute('style','display:inherit');
- $('#anonymousDiv').show();
- $('#privateDiv').show();
- $('#protectedDiv').show();
- });
- textarea = document.getElementById('id_pdfannotator_content');
- textarea.placeholder = M.util.get_string('startDiscussion','pdfannotator');
- submitbutton = document.getElementById('commentSubmit');
- submitbutton.value = M.util.get_string('createAnnotation','pdfannotator');
- resetbutton = document.getElementById('commentCancel');
- resetbutton.addEventListener('click',cancelClick);
- form.onsubmit = submitClick;
- //fixCommentForm();
- if(_type === 'pin'){
- data = new Object();
- data.x = e.clientX;
- data.y = e.clientY;
- }else{
- data = document.createElement('div');
- data.setAttribute('id','pdf-annotate-point-input');
- data.style.border='3px solid '+_utils.BORDER_COLOR;
- data.style.borderRadius='3px';
- data.style.display = 'none';
- data.style.position='absolute';
- data.style.top=e.clientY+'px';
- data.style.left=e.clientX+'px';
- }
-
- form.addEventListener('blur',submitBlur);
- textarea.focus();
- return [textarea,data];
- }
- function openCommentTouchscreen(e,cancelClick,submitClick,toolbarClick,submitBlur,_type){
- //save e for later
- _e = e;
-
- var button1 = document.getElementById('allQuestions'); // to be found in index template
- button1.style.display = 'inline';
- var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
- button2.style.display = 'inline';
-
- //title
- $('#comment-wrapper h4')[0].innerHTML = M.util.get_string('comments','pdfannotator');
- //add Eventlistener to Toolbar. Every Click in Toolbar should cancel the Annotation-Comment-Creation
- document.querySelector('.toolbar').addEventListener('click',toolbarClick);
- //Hide shown comments
- document.querySelector('.comment-list-container').innerHTML = '';
- form = document.querySelector('.comment-list-form');
- form.setAttribute('style','display:inherit');
- $('#anonymousCheckbox').show();
- $('#privateCheckbox').show();
- $('#protectedCheckbox').show();
- textarea = document.getElementById('id_pdfannotator_content');
- textarea.placeholder = M.util.get_string('startDiscussion','pdfannotator');
- submitbutton = document.getElementById('commentSubmit');
- submitbutton.value = M.util.get_string('createAnnotation','pdfannotator');
- resetbutton = document.getElementById('commentCancel');
- resetbutton.addEventListener('click',cancelClick);
- form.onsubmit = submitClick;
- //fixCommentForm();
- if(_type === 'pin'){
- data = new Object();
- data.x = e.changedTouches[0].clientX;
- data.y = e.changedTouches[0].clientY;
- }else{
- data = document.createElement('div');
- data.setAttribute('id','pdf-annotate-point-input');
- data.style.border='3px solid '+_utils.BORDER_COLOR;
- data.style.borderRadius='3px';
- data.style.display = 'none';
- data.style.position='absolute';
- data.style.top=e.clientY+'px';
- data.style.left=e.clientX+'px';
- }
-
- form.addEventListener('blur',submitBlur);
- textarea.focus();
- return [textarea,data];
- }
+ twttr.txt = {};
+ twttr.txt.regexen = {};
- /**
- *
- * @param {type} action can be add for adding comments. Or edit for editing comments.
- * @param {int} uuid
- * @param {Function} fn a callback funtion. It will be called after the Promises in this funktion finish.
- *
- *
- */
- function loadEditor(action='add', uuid=0, fn=null, fnParams=null){
- // search the placeholder for editor.
- let addCommentEditor = document.querySelectorAll('#add_comment_editor_wrapper');
- let editCommentEditor = document.querySelectorAll (`#edit_comment_editor_wrapper_${uuid}`);
-
- if (action === "add") {
- _ajaxloader.showLoader(`.editor-loader-placeholder-${action}`);
-
- // remove old editor and old input values of draftitemid and editorformat, if exists.
- if (addCommentEditor.length > 0) {
- addCommentEditor[0].remove();
- }
+ var HTML_ENTITIES = {
+ '&': '&',
+ '>': '>',
+ '<': '<',
+ '"': '"',
+ "'": ''',
+ };
- let data = {};
- templates.render('mod_pdfannotator/add_comment_editor_placeholder', data)
- .then(function(html, js) {
- let commentListForm = document.getElementById('comment-list-form');
- templates.prependNodeContents(commentListForm, html, js);
- if (_editorSettings.active_editor === 'textarea_texteditor') {
- document.getElementById('id_pdfannotator_content').setAttribute('style', 'display:unset !important');
- }
- })
- .then(function() {
- let args = {'action': action, 'cmid': _cm.id};
- Fragment.loadFragment('mod_pdfannotator', 'open_add_comment_editor', _contextId, args)
- .done(function(html, js) {
- if (!html) {
- throw new TypeError("Invalid HMTL Input");
+ // HTML escaping
+ twttr.txt.htmlEscape = function (text) {
+ return (
+ text &&
+ text.replace(/[&"'><]/g, function (character) {
+ return HTML_ENTITIES[character];
+ })
+ );
+ };
+
+ // Builds a RegExp
+ function regexSupplant(regex, flags) {
+ flags = flags || '';
+ if (typeof regex !== 'string') {
+ if (regex.global && flags.indexOf('g') < 0) {
+ flags += 'g';
}
- templates.replaceNode(document.getElementById('editor-commentlist-inputs'), html, js);
- if (fn instanceof Function) {
- (0,fn)(fnParams);
+ if (regex.ignoreCase && flags.indexOf('i') < 0) {
+ flags += 'i';
}
- _ajaxloader.hideLoader(`.editor-loader-placeholder-${action}`);
- return true;
- })
- .then(function() {
- let commentText = document.getElementById('id_pdfannotator_contenteditable');
- if(commentText) {
- commentText.focus();
+ if (regex.multiline && flags.indexOf('m') < 0) {
+ flags += 'm';
}
- });
- })
- .catch(notification.exception);
- } else if(action === "edit") {
- _ajaxloader.showLoader(`.editor-loader-placeholder-${action}-${uuid}`);
-
- // remove old editor and old input values of draftitemid and editorformat, if exists.
- if (editCommentEditor.length > 0) {
- editCommentEditor[0].remove();
+
+ regex = regex.source;
+ }
+
+ return new RegExp(
+ regex.replace(/#\{(\w+)\}/g, function (match, name) {
+ var newRegex = twttr.txt.regexen[name] || '';
+ if (typeof newRegex !== 'string') {
+ newRegex = newRegex.source;
+ }
+ return newRegex;
+ }),
+ flags
+ );
}
- let data = {'uuid': uuid};
- templates.render('mod_pdfannotator/edit_comment_editor_placeholder', data)
- .then(function(html, js) {
- let editForm = document.getElementById(`edit${uuid}`);
- templates.prependNodeContents(editForm, html, js);
- return true;
- })
- .then(function() {
- let args = {'action': action, 'cmid': _cm.id, 'uuid': uuid};
- Fragment.loadFragment('mod_pdfannotator', 'open_edit_comment_editor', _contextId, args)
- .then(function(html, js) {
- if (!html) {
- throw new TypeError("Invalid HMTL Input");
- }
- //templates.runTemplateJS(js);
- let editCommentEditorElement = document.getElementById(`edit_comment_editor_wrapper_${uuid}`);
- html = html.split('displaycontent:');
- let isreplaced = templates.appendNodeContents(editCommentEditorElement, html[0], js);
- let editTextarea = document.getElementById(`editarea${uuid}`);
- editTextarea.innerText = html[1];
-
- _ajaxloader.hideLoader(`.editor-loader-placeholder-${action}-${uuid}`);
-
- let editForm = document.getElementById(`edit${uuid}`)
- let chatMessage = document.getElementById(`chatmessage${uuid}`);
- let editAreaEditable = document.getElementById(`editarea${uuid}editable`);
- if (editAreaEditable) { // Does not exist for tinymce editor.
- editAreaEditable.innerHTML = editTextarea.value;
- }
- if(editForm.style.display === "none") {
- editForm.style.cssText += ';display:block;';
- chatMessage.innerHTML = "";
- }
- return true;
- })
- .then(function() {
- let commentText = document.getElementById(`editarea${uuid}`);
- if(commentText) {
- commentText.focus();
- }
- if (fn instanceof Function) {
- (0,fn)(fnParams);
- }
+ twttr.txt.regexSupplant = regexSupplant;
+
+ // simple string interpolation
+ function stringSupplant(str, values) {
+ return str.replace(/#\{(\w+)\}/g, function (match, name) {
+ return values[name] || '';
});
- })
- .catch(notification.exception);
- } else {
- // nothing to do.
- }
- }
-
- /***/},
- /* 36 *//*OWN Module! To show and hide ajaxloader*/
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.showLoader=showLoader;
- exports.hideLoader=hideLoader;
-
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
-
- /**
- * hides the loading animation
- * @returns {undefined}
- */
- function hideLoader(selector='.comment-list-container'){
- let loader = document.querySelector('#ajaxLoaderCreation');
- if(loader !== null){
- let commentContainer = document.querySelectorAll(`${selector}`)[0];
- commentContainer.removeChild(loader);
- }
- }
-
- /**
- * Shows an loading animation in the comment wrapper
- * @returns {undefined}
- */
- function showLoader(selector='.comment-list-container'){
- let commentContainer = document.querySelector(`${selector}`);
- commentContainer.innerHTML = '';
- let img = document.createElement('img');
- img.id = "ajaxLoaderCreation";
- img.src = M.util.image_url('i/loading');
- img.alt = M.util.get_string('loading','pdfannotator');
- img.classList.add('icon');
- img.style = 'display: block; margin-left: auto;margin-right: auto;';
- commentContainer.appendChild(img);
- }
- },
- /* 37 *//*OWN Module! To pick an annotation*/
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.pickAnnotation=pickAnnotation;
- var _event=__webpack_require__(4);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
-
- /**
- * This function scrolls to the specific annotation and selects the annotation
- * @param {type} page of the annotation
- * @param {type} annoid the id of the picked annotation
- * @param {type} commid id of the comment, if a comment should be marked, else null
- * @return {void}
- */
- function pickAnnotation(page,annoid,commid){
- //[0] for only first element (it only can be one element)
- var target = $('[data-pdf-annotate-id='+annoid+']')[0];
- if(commid !== null){
- target.markCommentid = commid;
- }
- _event.fireEvent('annotation:click',target);
-
- //Scroll to defined page (because of the picked annotation (new annotation, new answer or report) from overview)
- var targetDiv = $('[data-target-id='+annoid+']')[0];
- var pageOffset = document.getElementById('pageContainer'+page).offsetTop;
+ }
- var contentWrapper = $('#content-wrapper');
- contentWrapper.scrollTop(pageOffset + targetDiv.offsetTop - 100);
- contentWrapper.scrollLeft(targetDiv.offsetLeft - contentWrapper.width() + 100);
+ twttr.txt.stringSupplant = stringSupplant;
+
+ twttr.txt.regexen.spaces_group =
+ /\x09-\x0D\x20\x85\xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000/;
+ twttr.txt.regexen.spaces = regexSupplant(/[#{spaces_group}]/);
+ twttr.txt.regexen.invalid_chars_group = /\uFFFE\uFEFF\uFFFF\u202A-\u202E/;
+ twttr.txt.regexen.invalid_chars = regexSupplant(/[#{invalid_chars_group}]/);
+ twttr.txt.regexen.punct = /\!'#%&'\(\)*\+,\\\-\.\/:;<=>\?@\[\]\^_{|}~\$/;
+ twttr.txt.regexen.rtl_chars = /[\u0600-\u06FF]|[\u0750-\u077F]|[\u0590-\u05FF]|[\uFE70-\uFEFF]/gm;
+ twttr.txt.regexen.non_bmp_code_pairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/gm;
+
+ twttr.txt.regexen.latinAccentChars =
+ /\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0100-\u024F\u0253\u0254\u0256\u0257\u0259\u025B\u0263\u0268\u026F\u0272\u0289\u028B\u02BB\u0300-\u036F\u1E00-\u1EFF/;
+
+ // Generated from unicode_regex/unicode_regex_groups.scala, same as objective c's \p{L}\p{M}
+ twttr.txt.regexen.bmpLetterAndMarks =
+ /A-Za-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u052f\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u065f\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06ef\u06fa-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07ca-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0-\u08b2\u08e4-\u0963\u0971-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09f0\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a70-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0c00-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c81-\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0cf1\u0cf2\u0d01-\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u103f\u1050-\u108f\u109a-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16f1-\u16f8\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u180b-\u180d\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191e\u1920-\u192b\u1930-\u193b\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f\u1aa7\u1ab0-\u1abe\u1b00-\u1b4b\u1b6b-\u1b73\u1b80-\u1baf\u1bba-\u1bf3\u1c00-\u1c37\u1c4d-\u1c4f\u1c5a-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1cf8\u1cf9\u1d00-\u1df5\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u20d0-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2183\u2184\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005\u3006\u302a-\u302f\u3031-\u3035\u303b\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua672\ua674-\ua67d\ua67f-\ua69d\ua69f-\ua6e5\ua6f0\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua7ad\ua7b0\ua7b1\ua7f7-\ua827\ua840-\ua873\ua880-\ua8c4\ua8e0-\ua8f7\ua8fb\ua90a-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf\ua9e0-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa36\uaa40-\uaa4d\uaa60-\uaa76\uaa7a-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab5f\uab64\uab65\uabc0-\uabea\uabec\uabed\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf870-\uf87f\uf882\uf884-\uf89f\uf8b8\uf8c1-\uf8d6\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe2d\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc/;
+ twttr.txt.regexen.astralLetterAndMarks =
+ /\ud800[\udc00-\udc0b\udc0d-\udc26\udc28-\udc3a\udc3c\udc3d\udc3f-\udc4d\udc50-\udc5d\udc80-\udcfa\uddfd\ude80-\ude9c\udea0-\uded0\udee0\udf00-\udf1f\udf30-\udf40\udf42-\udf49\udf50-\udf7a\udf80-\udf9d\udfa0-\udfc3\udfc8-\udfcf]|\ud801[\udc00-\udc9d\udd00-\udd27\udd30-\udd63\ude00-\udf36\udf40-\udf55\udf60-\udf67]|\ud802[\udc00-\udc05\udc08\udc0a-\udc35\udc37\udc38\udc3c\udc3f-\udc55\udc60-\udc76\udc80-\udc9e\udd00-\udd15\udd20-\udd39\udd80-\uddb7\uddbe\uddbf\ude00-\ude03\ude05\ude06\ude0c-\ude13\ude15-\ude17\ude19-\ude33\ude38-\ude3a\ude3f\ude60-\ude7c\ude80-\ude9c\udec0-\udec7\udec9-\udee6\udf00-\udf35\udf40-\udf55\udf60-\udf72\udf80-\udf91]|\ud803[\udc00-\udc48]|\ud804[\udc00-\udc46\udc7f-\udcba\udcd0-\udce8\udd00-\udd34\udd50-\udd73\udd76\udd80-\uddc4\uddda\ude00-\ude11\ude13-\ude37\udeb0-\udeea\udf01-\udf03\udf05-\udf0c\udf0f\udf10\udf13-\udf28\udf2a-\udf30\udf32\udf33\udf35-\udf39\udf3c-\udf44\udf47\udf48\udf4b-\udf4d\udf57\udf5d-\udf63\udf66-\udf6c\udf70-\udf74]|\ud805[\udc80-\udcc5\udcc7\udd80-\uddb5\uddb8-\uddc0\ude00-\ude40\ude44\ude80-\udeb7]|\ud806[\udca0-\udcdf\udcff\udec0-\udef8]|\ud808[\udc00-\udf98]|\ud80c[\udc00-\udfff]|\ud80d[\udc00-\udc2e]|\ud81a[\udc00-\ude38\ude40-\ude5e\uded0-\udeed\udef0-\udef4\udf00-\udf36\udf40-\udf43\udf63-\udf77\udf7d-\udf8f]|\ud81b[\udf00-\udf44\udf50-\udf7e\udf8f-\udf9f]|\ud82c[\udc00\udc01]|\ud82f[\udc00-\udc6a\udc70-\udc7c\udc80-\udc88\udc90-\udc99\udc9d\udc9e]|\ud834[\udd65-\udd69\udd6d-\udd72\udd7b-\udd82\udd85-\udd8b\uddaa-\uddad\ude42-\ude44]|\ud835[\udc00-\udc54\udc56-\udc9c\udc9e\udc9f\udca2\udca5\udca6\udca9-\udcac\udcae-\udcb9\udcbb\udcbd-\udcc3\udcc5-\udd05\udd07-\udd0a\udd0d-\udd14\udd16-\udd1c\udd1e-\udd39\udd3b-\udd3e\udd40-\udd44\udd46\udd4a-\udd50\udd52-\udea5\udea8-\udec0\udec2-\udeda\udedc-\udefa\udefc-\udf14\udf16-\udf34\udf36-\udf4e\udf50-\udf6e\udf70-\udf88\udf8a-\udfa8\udfaa-\udfc2\udfc4-\udfcb]|\ud83a[\udc00-\udcc4\udcd0-\udcd6]|\ud83b[\ude00-\ude03\ude05-\ude1f\ude21\ude22\ude24\ude27\ude29-\ude32\ude34-\ude37\ude39\ude3b\ude42\ude47\ude49\ude4b\ude4d-\ude4f\ude51\ude52\ude54\ude57\ude59\ude5b\ude5d\ude5f\ude61\ude62\ude64\ude67-\ude6a\ude6c-\ude72\ude74-\ude77\ude79-\ude7c\ude7e\ude80-\ude89\ude8b-\ude9b\udea1-\udea3\udea5-\udea9\udeab-\udebb]|\ud840[\udc00-\udfff]|\ud841[\udc00-\udfff]|\ud842[\udc00-\udfff]|\ud843[\udc00-\udfff]|\ud844[\udc00-\udfff]|\ud845[\udc00-\udfff]|\ud846[\udc00-\udfff]|\ud847[\udc00-\udfff]|\ud848[\udc00-\udfff]|\ud849[\udc00-\udfff]|\ud84a[\udc00-\udfff]|\ud84b[\udc00-\udfff]|\ud84c[\udc00-\udfff]|\ud84d[\udc00-\udfff]|\ud84e[\udc00-\udfff]|\ud84f[\udc00-\udfff]|\ud850[\udc00-\udfff]|\ud851[\udc00-\udfff]|\ud852[\udc00-\udfff]|\ud853[\udc00-\udfff]|\ud854[\udc00-\udfff]|\ud855[\udc00-\udfff]|\ud856[\udc00-\udfff]|\ud857[\udc00-\udfff]|\ud858[\udc00-\udfff]|\ud859[\udc00-\udfff]|\ud85a[\udc00-\udfff]|\ud85b[\udc00-\udfff]|\ud85c[\udc00-\udfff]|\ud85d[\udc00-\udfff]|\ud85e[\udc00-\udfff]|\ud85f[\udc00-\udfff]|\ud860[\udc00-\udfff]|\ud861[\udc00-\udfff]|\ud862[\udc00-\udfff]|\ud863[\udc00-\udfff]|\ud864[\udc00-\udfff]|\ud865[\udc00-\udfff]|\ud866[\udc00-\udfff]|\ud867[\udc00-\udfff]|\ud868[\udc00-\udfff]|\ud869[\udc00-\uded6\udf00-\udfff]|\ud86a[\udc00-\udfff]|\ud86b[\udc00-\udfff]|\ud86c[\udc00-\udfff]|\ud86d[\udc00-\udf34\udf40-\udfff]|\ud86e[\udc00-\udc1d]|\ud87e[\udc00-\ude1d]|\udb40[\udd00-\uddef]/;
+
+ // Generated from unicode_regex/unicode_regex_groups.scala, same as objective c's \p{Nd}
+ twttr.txt.regexen.bmpNumerals =
+ /0-9\u0660-\u0669\u06f0-\u06f9\u07c0-\u07c9\u0966-\u096f\u09e6-\u09ef\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be6-\u0bef\u0c66-\u0c6f\u0ce6-\u0cef\u0d66-\u0d6f\u0de6-\u0def\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29\u1040-\u1049\u1090-\u1099\u17e0-\u17e9\u1810-\u1819\u1946-\u194f\u19d0-\u19d9\u1a80-\u1a89\u1a90-\u1a99\u1b50-\u1b59\u1bb0-\u1bb9\u1c40-\u1c49\u1c50-\u1c59\ua620-\ua629\ua8d0-\ua8d9\ua900-\ua909\ua9d0-\ua9d9\ua9f0-\ua9f9\uaa50-\uaa59\uabf0-\uabf9\uff10-\uff19/;
+ twttr.txt.regexen.astralNumerals =
+ /\ud801[\udca0-\udca9]|\ud804[\udc66-\udc6f\udcf0-\udcf9\udd36-\udd3f\uddd0-\uddd9\udef0-\udef9]|\ud805[\udcd0-\udcd9\ude50-\ude59\udec0-\udec9]|\ud806[\udce0-\udce9]|\ud81a[\ude60-\ude69\udf50-\udf59]|\ud835[\udfce-\udfff]/;
+
+ twttr.txt.regexen.hashtagSpecialChars =
+ /_\u200c\u200d\ua67e\u05be\u05f3\u05f4\uff5e\u301c\u309b\u309c\u30a0\u30fb\u3003\u0f0b\u0f0c\xb7/;
+
+ // A hashtag must contain at least one unicode letter or mark, as well as numbers, underscores, and select special characters.
+ twttr.txt.regexen.hashSigns = /[##]/;
+ twttr.txt.regexen.hashtagAlpha = regexSupplant(
+ /(?:[#{bmpLetterAndMarks}]|(?=#{non_bmp_code_pairs})(?:#{astralLetterAndMarks}))/
+ );
+ twttr.txt.regexen.hashtagAlphaNumeric = regexSupplant(
+ /(?:[#{bmpLetterAndMarks}#{bmpNumerals}#{hashtagSpecialChars}]|(?=#{non_bmp_code_pairs})(?:#{astralLetterAndMarks}|#{astralNumerals}))/
+ );
+ twttr.txt.regexen.endHashtagMatch = regexSupplant(/^(?:#{hashSigns}|:\/\/)/);
+ twttr.txt.regexen.codePoint = /(?:[^\uD800-\uDFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF])/;
+ twttr.txt.regexen.hashtagBoundary = regexSupplant(
+ /(?:^|$|(?!#{hashtagAlphaNumeric}|&)#{codePoint})/
+ );
+ twttr.txt.regexen.validHashtag = regexSupplant(
+ /(#{hashtagBoundary})(#{hashSigns})(?!\uFE0F|\u20E3)(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi
+ );
+
+ // Mention related regex collection
+ twttr.txt.regexen.validMentionPrecedingChars =
+ /(?:^|[^a-zA-Z0-9_!#$%&*@@]|(?:^|[^a-zA-Z0-9_+~.-])(?:rt|RT|rT|Rt):?)/;
+ twttr.txt.regexen.atSigns = /[@@]/;
+ twttr.txt.regexen.validMentionOrList = regexSupplant(
+ '(#{validMentionPrecedingChars})' + // $1: Preceding character
+ '(#{atSigns})' + // $2: At mark
+ '([a-zA-Z0-9_]{1,20})' + // $3: Screen name
+ '(/[a-zA-Z][a-zA-Z0-9_-]{0,24})?', // $4: List (optional)
+ 'g'
+ );
+ twttr.txt.regexen.validReply = regexSupplant(/^(?:#{spaces})*#{atSigns}([a-zA-Z0-9_]{1,20})/);
+ twttr.txt.regexen.endMentionMatch = regexSupplant(/^(?:#{atSigns}|[#{latinAccentChars}]|:\/\/)/);
+
+ // URL related regex collection
+ twttr.txt.regexen.validUrlPrecedingChars = regexSupplant(
+ /(?:[^A-Za-z0-9@@$###{invalid_chars_group}]|^)/
+ );
+ twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars = /[-_.\/]$/;
+ twttr.txt.regexen.invalidDomainChars = stringSupplant(
+ '#{punct}#{spaces_group}#{invalid_chars_group}',
+ twttr.txt.regexen
+ );
+ twttr.txt.regexen.validDomainChars = regexSupplant(/[^#{invalidDomainChars}]/);
+ twttr.txt.regexen.validSubdomain = regexSupplant(
+ /(?:(?:#{validDomainChars}(?:[_-]|#{validDomainChars})*)?#{validDomainChars}\.)/
+ );
+ twttr.txt.regexen.validDomainName = regexSupplant(
+ /(?:(?:#{validDomainChars}(?:-|#{validDomainChars})*)?#{validDomainChars}\.)/
+ );
+ twttr.txt.regexen.validGTLD = regexSupplant(
+ RegExp(
+ '(?:(?:' +
+ '삼성|닷컴|닷넷|香格里拉|餐厅|食品|飞利浦|電訊盈科|集团|购物|谷歌|诺基亚|联通|网络|网站|网店|网址|组织机构|移动|珠宝|点看|游戏|淡马锡|机构|書籍|时尚|新闻|政府|政务|' +
+ '手表|手机|我爱你|慈善|微博|广东|工行|家電|娱乐|大拿|在线|嘉里大酒店|嘉里|商标|商店|商城|公益|公司|八卦|健康|信息|佛山|企业|中文网|中信|世界|ポイント|ファッション|' +
+ 'セール|ストア|コム|グーグル|クラウド|みんな|คอม|संगठन|नेट|कॉम|همراه|موقع|موبايلي|كوم|شبكة|بيتك|بازار|العليان|' +
+ 'ارامكو|ابوظبي|קום|сайт|рус|орг|онлайн|москва|ком|дети|zuerich|zone|zippo|zip|zero|zara|zappos|' +
+ 'yun|youtube|you|yokohama|yoga|yodobashi|yandex|yamaxun|yahoo|yachts|xyz|xxx|xperia|xin|xihuan|' +
+ 'xfinity|xerox|xbox|wtf|wtc|world|works|work|woodside|wolterskluwer|wme|wine|windows|win|' +
+ 'williamhill|wiki|wien|whoswho|weir|weibo|wedding|wed|website|weber|webcam|weatherchannel|' +
+ 'weather|watches|watch|warman|wanggou|wang|walter|wales|vuelos|voyage|voto|voting|vote|' +
+ 'volkswagen|vodka|vlaanderen|viva|vistaprint|vista|vision|virgin|vip|vin|villas|viking|vig|video|' +
+ 'viajes|vet|versicherung|vermögensberatung|vermögensberater|verisign|ventures|vegas|vana|' +
+ 'vacations|ups|uol|uno|university|unicom|ubs|tvs|tushu|tunes|tui|tube|trv|trust|' +
+ 'travelersinsurance|travelers|travelchannel|travel|training|trading|trade|toys|toyota|town|tours|' +
+ 'total|toshiba|toray|top|tools|tokyo|today|tmall|tirol|tires|tips|tiffany|tienda|tickets|theatre|' +
+ 'theater|thd|teva|tennis|temasek|telefonica|telecity|tel|technology|tech|team|tdk|tci|taxi|tax|' +
+ 'tattoo|tatar|tatamotors|taobao|talk|taipei|tab|systems|symantec|sydney|swiss|swatch|suzuki|' +
+ 'surgery|surf|support|supply|supplies|sucks|style|study|studio|stream|store|storage|stockholm|' +
+ 'stcgroup|stc|statoil|statefarm|statebank|starhub|star|stada|srl|spreadbetting|spot|spiegel|' +
+ 'space|soy|sony|song|solutions|solar|sohu|software|softbank|social|soccer|sncf|smile|skype|sky|' +
+ 'skin|ski|site|singles|sina|silk|shriram|show|shouji|shopping|shop|shoes|shiksha|shia|shell|shaw|' +
+ 'sharp|shangrila|sfr|sexy|sex|sew|seven|services|sener|select|seek|security|seat|scot|scor|' +
+ 'science|schwarz|schule|school|scholarships|schmidt|schaeffler|scb|sca|sbs|sbi|saxo|save|sas|' +
+ 'sarl|sapo|sap|sanofi|sandvikcoromant|sandvik|samsung|salon|sale|sakura|safety|safe|saarland|' +
+ 'ryukyu|rwe|run|ruhr|rsvp|room|rodeo|rocks|rocher|rip|rio|ricoh|richardli|rich|rexroth|reviews|' +
+ 'review|restaurant|rest|republican|report|repair|rentals|rent|ren|reit|reisen|reise|rehab|' +
+ 'redumbrella|redstone|red|recipes|realty|realtor|realestate|read|racing|quest|quebec|qpon|pwc|' +
+ 'pub|protection|property|properties|promo|progressive|prof|productions|prod|pro|prime|press|' +
+ 'praxi|post|porn|politie|poker|pohl|pnc|plus|plumbing|playstation|play|place|pizza|pioneer|pink|' +
+ 'ping|pin|pid|pictures|pictet|pics|piaget|physio|photos|photography|photo|philips|pharmacy|pet|' +
+ 'pccw|passagens|party|parts|partners|pars|paris|panerai|pamperedchef|page|ovh|ott|otsuka|osaka|' +
+ 'origins|orientexpress|organic|org|orange|oracle|ooo|online|onl|ong|one|omega|ollo|olayangroup|' +
+ 'olayan|okinawa|office|obi|nyc|ntt|nrw|nra|nowtv|nowruz|now|norton|northwesternmutual|nokia|' +
+ 'nissay|nissan|ninja|nikon|nico|nhk|ngo|nfl|nexus|nextdirect|next|news|new|neustar|network|' +
+ 'netflix|netbank|net|nec|navy|natura|name|nagoya|nadex|mutuelle|mutual|museum|mtr|mtpc|mtn|' +
+ 'movistar|movie|mov|motorcycles|moscow|mortgage|mormon|montblanc|money|monash|mom|moi|moe|moda|' +
+ 'mobily|mobi|mma|mls|mlb|mitsubishi|mit|mini|mil|microsoft|miami|metlife|meo|menu|men|memorial|' +
+ 'meme|melbourne|meet|media|med|mba|mattel|marriott|markets|marketing|market|mango|management|man|' +
+ 'makeup|maison|maif|madrid|luxury|luxe|lupin|ltda|ltd|love|lotto|lotte|london|lol|locus|locker|' +
+ 'loans|loan|lixil|living|live|lipsy|link|linde|lincoln|limo|limited|like|lighting|lifestyle|' +
+ 'lifeinsurance|life|lidl|liaison|lgbt|lexus|lego|legal|leclerc|lease|lds|lawyer|law|latrobe|lat|' +
+ 'lasalle|lanxess|landrover|land|lancaster|lamer|lamborghini|lacaixa|kyoto|kuokgroup|kred|krd|kpn|' +
+ 'kpmg|kosher|komatsu|koeln|kiwi|kitchen|kindle|kinder|kim|kia|kfh|kerryproperties|kerrylogistics|' +
+ 'kerryhotels|kddi|kaufen|juegos|jprs|jpmorgan|joy|jot|joburg|jobs|jnj|jmp|jll|jlc|jewelry|jetzt|' +
+ 'jcp|jcb|java|jaguar|iwc|itv|itau|istanbul|ist|ismaili|iselect|irish|ipiranga|investments|' +
+ 'international|int|insure|insurance|institute|ink|ing|info|infiniti|industries|immobilien|immo|' +
+ 'imdb|imamat|ikano|iinet|ifm|icu|ice|icbc|ibm|hyundai|htc|hsbc|how|house|hotmail|hoteles|hosting|' +
+ 'host|horse|honda|homes|homedepot|holiday|holdings|hockey|hkt|hiv|hitachi|hisamitsu|hiphop|hgtv|' +
+ 'hermes|here|helsinki|help|healthcare|health|hdfcbank|haus|hangout|hamburg|guru|guitars|guide|' +
+ 'guge|gucci|guardian|group|gripe|green|gratis|graphics|grainger|gov|got|gop|google|goog|goodyear|' +
+ 'goo|golf|goldpoint|gold|godaddy|gmx|gmo|gmbh|gmail|globo|global|gle|glass|giving|gives|gifts|' +
+ 'gift|ggee|genting|gent|gea|gdn|gbiz|garden|games|game|gallup|gallo|gallery|gal|fyi|futbol|' +
+ 'furniture|fund|fujitsu|ftr|frontier|frontdoor|frogans|frl|fresenius|fox|foundation|forum|' +
+ 'forsale|forex|ford|football|foodnetwork|foo|fly|flsmidth|flowers|florist|flir|flights|flickr|' +
+ 'fitness|fit|fishing|fish|firmdale|firestone|fire|financial|finance|final|film|ferrero|feedback|' +
+ 'fedex|fast|fashion|farmers|farm|fans|fan|family|faith|fairwinds|fail|fage|extraspace|express|' +
+ 'exposed|expert|exchange|everbank|events|eus|eurovision|estate|esq|erni|ericsson|equipment|epson|' +
+ 'epost|enterprises|engineering|engineer|energy|emerck|email|education|edu|edeka|eat|earth|dvag|' +
+ 'durban|dupont|dunlop|dubai|dtv|drive|download|dot|doosan|domains|doha|dog|docs|dnp|discount|' +
+ 'directory|direct|digital|diet|diamonds|dhl|dev|design|desi|dentist|dental|democrat|delta|' +
+ 'deloitte|dell|delivery|degree|deals|dealer|deal|dds|dclk|day|datsun|dating|date|dance|dad|dabur|' +
+ 'cyou|cymru|cuisinella|csc|cruises|crs|crown|cricket|creditunion|creditcard|credit|courses|' +
+ 'coupons|coupon|country|corsica|coop|cool|cookingchannel|cooking|contractors|contact|consulting|' +
+ 'construction|condos|comsec|computer|compare|company|community|commbank|comcast|com|cologne|' +
+ 'college|coffee|codes|coach|clubmed|club|cloud|clothing|clinique|clinic|click|cleaning|claims|' +
+ 'cityeats|city|citic|cisco|circle|cipriani|church|chrome|christmas|chloe|chintai|cheap|chat|' +
+ 'chase|channel|chanel|cfd|cfa|cern|ceo|center|ceb|cbre|cbn|cba|catering|cat|casino|cash|casa|' +
+ 'cartier|cars|careers|career|care|cards|caravan|car|capital|capetown|canon|cancerresearch|camp|' +
+ 'camera|cam|call|cal|cafe|cab|bzh|buzz|buy|business|builders|build|bugatti|budapest|brussels|' +
+ 'brother|broker|broadway|bridgestone|bradesco|boutique|bot|bostik|bosch|boots|book|boo|bond|bom|' +
+ 'boehringer|boats|bnpparibas|bnl|bmw|bms|blue|bloomberg|blog|blanco|blackfriday|black|biz|bio|' +
+ 'bingo|bing|bike|bid|bible|bharti|bet|best|berlin|bentley|beer|beats|bcn|bcg|bbva|bbc|bayern|' +
+ 'bauhaus|bargains|barefoot|barclays|barclaycard|barcelona|bar|bank|band|baidu|baby|azure|axa|aws|' +
+ 'avianca|autos|auto|author|audio|audible|audi|auction|attorney|associates|asia|arte|art|arpa|' +
+ 'army|archi|aramco|aquarelle|apple|app|apartments|anz|anquan|android|analytics|amsterdam|amica|' +
+ 'alstom|alsace|ally|allfinanz|alipay|alibaba|akdn|airtel|airforce|airbus|aig|agency|agakhan|afl|' +
+ 'aetna|aero|aeg|adult|ads|adac|actor|active|aco|accountants|accountant|accenture|academy|' +
+ 'abudhabi|abogado|able|abbvie|abbott|abb|aarp|aaa|onion' +
+ ')(?=[^0-9a-zA-Z@]|$))'
+ )
+ );
+ twttr.txt.regexen.validCCTLD = regexSupplant(
+ RegExp(
+ '(?:(?:' +
+ '한국|香港|澳門|新加坡|台灣|台湾|中國|中国|გე|ไทย|ලංකා|ഭാരതം|ಭಾರತ|భారత్|சிங்கப்பூர்|இலங்கை|இந்தியா|ଭାରତ|ભારત|ਭਾਰਤ|' +
+ 'ভাৰত|ভারত|বাংলা|भारत|پاکستان|مليسيا|مصر|قطر|فلسطين|عمان|عراق|سورية|سودان|تونس|بھارت|ایران|' +
+ 'امارات|المغرب|السعودية|الجزائر|الاردن|հայ|қаз|укр|срб|рф|мон|мкд|ею|бел|бг|ελ|zw|zm|za|yt|ye|ws|' +
+ 'wf|vu|vn|vi|vg|ve|vc|va|uz|uy|us|um|uk|ug|ua|tz|tw|tv|tt|tr|tp|to|tn|tm|tl|tk|tj|th|tg|tf|td|tc|' +
+ 'sz|sy|sx|sv|su|st|ss|sr|so|sn|sm|sl|sk|sj|si|sh|sg|se|sd|sc|sb|sa|rw|ru|rs|ro|re|qa|py|pw|pt|ps|' +
+ 'pr|pn|pm|pl|pk|ph|pg|pf|pe|pa|om|nz|nu|nr|np|no|nl|ni|ng|nf|ne|nc|na|mz|my|mx|mw|mv|mu|mt|ms|mr|' +
+ 'mq|mp|mo|mn|mm|ml|mk|mh|mg|mf|me|md|mc|ma|ly|lv|lu|lt|ls|lr|lk|li|lc|lb|la|kz|ky|kw|kr|kp|kn|km|' +
+ 'ki|kh|kg|ke|jp|jo|jm|je|it|is|ir|iq|io|in|im|il|ie|id|hu|ht|hr|hn|hm|hk|gy|gw|gu|gt|gs|gr|gq|gp|' +
+ 'gn|gm|gl|gi|gh|gg|gf|ge|gd|gb|ga|fr|fo|fm|fk|fj|fi|eu|et|es|er|eh|eg|ee|ec|dz|do|dm|dk|dj|de|cz|' +
+ 'cy|cx|cw|cv|cu|cr|co|cn|cm|cl|ck|ci|ch|cg|cf|cd|cc|ca|bz|by|bw|bv|bt|bs|br|bq|bo|bn|bm|bl|bj|bi|' +
+ 'bh|bg|bf|be|bd|bb|ba|az|ax|aw|au|at|as|ar|aq|ao|an|am|al|ai|ag|af|ae|ad|ac' +
+ ')(?=[^0-9a-zA-Z@]|$))'
+ )
+ );
+ twttr.txt.regexen.validPunycode = /(?:xn--[0-9a-z]+)/;
+ twttr.txt.regexen.validSpecialCCTLD = /(?:(?:co|tv)(?=[^0-9a-zA-Z@]|$))/;
+ twttr.txt.regexen.validDomain = regexSupplant(
+ /(?:#{validSubdomain}*#{validDomainName}(?:#{validGTLD}|#{validCCTLD}|#{validPunycode}))/
+ );
+ twttr.txt.regexen.validAsciiDomain = regexSupplant(
+ /(?:(?:[\-a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/gi
+ );
+ twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/i);
+ twttr.txt.regexen.validSpecialShortDomain = regexSupplant(
+ /^#{validDomainName}#{validSpecialCCTLD}$/i
+ );
+ twttr.txt.regexen.validPortNumber = /[0-9]+/;
+ twttr.txt.regexen.cyrillicLettersAndMarks = /\u0400-\u04FF/;
+ twttr.txt.regexen.validGeneralUrlPathChars = regexSupplant(
+ /[a-z#{cyrillicLettersAndMarks}0-9!\*';:=\+,\.\$\/%#\[\]\-_~@\|{latinAccentChars}]/i
+ );
+ // Allow URL paths to contain up to two nested levels of balanced parens
+ // 1. Used in Wikipedia URLs like /Primer_(film)
+ // 2. Used in IIS sessions like /S(dfd346)/
+ // 3. Used in Rdio URLs like /track/We_Up_(Album_Version_(Edited))/
+ twttr.txt.regexen.validUrlBalancedParens = regexSupplant(
+ '\\(' +
+ '(?:' +
+ '#{validGeneralUrlPathChars}+' +
+ '|' +
+ // allow one nested level of balanced parentheses
+ '(?:' +
+ '#{validGeneralUrlPathChars}*' +
+ '\\(' +
+ '#{validGeneralUrlPathChars}+' +
+ '\\)' +
+ '#{validGeneralUrlPathChars}*' +
+ ')' +
+ ')' +
+ '\\)',
+ 'i'
+ );
+ // Valid end-of-path chracters (so /foo. does not gobble the period).
+ // 1. Allow = for empty URL parameters and other URL-join artifacts
+ twttr.txt.regexen.validUrlPathEndingChars = regexSupplant(
+ /[\+\-a-z#{cyrillicLettersAndMarks}0-9=_#\/#{latinAccentChars}]|(?:#{validUrlBalancedParens})/i
+ );
+ // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/
+ twttr.txt.regexen.validUrlPath = regexSupplant(
+ '(?:' +
+ '(?:' +
+ '#{validGeneralUrlPathChars}*' +
+ '(?:#{validUrlBalancedParens}#{validGeneralUrlPathChars}*)*' +
+ '#{validUrlPathEndingChars}' +
+ ')|(?:@#{validGeneralUrlPathChars}+/)' +
+ ')',
+ 'i'
+ );
+
+ twttr.txt.regexen.validUrlQueryChars = /[a-z0-9!?\*'@\(\);:&=\+\$\/%#\[\]\-_\.,~|]/i;
+ twttr.txt.regexen.validUrlQueryEndingChars = /[a-z0-9_&=#\/]/i;
+ twttr.txt.regexen.extractUrl = regexSupplant(
+ '(' + // $1 total match
+ '(#{validUrlPrecedingChars})' + // $2 Preceeding chracter
+ '(' + // $3 URL
+ '(https?:\\/\\/)?' + // $4 Protocol (optional)
+ '(#{validDomain})' + // $5 Domain(s)
+ '(?::(#{validPortNumber}))?' + // $6 Port number (optional)
+ '(\\/#{validUrlPath}*)?' + // $7 URL Path
+ '(\\?#{validUrlQueryChars}*#{validUrlQueryEndingChars})?' + // $8 Query String
+ ')' +
+ ')',
+ 'gi'
+ );
+
+ twttr.txt.regexen.validTcoUrl = /^https?:\/\/t\.co\/[a-z0-9]+/i;
+ twttr.txt.regexen.urlHasProtocol = /^https?:\/\//i;
+ twttr.txt.regexen.urlHasHttps = /^https:\/\//i;
+
+ // cashtag related regex
+ twttr.txt.regexen.cashtag = /[a-z]{1,6}(?:[._][a-z]{1,2})?/i;
+ twttr.txt.regexen.validCashtag = regexSupplant(
+ '(^|#{spaces})(\\$)(#{cashtag})(?=$|\\s|[#{punct}])',
+ 'gi'
+ );
+
+ // These URL validation pattern strings are based on the ABNF from RFC 3986
+ twttr.txt.regexen.validateUrlUnreserved = /[a-z\u0400-\u04FF0-9\-._~]/i;
+ twttr.txt.regexen.validateUrlPctEncoded = /(?:%[0-9a-f]{2})/i;
+ twttr.txt.regexen.validateUrlSubDelims = /[!$&'()*+,;=]/i;
+ twttr.txt.regexen.validateUrlPchar = regexSupplant(
+ '(?:' +
+ '#{validateUrlUnreserved}|' +
+ '#{validateUrlPctEncoded}|' +
+ '#{validateUrlSubDelims}|' +
+ '[:|@]' +
+ ')',
+ 'i'
+ );
+
+ twttr.txt.regexen.validateUrlScheme = /(?:[a-z][a-z0-9+\-.]*)/i;
+ twttr.txt.regexen.validateUrlUserinfo = regexSupplant(
+ '(?:' +
+ '#{validateUrlUnreserved}|' +
+ '#{validateUrlPctEncoded}|' +
+ '#{validateUrlSubDelims}|' +
+ ':' +
+ ')*',
+ 'i'
+ );
+
+ twttr.txt.regexen.validateUrlDecOctet =
+ /(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9]{2})|(?:2[0-4][0-9])|(?:25[0-5]))/i;
+ twttr.txt.regexen.validateUrlIpv4 = regexSupplant(
+ /(?:#{validateUrlDecOctet}(?:\.#{validateUrlDecOctet}){3})/i
+ );
+
+ // Punting on real IPv6 validation for now
+ twttr.txt.regexen.validateUrlIpv6 = /(?:\[[a-f0-9:\.]+\])/i;
+
+ // Also punting on IPvFuture for now
+ twttr.txt.regexen.validateUrlIp = regexSupplant(
+ '(?:' + '#{validateUrlIpv4}|' + '#{validateUrlIpv6}' + ')',
+ 'i'
+ );
+
+ // This is more strict than the rfc specifies
+ twttr.txt.regexen.validateUrlSubDomainSegment = /(?:[a-z0-9](?:[a-z0-9_\-]*[a-z0-9])?)/i;
+ twttr.txt.regexen.validateUrlDomainSegment = /(?:[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?)/i;
+ twttr.txt.regexen.validateUrlDomainTld = /(?:[a-z](?:[a-z0-9\-]*[a-z0-9])?)/i;
+ twttr.txt.regexen.validateUrlDomain = regexSupplant(
+ /(?:(?:#{validateUrlSubDomainSegment]}\.)*(?:#{validateUrlDomainSegment]}\.)#{validateUrlDomainTld})/i
+ );
+
+ twttr.txt.regexen.validateUrlHost = regexSupplant(
+ '(?:' + '#{validateUrlIp}|' + '#{validateUrlDomain}' + ')',
+ 'i'
+ );
+
+ // Unencoded internationalized domains - this doesn't check for invalid UTF-8 sequences
+ twttr.txt.regexen.validateUrlUnicodeSubDomainSegment =
+ /(?:(?:[a-z0-9]|[^\u0000-\u007f])(?:(?:[a-z0-9_\-]|[^\u0000-\u007f])*(?:[a-z0-9]|[^\u0000-\u007f]))?)/i;
+ twttr.txt.regexen.validateUrlUnicodeDomainSegment =
+ /(?:(?:[a-z0-9]|[^\u0000-\u007f])(?:(?:[a-z0-9\-]|[^\u0000-\u007f])*(?:[a-z0-9]|[^\u0000-\u007f]))?)/i;
+ twttr.txt.regexen.validateUrlUnicodeDomainTld =
+ /(?:(?:[a-z]|[^\u0000-\u007f])(?:(?:[a-z0-9\-]|[^\u0000-\u007f])*(?:[a-z0-9]|[^\u0000-\u007f]))?)/i;
+ twttr.txt.regexen.validateUrlUnicodeDomain = regexSupplant(
+ /(?:(?:#{validateUrlUnicodeSubDomainSegment}\.)*(?:#{validateUrlUnicodeDomainSegment}\.)#{validateUrlUnicodeDomainTld})/i
+ );
+
+ twttr.txt.regexen.validateUrlUnicodeHost = regexSupplant(
+ '(?:' + '#{validateUrlIp}|' + '#{validateUrlUnicodeDomain}' + ')',
+ 'i'
+ );
+
+ twttr.txt.regexen.validateUrlPort = /[0-9]{1,5}/;
+
+ twttr.txt.regexen.validateUrlUnicodeAuthority = regexSupplant(
+ '(?:(#{validateUrlUserinfo})@)?' + // $1 userinfo
+ '(#{validateUrlUnicodeHost})' + // $2 host
+ '(?::(#{validateUrlPort}))?', //$3 port
+ 'i'
+ );
+
+ twttr.txt.regexen.validateUrlAuthority = regexSupplant(
+ '(?:(#{validateUrlUserinfo})@)?' + // $1 userinfo
+ '(#{validateUrlHost})' + // $2 host
+ '(?::(#{validateUrlPort}))?', // $3 port
+ 'i'
+ );
+
+ twttr.txt.regexen.validateUrlPath = regexSupplant(/(\/#{validateUrlPchar}*)*/i);
+ twttr.txt.regexen.validateUrlQuery = regexSupplant(/(#{validateUrlPchar}|\/|\?)*/i);
+ twttr.txt.regexen.validateUrlFragment = regexSupplant(/(#{validateUrlPchar}|\/|\?)*/i);
+
+ // Modified version of RFC 3986 Appendix B
+ twttr.txt.regexen.validateUrlUnencoded = regexSupplant(
+ '^' + // Full URL
+ '(?:' +
+ '([^:/?#]+):\\/\\/' + // $1 Scheme
+ ')?' +
+ '([^/?#]*)' + // $2 Authority
+ '([^?#]*)' + // $3 Path
+ '(?:' +
+ '\\?([^#]*)' + // $4 Query
+ ')?' +
+ '(?:' +
+ '#(.*)' + // $5 Fragment
+ ')?$',
+ 'i'
+ );
+
+ // Default CSS class for auto-linked lists (along with the url class)
+ var DEFAULT_LIST_CLASS = 'tweet-url list-slug';
+ // Default CSS class for auto-linked usernames (along with the url class)
+ var DEFAULT_USERNAME_CLASS = 'tweet-url username';
+ // Default CSS class for auto-linked hashtags (along with the url class)
+ var DEFAULT_HASHTAG_CLASS = 'tweet-url hashtag';
+ // Default CSS class for auto-linked cashtags (along with the url class)
+ var DEFAULT_CASHTAG_CLASS = 'tweet-url cashtag';
+ // Options which should not be passed as HTML attributes
+ var OPTIONS_NOT_ATTRIBUTES = {
+ urlClass: true,
+ listClass: true,
+ usernameClass: true,
+ hashtagClass: true,
+ cashtagClass: true,
+ usernameUrlBase: true,
+ listUrlBase: true,
+ hashtagUrlBase: true,
+ cashtagUrlBase: true,
+ usernameUrlBlock: true,
+ listUrlBlock: true,
+ hashtagUrlBlock: true,
+ linkUrlBlock: true,
+ usernameIncludeSymbol: true,
+ suppressLists: true,
+ suppressNoFollow: true,
+ targetBlank: true,
+ suppressDataScreenName: true,
+ urlEntities: true,
+ symbolTag: true,
+ textWithSymbolTag: true,
+ urlTarget: true,
+ invisibleTagAttrs: true,
+ linkAttributeBlock: true,
+ linkTextBlock: true,
+ htmlEscapeNonEntities: true,
+ };
- }
- },
- /* 38 *//*OWN Module! To show questions of one PDF-Page on the right side*/
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.renderQuestions=renderQuestions;
- exports.renderAllQuestions = renderAllQuestions;
- var _event=__webpack_require__(4);
- var _shortText=__webpack_require__(39);
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
-
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
-
- /**
- * This function renders on the right side the questions of all annotations of a specific page.
- *
- * @param {type} documentId the Id of the pdf
- * @param {type} pageNumber the requested pagenumber
- * @param {type} activeCall specifies that the function was called by click on button with id='questionsOnThisPage'
- * @return {undefined}
- */
- function renderQuestions (documentId, pageNumber, activeCall = null){
- let pattern = $('#searchPattern').val();
- _PDFJSAnnotate2.default.getStoreAdapter().getQuestions(documentId,pageNumber, pattern).then(function(questions){
- let container = document.querySelector('.comment-list-container');
- let title = $('#comment-wrapper > h4')[0];
- if(pattern === '') {
- title.innerHTML = M.util.get_string('questionstitle','pdfannotator') + ' ' + pageNumber;
- } else {
- title.innerHTML = M.util.get_string('searchresults','pdfannotator');
- }
- var button1 = document.getElementById('allQuestions'); // to be found in index template
- button1.style.display = 'inline';
- var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
- button2.style.display = 'none';
-
- //only if form is not shown, otherwise the questions should not be rendered
- if(document.querySelector('.comment-list-form').style.display === 'none' || activeCall){
-
- if(activeCall) {
- document.querySelector('.comment-list-form').style.display = 'none';
- }
- container.innerHTML = '';
+ var BOOLEAN_ATTRIBUTES = { disabled: true, readonly: true, multiple: true, checked: true };
- if(questions.length < 1){
- if (pattern === '') {
- container.innerHTML = M.util.get_string('noquestions','pdfannotator');
- } else {
- container.innerHTML = M.util.get_string('nosearchresults','pdfannotator');
- }
- }else{
- for(let id in questions){
- let question = questions[id];
- let questionWrapper = document.createElement('div');
- questionWrapper.className = 'chat-message comment-list-item questions';
- let questionText = document.createElement('span');
- questionText.className = 'more';
- questionText.innerHTML = question.content;
- let questionAnswercount = document.createElement('span');
- questionAnswercount.innerHTML = question.answercount;
- questionAnswercount.className = 'questionanswercount';
-
- let questionPix = document.createElement('i');
- questionPix.classList = "icon fa fa-comment fa-fw questionanswercount";
- questionPix.title = M.util.get_string('answers', 'pdfannotator');
-
- let iconWrapper = document.createElement('div');
- iconWrapper.className = 'icon-wrapper';
-
- if (question.solved != 0){
- let solvedPix = document.createElement('i');
- solvedPix.classList = "icon fa fa-lock fa-fw solvedicon";
- solvedPix.title = M.util.get_string('questionSolved', 'pdfannotator');
- iconWrapper.appendChild(solvedPix);
- }
-
- iconWrapper.appendChild(questionPix);
- iconWrapper.appendChild(questionAnswercount);
-
- questionWrapper.appendChild(questionText);
- questionWrapper.appendChild(iconWrapper);
-
- container.appendChild(questionWrapper);
- (function(questionObj,questionDOM){
- questionDOM.onclick = function(e){
- if(questionObj.page !== undefined && questionObj.page !== $('#currentPage').val()) {
- $('#content-wrapper').scrollTop(document.getElementById('pageContainer'+questionObj.page).offsetTop);
- }
- (function scrollToAnnotation(annotationid, pageNumber) {
- let target = $('[data-pdf-annotate-id='+annotationid+']')[0];
- // if scrolled to a different page (see a few lines above) and page isn't loaded yet; wait and try again
- if (target === undefined) {
- setTimeout(function() {scrollToAnnotation(annotationid, pageNumber);}, 200);
- } else {
- _event.fireEvent('annotation:click',target);
- var targetDiv = $('[data-target-id='+annotationid+']')[0];
- var contentWrapper = $('#content-wrapper');
- if(pageNumber === undefined) {
- pageNumber = $('#currentPage').val();
- }
- var pageOffset = document.getElementById('pageContainer'+pageNumber).offsetTop;
- contentWrapper.scrollTop(pageOffset + targetDiv.offsetTop - 100);
- contentWrapper.scrollLeft(targetDiv.offsetLeft - contentWrapper.width() + 100);
- }
- })(questionObj.annotationid, questionObj.page);
- };
- })(question,questionWrapper);
+ // Simple object cloning function for simple objects
+ function clone(o) {
+ var r = {};
+ for (var k in o) {
+ if (o.hasOwnProperty(k)) {
+ r[k] = o[k];
}
- // comment overview column
- _shortText.mathJaxAndShortenText('.more', 4);
- }
- }
- }, function (err){
- notification.addNotification({
- message: M.util.get_string('error:getQuestions', 'pdfannotator'),
- type: "error"
- });
- });
- }
-
-
-
- /**
- * Function renders overview column for all questions in this document
- *
- * @param {type} documentId
- * @return {undefined}
- */
- function renderAllQuestions (documentId) {
- _PDFJSAnnotate2.default.getStoreAdapter().getQuestions(documentId).then(function(questions){
- let container = document.querySelector('.comment-list-container');
- let title = $('#comment-wrapper > h4')[0];
- title.innerHTML = M.util.get_string('allquestionstitle','pdfannotator') + ' ' + questions.pdfannotatorname;
-
- container.innerHTML = '';
-
- questions = questions.questions;
-
- var button1 = document.getElementById('allQuestions'); // to be found in index.mustache template
- button1.style.display = 'none';
- var button2 = document.getElementById('questionsOnThisPage'); // to be found in index.mustache template
- button2.style.display = 'inline';
-
- if(document.querySelector('.comment-list-form').style.display !== 'none') {
- document.querySelector('.comment-list-form').style.display = 'none';
- }
-
- if(questions.length < 1){
- container.innerHTML = M.util.get_string('noquestions_view','pdfannotator');
- }else{
- for(var page in questions){
- let questionWrapper = document.createElement('div');
- questionWrapper.className = 'chat-message comment-list-item questions page';
- let questionText = document.createElement('span');
- questionText.innerHTML = M.util.get_string('page', 'pdfannotator')+ ' ' +page;
- let questionAnswercount = document.createElement('span');
- questionAnswercount.innerHTML = questions[page].length;
- questionAnswercount.className = 'questionanswercount';
-
- let questionPix = document.createElement('i');
- questionPix.classList = "icon fa fa-comments fa-fw questionanswercount";
- questionPix.title = M.util.get_string('questionsimgtitle','pdfannotator');
- let iconWrapper = document.createElement('div');
- iconWrapper.classList = "icon-wrapper";
- iconWrapper.appendChild(questionAnswercount);
- iconWrapper.appendChild(questionPix);
- questionWrapper.appendChild(questionText);
- questionWrapper.appendChild(iconWrapper);
- container.appendChild(questionWrapper);
- (function(page,questionDOM){
- questionDOM.onclick = function(e){
- $('#content-wrapper').scrollTop(document.getElementById('pageContainer'+page).offsetTop);
- var pageinputfield = document.getElementById('currentPage');
- if(pageinputfield.value === page) {
- renderQuestions(documentId, page, 1);
- }
-
- };
- })(page,questionWrapper);
}
- }
-
- }, function (err){
- notification.addNotification({
- message: M.util.get_string('error:getAllQuestions', 'pdfannotator'),
- type: "error"
- });
- });
- }
- },
- /* 39 *//*OWN Module! To shorten a specific text*/
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.shortenText=shortenText;
- exports.shortenTextDynamic=shortenTextDynamic;
- exports.mathJaxAndShortenText=mathJaxAndShortenText;
-
- /**
- * Shorten display of any report or question to a maximum of 80 characters and display
- * a 'view more'/'view less' link
- *
- * Copyright 2013 Viral Patel and other contributors
- * http://viralpatel.net
- *
- * slightly modified by RWTH Aachen in 2018
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * @param {type} selector
- * @param {type} maxLength
- * @param {type} ellipsesText
- * @returns {undefined}
- */
- function shortenText(selector, maxLength = 80, ellipsesText = '...'){
- var showChar = maxLength;
- var moretext = M.util.get_string('showmore', 'pdfannotator');
- var lesstext = M.util.get_string('showless', 'pdfannotator');
- $(selector).each(function() {
- if($(this).children().first().attr('id')=== 'content') { return; }
- var content = $(this).html();
- //determine if the message should be shortend, here only the characters without the html should be considered
- var contentWithoudTags = this.innerText;
- if(contentWithoudTags.length > (showChar + ellipsesText.length)) {
- //for the clip-function you should import textclipper.js
- var c = clip(unescape(content),showChar, {html:true, indicator: ''});//clipped content, the indicator is nothing, because we add the ellipsesText manually in the html
- var h = content; // complete content
- var html = '' + c + '' + ellipsesText+ ' ' + h + ''+c+' ' + moretext + '';
- $(this).html(html);
+
+ return r;
}
- });
+ twttr.txt.tagAttrs = function (attributes) {
+ var htmlAttrs = '';
+ for (var k in attributes) {
+ var v = attributes[k];
+ if (BOOLEAN_ATTRIBUTES[k]) {
+ v = v ? k : null;
+ }
+ if (v == null) continue;
+ htmlAttrs +=
+ ' ' + twttr.txt.htmlEscape(k) + '="' + twttr.txt.htmlEscape(v.toString()) + '"';
+ }
+ return htmlAttrs;
+ };
+
+ twttr.txt.linkToText = function (entity, text, attributes, options) {
+ if (!options.suppressNoFollow) {
+ attributes.rel = 'nofollow';
+ }
+ // if linkAttributeBlock is specified, call it to modify the attributes
+ if (options.linkAttributeBlock) {
+ options.linkAttributeBlock(entity, attributes);
+ }
+ // if linkTextBlock is specified, call it to get a new/modified link text
+ if (options.linkTextBlock) {
+ text = options.linkTextBlock(entity, text);
+ }
+ var d = {
+ text: text,
+ attr: twttr.txt.tagAttrs(attributes),
+ };
+ return stringSupplant('#{text}', d);
+ };
- $(selector+" .morelink").click(function(){
- if($(this).hasClass("less")) {
- $(this).removeClass("less");
- $(this).html(moretext); // entspricht innerHTML
- $(this).parent().prev().prev().html($(this).prev().html());
- // $(selector+" #content").html($(selector+" .morecontent .clippedContent").html());
+ twttr.txt.linkToTextWithSymbol = function (entity, symbol, text, attributes, options) {
+ var taggedSymbol = options.symbolTag
+ ? '<' + options.symbolTag + '>' + symbol + '' + options.symbolTag + '>'
+ : symbol;
+ text = twttr.txt.htmlEscape(text);
+ var taggedText = options.textWithSymbolTag
+ ? '<' + options.textWithSymbolTag + '>' + text + '' + options.textWithSymbolTag + '>'
+ : text;
+
+ if (options.usernameIncludeSymbol || !symbol.match(twttr.txt.regexen.atSigns)) {
+ return twttr.txt.linkToText(entity, taggedSymbol + taggedText, attributes, options);
} else {
- $(this).addClass("less");
- $(this).html(lesstext);
- $(this).parent().prev().prev().html($(this).prev().prev().html());
- // $(selector+" #content").html($(selector+" .morecontent .completeContent").html());
+ return taggedSymbol + twttr.txt.linkToText(entity, taggedText, attributes, options);
}
- $(this).parent().prev().toggle(); //span .moreellipses
- return false;
- });
-
- };
-
- /**
- * This function shortens the text. The length of the string is determined by the size of the parent and the given divisor.
- * @param {type} parentselector The selector of which the size should be referenced
- * @param {type} selector The selector where the text should be shortened
- * @param {type} divisor The textlength is the size / divisior
- * @param {type} ellipsesText text which should be displayed to point out that the text was shortened
- * @returns {undefined}
- */
- function shortenTextDynamic(parentselector, selector, divisor){
- if (parentselector === null) {
- let elem = document.querySelector(selector);
- if (elem !== null) {
- var parent = elem.parentElement;
- } else {
- return;
- }
- } else {
- var parent = document.querySelector(parentselector);
- }
- if (parent !== null) {
- let minCharacters = 80;
- let maxCharacters = 120;
- let nCharactersToDisplay = parent.offsetWidth / divisor;
-
- if (nCharactersToDisplay < minCharacters) {
- shortenText(selector);
- } else if (nCharactersToDisplay > maxCharacters) {
- nCharactersToDisplay = maxCharacters;
- shortenText(selector, nCharactersToDisplay);
- } else {
- shortenText(selector, nCharactersToDisplay);
- }
- }else{
- shortenText(selector); // Default: 80 characters
- }
- }
-
- /**
- * Renders MathJax and calls shortenText() afterwards.
- * @param {type} selector
- * @param {type} divisor
- * @param {type} click
- * @returns {undefined}
- */
- function mathJaxAndShortenText(selector, divisor, click = false){
- if (typeof(MathJax) !== "undefined") {
- // Add the Mathjax-function and the shortenText function to the queue.
- MathJax.Hub.Queue(['Typeset', MathJax.Hub], [function(){
- shortenTextDynamic(null, selector, divisor);
- if (click) {
- $(selector+" .morelink").click();
- }
- }, null]);
- } else {
- shortenTextDynamic(null, selector, divisor);
- if (click) {
- $(selector+" .morelink").click();
+ };
+
+ twttr.txt.linkToHashtag = function (entity, text, options) {
+ var hash = text.substring(entity.indices[0], entity.indices[0] + 1);
+ var hashtag = twttr.txt.htmlEscape(entity.hashtag);
+ var attrs = clone(options.htmlAttrs || {});
+ attrs.href = options.hashtagUrlBase + hashtag;
+ attrs.title = '#' + hashtag;
+ attrs['class'] = options.hashtagClass;
+ if (hashtag.charAt(0).match(twttr.txt.regexen.rtl_chars)) {
+ attrs['class'] += ' rtl';
}
- }
- }
-
- },
- /* 40 *//*OWN Module! To load new annotations (Synchronisation between sessions)*/
- /***/function(module,exports,__webpack_require__){
- 'use strict';
- Object.defineProperty(exports,"__esModule",{value:true});
- exports.load = loadNewAnnotations;
- var _event=__webpack_require__(4);
- var _shortText=__webpack_require__(39);
- var _PDFJSAnnotate=__webpack_require__(1);
- var _PDFJSAnnotate2=_interopRequireDefault(_PDFJSAnnotate);
- var _appendChild=__webpack_require__(11);
- var _appendChild2=_interopRequireDefault(_appendChild);
- function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}
- var _utils=__webpack_require__(6);
- var SIZE = 20;
- /**
- * This functions checks, if two annotations are at the same position an looks the same.
- * @return boolean, true if same and false if not
- */
- function isAnnotationsPosEqual(annotationA, annotationB){
- switch(annotationA.type){
- case 'area':
- return (parseInt(annotationA.x) === parseInt(annotationB.x) && parseInt(annotationA.y) === parseInt(annotationB.y) && parseInt(annotationA.width) === parseInt(annotationB.width) && parseInt(annotationA.height) === parseInt(annotationB.height));
- case 'drawing':
- return (annotationA.color === annotationB.color && JSON.stringify(annotationA.lines) === JSON.stringify(annotationB.lines) && parseInt(annotationA.width) === parseInt(annotationB.width));
- case 'highlight':
- case 'strikeout':
- //strikeout and highlight cannot be shifted, so they are the same
- return true;
- case 'point':
- return (parseInt(annotationA.x) === parseInt(annotationB.x) && parseInt(annotationA.y) === parseInt(annotationB.y));
- case 'textbox':
- return (parseInt(annotationA.x) === parseInt(annotationB.x) && parseInt(annotationA.y) === parseInt(annotationB.y) && parseInt(annotationA.width) === parseInt(annotationB.width) && parseInt(annotationA.height) === parseInt(annotationB.height) && annotationA.content === annotationB.content && annotationA.color === annotationB.color && parseInt(annotationA.size) === parseInt(annotationB.size));
- default:
- return false;
- }
- }
- /**
- * This function edits the SVG-Object of the annotation in the DOM
- * @param {type} type type of annotation
- * @param {type} node the annotation node
- * @param {type} svg the outer svg
- * @param {type} annotation the annotation object
- * @returns {void}
- */
- function editAnnotationSVG(type, node, svg, annotation){
- if(['area',/*'highlight',*/'point','textbox'].indexOf(type)>-1){
- (function(){
- var x = annotation.x;
- var y = annotation.y ;
- if(type === 'point'){
- x = annotation.x - (SIZE/4);
- y = annotation.y - SIZE;
+ if (options.targetBlank) {
+ attrs.target = '_blank';
}
- node.setAttribute('y',y);
- node.setAttribute('x',x);
- })();
- } else if(type==='drawing'){
- (function(){
- node.parentNode.removeChild(node);
- (0,_appendChild2.default)(svg,annotation);
- })();
- }
- }
- /**
- * This function synchronizes the annotations
- * It calls itself 5 secs after the function finishes. So every 5+ seconds the annotations are updated.
- * It loads only the annotations of the current shown page.
- */
- function loadNewAnnotations(){
- //determine which page is shown, to only load these annotations.
- var pageNumber = document.getElementById('currentPage').value;
- var page=document.getElementById('pageContainer'+pageNumber);
- if(page === null){
- setTimeout(loadNewAnnotations, 5000);
- return;
- }
- var svg=page.querySelector('.annotationLayer');
- var metadata = _utils.getMetadata(svg);
- var viewport = metadata.viewport;
- var documentId = metadata.documentId;
- //Sometimes the page is not loaded yet, than try again in 5secs
- if(isNaN(documentId) || documentId === null){
- setTimeout(loadNewAnnotations, 5000);
- return;
- }
- //Get annotations from database to get the newest.
- _PDFJSAnnotate2.default.getAnnotations(documentId,pageNumber)
- .then(function(data){
- var newAnnotations = [];
- newAnnotations[pageNumber] = data.annotations;
- var oldAnnotations = currentAnnotations.slice();
- currentAnnotations[pageNumber] = newAnnotations[pageNumber];
- var exists = false;
- for (var annotationID in newAnnotations[pageNumber]) {
- var annotation = newAnnotations[pageNumber][annotationID];
- for(var oldAnnoid in oldAnnotations[pageNumber]){
- var oldAnno = oldAnnotations[pageNumber][oldAnnoid];
- annotation.uuid = parseInt(annotation.uuid);
- oldAnno.uuid = parseInt(oldAnno.uuid);
- if(oldAnno !== undefined && annotation.uuid === oldAnno.uuid){
- if(!isAnnotationsPosEqual(annotation,oldAnno)){
- var node = document.querySelector('[data-pdf-annotate-id="'+oldAnno.uuid+'"]');
- if(node !== null){
- editAnnotationSVG(annotation.type, node, svg, annotation);
- }
+ return twttr.txt.linkToTextWithSymbol(entity, hash, hashtag, attrs, options);
+ };
+
+ twttr.txt.linkToCashtag = function (entity, text, options) {
+ var cashtag = twttr.txt.htmlEscape(entity.cashtag);
+ var attrs = clone(options.htmlAttrs || {});
+ attrs.href = options.cashtagUrlBase + cashtag;
+ attrs.title = '$' + cashtag;
+ attrs['class'] = options.cashtagClass;
+ if (options.targetBlank) {
+ attrs.target = '_blank';
+ }
+
+ return twttr.txt.linkToTextWithSymbol(entity, '$', cashtag, attrs, options);
+ };
+
+ twttr.txt.linkToMentionAndList = function (entity, text, options) {
+ var at = text.substring(entity.indices[0], entity.indices[0] + 1);
+ var user = twttr.txt.htmlEscape(entity.screenName);
+ var slashListname = twttr.txt.htmlEscape(entity.listSlug);
+ var isList = entity.listSlug && !options.suppressLists;
+ var attrs = clone(options.htmlAttrs || {});
+ attrs['class'] = isList ? options.listClass : options.usernameClass;
+ attrs.href = isList
+ ? options.listUrlBase + user + slashListname
+ : options.usernameUrlBase + user;
+ if (!isList && !options.suppressDataScreenName) {
+ attrs['data-screen-name'] = user;
+ }
+ if (options.targetBlank) {
+ attrs.target = '_blank';
+ }
+
+ return twttr.txt.linkToTextWithSymbol(
+ entity,
+ at,
+ isList ? user + slashListname : user,
+ attrs,
+ options
+ );
+ };
+
+ twttr.txt.linkToUrl = function (entity, text, options) {
+ var url = entity.url;
+ var displayUrl = url;
+ var linkText = twttr.txt.htmlEscape(displayUrl);
+
+ // If the caller passed a urlEntities object (provided by a Twitter API
+ // response with include_entities=true), we use that to render the display_url
+ // for each URL instead of it's underlying t.co URL.
+ var urlEntity = (options.urlEntities && options.urlEntities[url]) || entity;
+ if (urlEntity.display_url) {
+ linkText = twttr.txt.linkTextWithEntity(urlEntity, options);
+ }
+
+ var attrs = clone(options.htmlAttrs || {});
+
+ if (!url.match(twttr.txt.regexen.urlHasProtocol)) {
+ url = 'http://' + url;
+ }
+ attrs.href = url;
+
+ if (options.targetBlank) {
+ attrs.target = '_blank';
+ }
+
+ // set class only if urlClass is specified.
+ if (options.urlClass) {
+ attrs['class'] = options.urlClass;
+ }
+
+ // set target only if urlTarget is specified.
+ if (options.urlTarget) {
+ attrs.target = options.urlTarget;
+ }
+
+ if (!options.title && urlEntity.display_url) {
+ attrs.title = urlEntity.expanded_url;
+ }
+
+ return twttr.txt.linkToText(entity, linkText, attrs, options);
+ };
+
+ twttr.txt.linkTextWithEntity = function (entity, options) {
+ var displayUrl = entity.display_url;
+ var expandedUrl = entity.expanded_url;
+
+ // Goal: If a user copies and pastes a tweet containing t.co'ed link, the resulting paste
+ // should contain the full original URL (expanded_url), not the display URL.
+ //
+ // Method: Whenever possible, we actually emit HTML that contains expanded_url, and use
+ // font-size:0 to hide those parts that should not be displayed (because they are not part of display_url).
+ // Elements with font-size:0 get copied even though they are not visible.
+ // Note that display:none doesn't work here. Elements with display:none don't get copied.
+ //
+ // Additionally, we want to *display* ellipses, but we don't want them copied. To make this happen we
+ // wrap the ellipses in a tco-ellipsis class and provide an onCopy handler that sets display:none on
+ // everything with the tco-ellipsis class.
+ //
+ // Exception: pic.twitter.com images, for which expandedUrl = "https://twitter.com/#!/username/status/1234/photo/1
+ // For those URLs, display_url is not a substring of expanded_url, so we don't do anything special to render the elided parts.
+ // For a pic.twitter.com URL, the only elided part will be the "https://", so this is fine.
+
+ var displayUrlSansEllipses = displayUrl.replace(/…/g, ''); // We have to disregard ellipses for matching
+ // Note: we currently only support eliding parts of the URL at the beginning or the end.
+ // Eventually we may want to elide parts of the URL in the *middle*. If so, this code will
+ // become more complicated. We will probably want to create a regexp out of display URL,
+ // replacing every ellipsis with a ".*".
+ if (expandedUrl.indexOf(displayUrlSansEllipses) != -1) {
+ var displayUrlIndex = expandedUrl.indexOf(displayUrlSansEllipses);
+ var v = {
+ displayUrlSansEllipses: displayUrlSansEllipses,
+ // Portion of expandedUrl that precedes the displayUrl substring
+ beforeDisplayUrl: expandedUrl.substr(0, displayUrlIndex),
+ // Portion of expandedUrl that comes after displayUrl
+ afterDisplayUrl: expandedUrl.substr(displayUrlIndex + displayUrlSansEllipses.length),
+ precedingEllipsis: displayUrl.match(/^…/) ? '…' : '',
+ followingEllipsis: displayUrl.match(/…$/) ? '…' : '',
+ };
+ for (var k in v) {
+ if (v.hasOwnProperty(k)) {
+ v[k] = twttr.txt.htmlEscape(v[k]);
+ }
+ }
+ // As an example: The user tweets "hi http://longdomainname.com/foo"
+ // This gets shortened to "hi http://t.co/xyzabc", with display_url = "…nname.com/foo"
+ // This will get rendered as:
+ //
+ // …
+ //
+ // http://longdomai
+ //
+ //
+ // nname.com/foo
+ //
+ //
+ //
+ // …
+ //
+ v['invisible'] = options.invisibleTagAttrs;
+ return stringSupplant(
+ "#{precedingEllipsis} #{beforeDisplayUrl}#{displayUrlSansEllipses}#{afterDisplayUrl} #{followingEllipsis}",
+ v
+ );
+ }
+ return displayUrl;
+ };
+
+ twttr.txt.autoLinkEntities = function (text, entities, options) {
+ options = clone(options || {});
+
+ options.hashtagClass = options.hashtagClass || DEFAULT_HASHTAG_CLASS;
+ options.hashtagUrlBase = options.hashtagUrlBase || 'https://twitter.com/#!/search?q=%23';
+ options.cashtagClass = options.cashtagClass || DEFAULT_CASHTAG_CLASS;
+ options.cashtagUrlBase = options.cashtagUrlBase || 'https://twitter.com/#!/search?q=%24';
+ options.listClass = options.listClass || DEFAULT_LIST_CLASS;
+ options.usernameClass = options.usernameClass || DEFAULT_USERNAME_CLASS;
+ options.usernameUrlBase = options.usernameUrlBase || 'https://twitter.com/';
+ options.listUrlBase = options.listUrlBase || 'https://twitter.com/';
+ options.htmlAttrs = twttr.txt.extractHtmlAttrsFromOptions(options);
+ options.invisibleTagAttrs =
+ options.invisibleTagAttrs || "style='position:absolute;left:-9999px;'";
+
+ // remap url entities to hash
+ var urlEntities, i, len;
+ if (options.urlEntities) {
+ urlEntities = {};
+ for (i = 0, len = options.urlEntities.length; i < len; i++) {
+ urlEntities[options.urlEntities[i].url] = options.urlEntities[i];
+ }
+ options.urlEntities = urlEntities;
+ }
+
+ var result = '';
+ var beginIndex = 0;
+
+ // sort entities by start index
+ entities.sort(function (a, b) {
+ return a.indices[0] - b.indices[0];
+ });
+
+ var nonEntity = options.htmlEscapeNonEntities
+ ? twttr.txt.htmlEscape
+ : function (text) {
+ return text;
+ };
+
+ for (var i = 0; i < entities.length; i++) {
+ var entity = entities[i];
+ result += nonEntity(text.substring(beginIndex, entity.indices[0]));
+
+ if (entity.url) {
+ result += twttr.txt.linkToUrl(entity, text, options);
+ } else if (entity.hashtag) {
+ result += text; //twttr.txt.linkToHashtag(entity, text, options);
+ } else if (entity.screenName) {
+ result += text; //twttr.txt.linkToMentionAndList(entity, text, options);
+ } else if (entity.cashtag) {
+ result += text; //twttr.txt.linkToCashtag(entity, text, options);
+ }
+ beginIndex = entity.indices[1];
+ }
+ result += nonEntity(text.substring(beginIndex, text.length));
+ return result;
+ };
+
+ twttr.txt.autoLinkWithJSON = function (text, json, options) {
+ // map JSON entity to twitter-text entity
+ if (json.user_mentions) {
+ for (var i = 0; i < json.user_mentions.length; i++) {
+ // this is a @mention
+ json.user_mentions[i].screenName = json.user_mentions[i].screen_name;
+ }
+ }
+
+ if (json.hashtags) {
+ for (var i = 0; i < json.hashtags.length; i++) {
+ // this is a #hashtag
+ json.hashtags[i].hashtag = json.hashtags[i].text;
+ }
+ }
+
+ if (json.symbols) {
+ for (var i = 0; i < json.symbols.length; i++) {
+ // this is a $CASH tag
+ json.symbols[i].cashtag = json.symbols[i].text;
+ }
+ }
+
+ // concatenate all entities
+ var entities = [];
+ for (var key in json) {
+ entities = entities.concat(json[key]);
+ }
+
+ // modify indices to UTF-16
+ twttr.txt.modifyIndicesFromUnicodeToUTF16(text, entities);
+
+ return twttr.txt.autoLinkEntities(text, entities, options);
+ };
+
+ twttr.txt.extractHtmlAttrsFromOptions = function (options) {
+ var htmlAttrs = {};
+ for (var k in options) {
+ var v = options[k];
+ if (OPTIONS_NOT_ATTRIBUTES[k]) continue;
+ if (BOOLEAN_ATTRIBUTES[k]) {
+ v = v ? k : null;
+ }
+ if (v == null) continue;
+ htmlAttrs[k] = v;
+ }
+ return htmlAttrs;
+ };
+
+ twttr.txt.autoLink = function (text, options) {
+ var entities = twttr.txt.extractEntitiesWithIndices(text, {
+ extractUrlsWithoutProtocol: false,
+ });
+ return twttr.txt.autoLinkEntities(text, entities, options);
+ };
+
+ twttr.txt.autoLinkUsernamesOrLists = function (text, options) {
+ var entities = twttr.txt.extractMentionsOrListsWithIndices(text);
+ return twttr.txt.autoLinkEntities(text, entities, options);
+ };
+
+ twttr.txt.autoLinkHashtags = function (text, options) {
+ var entities = twttr.txt.extractHashtagsWithIndices(text);
+ return twttr.txt.autoLinkEntities(text, entities, options);
+ };
+
+ twttr.txt.autoLinkCashtags = function (text, options) {
+ var entities = twttr.txt.extractCashtagsWithIndices(text);
+ return twttr.txt.autoLinkEntities(text, entities, options);
+ };
+
+ twttr.txt.autoLinkUrlsCustom = function (text, options) {
+ var entities = twttr.txt.extractUrlsWithIndices(text, {
+ extractUrlsWithoutProtocol: false,
+ });
+ return twttr.txt.autoLinkEntities(text, entities, options);
+ };
+
+ twttr.txt.removeOverlappingEntities = function (entities) {
+ entities.sort(function (a, b) {
+ return a.indices[0] - b.indices[0];
+ });
+
+ var prev = entities[0];
+ for (var i = 1; i < entities.length; i++) {
+ if (prev.indices[1] > entities[i].indices[0]) {
+ entities.splice(i, 1);
+ i--;
+ } else {
+ prev = entities[i];
+ }
+ }
+ };
+
+ twttr.txt.extractEntitiesWithIndices = function (text, options) {
+ var entities = twttr.txt
+ .extractUrlsWithIndices(text, options)
+ .concat(twttr.txt.extractMentionsOrListsWithIndices(text))
+ .concat(twttr.txt.extractHashtagsWithIndices(text, { checkUrlOverlap: false }))
+ .concat(twttr.txt.extractCashtagsWithIndices(text));
+
+ if (entities.length == 0) {
+ return [];
+ }
+
+ twttr.txt.removeOverlappingEntities(entities);
+ return entities;
+ };
+
+ twttr.txt.extractMentions = function (text) {
+ var screenNamesOnly = [],
+ screenNamesWithIndices = twttr.txt.extractMentionsWithIndices(text);
+
+ for (var i = 0; i < screenNamesWithIndices.length; i++) {
+ var screenName = screenNamesWithIndices[i].screenName;
+ screenNamesOnly.push(screenName);
+ }
+
+ return screenNamesOnly;
+ };
+
+ twttr.txt.extractMentionsWithIndices = function (text) {
+ var mentions = [],
+ mentionOrList,
+ mentionsOrLists = twttr.txt.extractMentionsOrListsWithIndices(text);
+
+ for (var i = 0; i < mentionsOrLists.length; i++) {
+ mentionOrList = mentionsOrLists[i];
+ if (mentionOrList.listSlug == '') {
+ mentions.push({
+ screenName: mentionOrList.screenName,
+ indices: mentionOrList.indices,
+ });
+ }
+ }
+
+ return mentions;
+ };
+
+ /**
+ * Extract list or user mentions.
+ * (Presence of listSlug indicates a list)
+ */
+ twttr.txt.extractMentionsOrListsWithIndices = function (text) {
+ if (!text || !text.match(twttr.txt.regexen.atSigns)) {
+ return [];
+ }
+
+ var possibleNames = [],
+ slashListname;
+
+ text.replace(
+ twttr.txt.regexen.validMentionOrList,
+ function (match, before, atSign, screenName, slashListname, offset, chunk) {
+ var after = chunk.slice(offset + match.length);
+ if (!after.match(twttr.txt.regexen.endMentionMatch)) {
+ slashListname = slashListname || '';
+ var startPosition = offset + before.length;
+ var endPosition = startPosition + screenName.length + slashListname.length + 1;
+ possibleNames.push({
+ screenName: screenName,
+ listSlug: slashListname,
+ indices: [startPosition, endPosition],
+ });
+ }
+ }
+ );
+
+ return possibleNames;
+ };
+
+ twttr.txt.extractReplies = function (text) {
+ if (!text) {
+ return null;
+ }
+
+ var possibleScreenName = text.match(twttr.txt.regexen.validReply);
+ if (!possibleScreenName || RegExp.rightContext.match(twttr.txt.regexen.endMentionMatch)) {
+ return null;
+ }
+
+ return possibleScreenName[1];
+ };
+
+ twttr.txt.extractUrls = function (text, options) {
+ var urlsOnly = [],
+ urlsWithIndices = twttr.txt.extractUrlsWithIndices(text, options);
+
+ for (var i = 0; i < urlsWithIndices.length; i++) {
+ urlsOnly.push(urlsWithIndices[i].url);
+ }
+
+ return urlsOnly;
+ };
+
+ twttr.txt.extractUrlsWithIndices = function (text, options) {
+ if (!options) {
+ options = { extractUrlsWithoutProtocol: true };
+ }
+ if (!text || (options.extractUrlsWithoutProtocol ? !text.match(/\./) : !text.match(/:/))) {
+ return [];
+ }
+
+ var urls = [];
+
+ while (twttr.txt.regexen.extractUrl.exec(text)) {
+ var before = RegExp.$2,
+ url = RegExp.$3,
+ protocol = RegExp.$4,
+ domain = RegExp.$5,
+ path = RegExp.$7;
+ var endPosition = twttr.txt.regexen.extractUrl.lastIndex,
+ startPosition = endPosition - url.length;
+
+ // if protocol is missing and domain contains non-ASCII characters,
+ // extract ASCII-only domains.
+ if (!protocol) {
+ if (
+ !options.extractUrlsWithoutProtocol ||
+ before.match(twttr.txt.regexen.invalidUrlWithoutProtocolPrecedingChars)
+ ) {
+ continue;
+ }
+ var lastUrl = null,
+ asciiEndPosition = 0;
+ domain.replace(twttr.txt.regexen.validAsciiDomain, function (asciiDomain) {
+ var asciiStartPosition = domain.indexOf(asciiDomain, asciiEndPosition);
+ asciiEndPosition = asciiStartPosition + asciiDomain.length;
+ lastUrl = {
+ url: asciiDomain,
+ indices: [startPosition + asciiStartPosition, startPosition + asciiEndPosition],
+ };
+ if (
+ path ||
+ asciiDomain.match(twttr.txt.regexen.validSpecialShortDomain) ||
+ !asciiDomain.match(twttr.txt.regexen.invalidShortDomain)
+ ) {
+ urls.push(lastUrl);
}
- exists = true;
- break;
- } else if (oldAnno.newAnno && isAnnotationsPosEqual(annotation,oldAnno)){
- //Annotation was just added and is the same in newAnnotations
- //do Nothing
- delete oldAnno.newAnno;
- break;
+ });
+
+ // no ASCII-only domain found. Skip the entire URL.
+ if (lastUrl == null) {
+ continue;
+ }
+
+ // lastUrl only contains domain. Need to add path and query if they exist.
+ if (path) {
+ lastUrl.url = url.replace(domain, lastUrl.url);
+ lastUrl.indices[1] = endPosition;
}
+ } else {
+ // In the case of t.co URLs, don't allow additional path characters.
+ if (url.match(twttr.txt.regexen.validTcoUrl)) {
+ url = RegExp.lastMatch;
+ endPosition = startPosition + url.length;
+ }
+ urls.push({
+ url: url,
+ indices: [startPosition, endPosition],
+ });
+ }
+ }
+
+ return urls;
+ };
+
+ twttr.txt.extractHashtags = function (text) {
+ var hashtagsOnly = [],
+ hashtagsWithIndices = twttr.txt.extractHashtagsWithIndices(text);
+
+ for (var i = 0; i < hashtagsWithIndices.length; i++) {
+ hashtagsOnly.push(hashtagsWithIndices[i].hashtag);
+ }
+
+ return hashtagsOnly;
+ };
+ twttr.txt.extractHashtagsWithIndices = function (text, options) {
+ if (!options) {
+ options = { checkUrlOverlap: true };
+ }
+
+ if (!text || !text.match(twttr.txt.regexen.hashSigns)) {
+ return [];
+ }
+
+ var tags = [];
+
+ text.replace(
+ twttr.txt.regexen.validHashtag,
+ function (match, before, hash, hashText, offset, chunk) {
+ var after = chunk.slice(offset + match.length);
+ if (after.match(twttr.txt.regexen.endHashtagMatch)) return;
+ var startPosition = offset + before.length;
+ var endPosition = startPosition + hashText.length + 1;
+ tags.push({
+ hashtag: hashText,
+ indices: [startPosition, endPosition],
+ });
+ }
+ );
+
+ if (options.checkUrlOverlap) {
+ // also extract URL entities
+ var urls = twttr.txt.extractUrlsWithIndices(text);
+ if (urls.length > 0) {
+ var entities = tags.concat(urls);
+ // remove overlap
+ twttr.txt.removeOverlappingEntities(entities);
+ // only push back hashtags
+ tags = [];
+ for (var i = 0; i < entities.length; i++) {
+ if (entities[i].hashtag) {
+ tags.push(entities[i]);
+ }
+ }
}
- if(!exists){
- //append annotation to svg
- (0,_appendChild2.default)(svg,annotation,viewport);
+ }
+
+ return tags;
+ };
+
+ twttr.txt.extractCashtags = function (text) {
+ var cashtagsOnly = [],
+ cashtagsWithIndices = twttr.txt.extractCashtagsWithIndices(text);
+
+ for (var i = 0; i < cashtagsWithIndices.length; i++) {
+ cashtagsOnly.push(cashtagsWithIndices[i].cashtag);
+ }
+
+ return cashtagsOnly;
+ };
+
+ twttr.txt.extractCashtagsWithIndices = function (text) {
+ if (!text || text.indexOf('$') == -1) {
+ return [];
+ }
+
+ var tags = [];
+
+ text.replace(
+ twttr.txt.regexen.validCashtag,
+ function (match, before, dollar, cashtag, offset, chunk) {
+ var startPosition = offset + before.length;
+ var endPosition = startPosition + cashtag.length + 1;
+ tags.push({
+ cashtag: cashtag,
+ indices: [startPosition, endPosition],
+ });
}
- exists = false;
+ );
+
+ return tags;
+ };
+
+ twttr.txt.modifyIndicesFromUnicodeToUTF16 = function (text, entities) {
+ twttr.txt.convertUnicodeIndices(text, entities, false);
+ };
+
+ twttr.txt.modifyIndicesFromUTF16ToUnicode = function (text, entities) {
+ twttr.txt.convertUnicodeIndices(text, entities, true);
+ };
+
+ twttr.txt.getUnicodeTextLength = function (text) {
+ return text.replace(twttr.txt.regexen.non_bmp_code_pairs, ' ').length;
+ };
+
+ twttr.txt.convertUnicodeIndices = function (text, entities, indicesInUTF16) {
+ if (entities.length == 0) {
+ return;
}
- var exists = false;
- for( var oldAnnoid in oldAnnotations[pageNumber]){
- var oldAnno = oldAnnotations[pageNumber][oldAnnoid];
- for (var annotationID in newAnnotations[pageNumber]) {
- var annotation = newAnnotations[pageNumber][annotationID];
- if(oldAnno.uuid == annotation.uuid){
- exists = true;
+
+ var charIndex = 0;
+ var codePointIndex = 0;
+
+ // sort entities by start index
+ entities.sort(function (a, b) {
+ return a.indices[0] - b.indices[0];
+ });
+ var entityIndex = 0;
+ var entity = entities[0];
+
+ while (charIndex < text.length) {
+ if (entity.indices[0] == (indicesInUTF16 ? charIndex : codePointIndex)) {
+ var len = entity.indices[1] - entity.indices[0];
+ entity.indices[0] = indicesInUTF16 ? codePointIndex : charIndex;
+ entity.indices[1] = entity.indices[0] + len;
+
+ entityIndex++;
+ if (entityIndex == entities.length) {
+ // no more entity
break;
}
+ entity = entities[entityIndex];
}
- if(!exists && !oldAnno.newAnno){
- var node = document.querySelector('[data-pdf-annotate-id="'+oldAnno.uuid+'"]');
- if(node !== null){
- node.parentNode.removeChild(node);
+
+ var c = text.charCodeAt(charIndex);
+ if (0xd800 <= c && c <= 0xdbff && charIndex < text.length - 1) {
+ // Found high surrogate char
+ c = text.charCodeAt(charIndex + 1);
+ if (0xdc00 <= c && c <= 0xdfff) {
+ // Found surrogate pair
+ charIndex++;
}
}
- exists = false;
+ codePointIndex++;
+ charIndex++;
}
- //call this function to repeat in 5 secs
- // setTimeout(loadNewAnnotations, 5000);
- }, function (err){
- notification.addNotification({
- message: M.util.get_string('error:getAnnotations', 'pdfannotator'),
- type: "error"
- });
- });
- }
- }
- /***end of submodules of Module 2***/]));});;//# sourceMappingURL=pdf-annotate.js.map
- /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3)(module)))
-
-/***/ },
-/* 3 */
-/***/ function(module, exports) {
-
- module.exports = function(module) {
- if(!module.webpackPolyfill) {
- module.deprecate = function() {};
- module.paths = [];
- // module.parent = undefined by default
- module.children = [];
- module.webpackPolyfill = 1;
- }
- return module;
- }
-
-
-/***/ },
-/* 4 */
-/***/ function(module, exports) {
-
- 'use strict';
-
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = initColorPicker;
- // Color picker component
- var COLORS = [{ hex: '#000000', name: 'Black' }, { hex: '#EF4437', name: 'Red' }, { hex: '#E71F63', name: 'Pink' }, { hex: '#8F3E97', name: 'Purple' }, { hex: '#65499D', name: 'Deep Purple' }, { hex: '#4554A4', name: 'Indigo' }, { hex: '#2083C5', name: 'Blue' }, { hex: '#35A4DC', name: 'Light Blue' }, { hex: '#09BCD3', name: 'Cyan' }, { hex: '#009688', name: 'Teal' }, { hex: '#43A047', name: 'Green' }, { hex: '#8BC34A', name: 'Light Green' }, { hex: '#FDC010', name: 'Yellow' }, { hex: '#F8971C', name: 'Orange' }, { hex: '#F0592B', name: 'Deep Orange' }, { hex: '#F06291', name: 'Light Pink' }];
-
- function initColorPicker(el, value, onChange) {
- function setColor(value) {
- var fireOnChange = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
-
- currentValue = value;
- a.setAttribute('data-color', value);
- a.style.background = value;
- if (fireOnChange && typeof onChange === 'function') {
- onChange(value);
- }
- closePicker();
- }
-
- function togglePicker() {
- if (isPickerOpen) {
- closePicker();
- } else {
- openPicker();
- }
- }
-
- function closePicker() {
- document.removeEventListener('keyup', handleDocumentKeyup);
- if (picker && picker.parentNode) {
- picker.parentNode.removeChild(picker);
- }
- isPickerOpen = false;
- a.focus();
- }
-
- function openPicker() {
- if (!picker) {
- picker = document.createElement('div');
- picker.style.background = '#fff';
- picker.style.border = '1px solid #ccc';
- picker.style.padding = '2px';
- picker.style.position = 'absolute';
- picker.style.width = '122px';
- el.style.position = 'relative';
-
- COLORS.map(createColorOption).forEach(function (c) {
- c.style.margin = '2px';
- c.onclick = function () {
- // Select text/pen instead of cursor.
- if(c.parentNode.parentNode.className === 'text-color') {
- document.querySelector('#pdftoolbar button.text').click();
- } else if(c.parentNode.parentNode.className === 'pen-color') {
- document.querySelector('#pdftoolbar button.pen').click();
- }
- setColor(c.getAttribute('data-color'));
- };
- picker.appendChild(c);
- });
- }
-
- document.addEventListener('keyup', handleDocumentKeyup);
- el.appendChild(picker);
- isPickerOpen = true;
- }
-
- function createColorOption(color) {
- var e = document.createElement('a');
- e.className = 'color';
- e.setAttribute('href', 'javascript://');
- e.setAttribute('title', color.name);
- e.setAttribute('data-color', color.hex);
- e.style.background = color.hex;
- return e;
- }
-
- function handleDocumentKeyup(e) {
- if (e.keyCode === 27) {
- closePicker();
- }
- }
-
- var picker = void 0;
- var isPickerOpen = false;
- var currentValue = void 0;
- var a = createColorOption({ hex: value });
- a.title = M.util.get_string('colorPicker','pdfannotator');
- a.onclick = togglePicker;
- el.appendChild(a);
- setColor(value, false);
- }
-
-/***/ }
-/******/ ]);
-}); //require JQuery closed
-}
+ };
-/**
- *
- */
-function read_visibility_of_checkbox(){
- var commentVisibility= "public";
- if (document.querySelector('#anonymousCheckbox').checked) {
- commentVisibility = "anonymous";
- document.querySelector('#anonymousCheckbox').checked = false;
- }
-
- if (document.querySelector('#privateCheckbox') != null) {
- if (document.querySelector('#privateCheckbox').checked) {
- commentVisibility = "private";
- document.querySelector('#privateCheckbox').checked = false;
- }
- }
-
- if (document.querySelector('#protectedCheckbox') != null) {
- if (document.querySelector('#protectedCheckbox').checked) {
- commentVisibility = "protected";
- document.querySelector('#protectedCheckbox').checked = false;
- }
- }
- return commentVisibility;
+ // this essentially does text.split(/<|>/)
+ // except that won't work in IE, where empty strings are ommitted
+ // so "<>".split(/<|>/) => [] in IE, but is ["", "", ""] in all others
+ // but "<<".split("<") => ["", "", ""]
+ twttr.txt.splitTags = function (text) {
+ var firstSplits = text.split('<'),
+ secondSplits,
+ allSplits = [],
+ split;
+
+ for (var i = 0; i < firstSplits.length; i += 1) {
+ split = firstSplits[i];
+ if (!split) {
+ allSplits.push('');
+ } else {
+ secondSplits = split.split('>');
+ for (var j = 0; j < secondSplits.length; j += 1) {
+ allSplits.push(secondSplits[j]);
+ }
+ }
+ }
+
+ return allSplits;
+ };
+
+ twttr.txt.hitHighlight = function (text, hits, options) {
+ var defaultHighlightTag = 'em';
+
+ hits = hits || [];
+ options = options || {};
+
+ if (hits.length === 0) {
+ return text;
+ }
+
+ var tagName = options.tag || defaultHighlightTag,
+ tags = ['<' + tagName + '>', '' + tagName + '>'],
+ chunks = twttr.txt.splitTags(text),
+ i,
+ j,
+ result = '',
+ chunkIndex = 0,
+ chunk = chunks[0],
+ prevChunksLen = 0,
+ chunkCursor = 0,
+ startInChunk = false,
+ chunkChars = chunk,
+ flatHits = [],
+ index,
+ hit,
+ tag,
+ placed,
+ hitSpot;
+
+ for (i = 0; i < hits.length; i += 1) {
+ for (j = 0; j < hits[i].length; j += 1) {
+ flatHits.push(hits[i][j]);
+ }
+ }
+
+ for (index = 0; index < flatHits.length; index += 1) {
+ hit = flatHits[index];
+ tag = tags[index % 2];
+ placed = false;
+
+ while (chunk != null && hit >= prevChunksLen + chunk.length) {
+ result += chunkChars.slice(chunkCursor);
+ if (startInChunk && hit === prevChunksLen + chunkChars.length) {
+ result += tag;
+ placed = true;
+ }
+
+ if (chunks[chunkIndex + 1]) {
+ result += '<' + chunks[chunkIndex + 1] + '>';
+ }
+
+ prevChunksLen += chunkChars.length;
+ chunkCursor = 0;
+ chunkIndex += 2;
+ chunk = chunks[chunkIndex];
+ chunkChars = chunk;
+ startInChunk = false;
+ }
+
+ if (!placed && chunk != null) {
+ hitSpot = hit - prevChunksLen;
+ result += chunkChars.slice(chunkCursor, hitSpot) + tag;
+ chunkCursor = hitSpot;
+ if (index % 2 === 0) {
+ startInChunk = true;
+ } else {
+ startInChunk = false;
+ }
+ } else if (!placed) {
+ placed = true;
+ result += tag;
+ }
+ }
+
+ if (chunk != null) {
+ if (chunkCursor < chunkChars.length) {
+ result += chunkChars.slice(chunkCursor);
+ }
+ for (index = chunkIndex + 1; index < chunks.length; index += 1) {
+ result += index % 2 === 0 ? chunks[index] : '<' + chunks[index] + '>';
+ }
+ }
+
+ return result;
+ };
+
+ var MAX_LENGTH = 140;
+
+ // Returns the length of Tweet text with consideration to t.co URL replacement
+ // and chars outside the basic multilingual plane that use 2 UTF16 code points
+ twttr.txt.getTweetLength = function (text, options) {
+ if (!options) {
+ options = {
+ // These come from https://api.twitter.com/1/help/configuration.json
+ // described by https://dev.twitter.com/docs/api/1/get/help/configuration
+ short_url_length: 23,
+ short_url_length_https: 23,
+ };
+ }
+ var textLength = twttr.txt.getUnicodeTextLength(text),
+ urlsWithIndices = twttr.txt.extractUrlsWithIndices(text);
+ twttr.txt.modifyIndicesFromUTF16ToUnicode(text, urlsWithIndices);
+
+ for (var i = 0; i < urlsWithIndices.length; i++) {
+ // Subtract the length of the original URL
+ textLength += urlsWithIndices[i].indices[0] - urlsWithIndices[i].indices[1];
+
+ // Add 23 characters for URL starting with https://
+ // http:// URLs still use https://t.co so they are 23 characters as well
+ if (urlsWithIndices[i].url.toLowerCase().match(twttr.txt.regexen.urlHasHttps)) {
+ textLength += options.short_url_length_https;
+ } else {
+ textLength += options.short_url_length;
+ }
+ }
+
+ return textLength;
+ };
+
+ // Check the text for any reason that it may not be valid as a Tweet. This is meant as a pre-validation
+ // before posting to api.twitter.com. There are several server-side reasons for Tweets to fail but this pre-validation
+ // will allow quicker feedback.
+ //
+ // Returns false if this text is valid. Otherwise one of the following strings will be returned:
+ //
+ // "too_long": if the text is too long
+ // "empty": if the text is nil or empty
+ // "invalid_characters": if the text contains non-Unicode or any of the disallowed Unicode characters
+ twttr.txt.isInvalidTweet = function (text) {
+ if (!text) {
+ return 'empty';
+ }
+
+ // Determine max length independent of URL length
+ if (twttr.txt.getTweetLength(text) > MAX_LENGTH) {
+ return 'too_long';
+ }
+
+ if (twttr.txt.hasInvalidCharacters(text)) {
+ return 'invalid_characters';
+ }
+
+ return false;
+ };
+
+ twttr.txt.hasInvalidCharacters = function (text) {
+ return twttr.txt.regexen.invalid_chars.test(text);
+ };
+
+ twttr.txt.isValidTweetText = function (text) {
+ return !twttr.txt.isInvalidTweet(text);
+ };
+
+ twttr.txt.isValidUsername = function (username) {
+ if (!username) {
+ return false;
+ }
+
+ var extracted = twttr.txt.extractMentions(username);
+
+ // Should extract the username minus the @ sign, hence the .slice(1)
+ return extracted.length === 1 && extracted[0] === username.slice(1);
+ };
+
+ var VALID_LIST_RE = regexSupplant(/^#{validMentionOrList}$/);
+
+ twttr.txt.isValidList = function (usernameList) {
+ var match = usernameList.match(VALID_LIST_RE);
+
+ // Must have matched and had nothing before or after
+ return !!(match && match[1] == '' && match[4]);
+ };
+
+ twttr.txt.isValidHashtag = function (hashtag) {
+ if (!hashtag) {
+ return false;
+ }
+
+ var extracted = twttr.txt.extractHashtags(hashtag);
+
+ // Should extract the hashtag minus the # sign, hence the .slice(1)
+ return extracted.length === 1 && extracted[0] === hashtag.slice(1);
+ };
+
+ twttr.txt.isValidUrl = function (url, unicodeDomains, requireProtocol) {
+ if (unicodeDomains == null) {
+ unicodeDomains = true;
+ }
+
+ if (requireProtocol == null) {
+ requireProtocol = true;
+ }
+
+ if (!url) {
+ return false;
+ }
+
+ var urlParts = url.match(twttr.txt.regexen.validateUrlUnencoded);
+
+ if (!urlParts || urlParts[0] !== url) {
+ return false;
+ }
+
+ var scheme = urlParts[1],
+ authority = urlParts[2],
+ path = urlParts[3],
+ query = urlParts[4],
+ fragment = urlParts[5];
+
+ if (
+ !(
+ (!requireProtocol ||
+ (isValidMatch(scheme, twttr.txt.regexen.validateUrlScheme) &&
+ scheme.match(/^https?$/i))) &&
+ isValidMatch(path, twttr.txt.regexen.validateUrlPath) &&
+ isValidMatch(query, twttr.txt.regexen.validateUrlQuery, true) &&
+ isValidMatch(fragment, twttr.txt.regexen.validateUrlFragment, true)
+ )
+ ) {
+ return false;
+ }
+
+ return (
+ (unicodeDomains &&
+ isValidMatch(authority, twttr.txt.regexen.validateUrlUnicodeAuthority)) ||
+ (!unicodeDomains && isValidMatch(authority, twttr.txt.regexen.validateUrlAuthority))
+ );
+ };
+
+ function isValidMatch(string, regex, optional) {
+ if (!optional) {
+ // RegExp["$&"] is the text of the last match
+ // blank strings are ok, but are falsy, so we check stringiness instead of truthiness
+ return typeof string === 'string' && string.match(regex) && RegExp['$&'] === string;
+ }
+
+ // RegExp["$&"] is the text of the last match
+ return !string || (string.match(regex) && RegExp['$&'] === string);
+ }
+
+ if (typeof module != 'undefined' && module.exports) {
+ module.exports = twttr.txt;
+ }
+
+ if (true) {
+ !((__WEBPACK_AMD_DEFINE_ARRAY__ = []),
+ (__WEBPACK_AMD_DEFINE_FACTORY__ = twttr.txt),
+ (__WEBPACK_AMD_DEFINE_RESULT__ =
+ typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function'
+ ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)
+ : __WEBPACK_AMD_DEFINE_FACTORY__),
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined &&
+ (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+ }
+
+ if (typeof window != 'undefined') {
+ if (window.twttr) {
+ for (var prop in twttr) {
+ window.twttr[prop] = twttr[prop];
+ }
+ } else {
+ window.twttr = twttr;
+ }
+ }
+ })();
+ },
+ /* 2 */
+ function (module, exports, __webpack_require__) {
+ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
+ /* WEBPACK VAR INJECTION */ (function (module) {
+ 'use strict';
+ var _typeof2 =
+ typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol'
+ ? function (obj) {
+ return typeof obj;
+ }
+ : function (obj) {
+ return obj && typeof Symbol === 'function' && obj.constructor === Symbol
+ ? 'symbol'
+ : typeof obj;
+ };
+ (function webpackUniversalModuleDefinition(root, factory) {
+ if (
+ (false ? 'undefined' : _typeof2(exports)) === 'object' &&
+ (false ? 'undefined' : _typeof2(module)) === 'object'
+ )
+ module.exports = factory();
+ else if (true)
+ !((__WEBPACK_AMD_DEFINE_ARRAY__ = []),
+ (__WEBPACK_AMD_DEFINE_FACTORY__ = factory),
+ (__WEBPACK_AMD_DEFINE_RESULT__ =
+ typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function'
+ ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)
+ : __WEBPACK_AMD_DEFINE_FACTORY__),
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined &&
+ (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+ else if ((typeof exports === 'undefined' ? 'undefined' : _typeof2(exports)) === 'object')
+ exports['PDFAnnotate'] = factory();
+ else root['PDFAnnotate'] = factory();
+ })(undefined, function () {
+ return (function (modules) {
+ // webpackBootstrap
+ // The module cache
+ var installedModules = {}; // The require function
+ function __webpack_require__(moduleId) {
+ // Check if module is in cache
+ if (installedModules[moduleId]) return installedModules[moduleId].exports; // Create a new module (and put it into the cache)
+ var module = (installedModules[moduleId] = {
+ exports: {},
+ id: moduleId,
+ loaded: false,
+ }); // Execute the module function
+ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Flag the module as loaded
+ module.loaded = true; // Return the exports of the module
+ return module.exports;
+ } // expose the modules object (__webpack_modules__)
+ __webpack_require__.m = modules; // expose the module cache
+ __webpack_require__.c = installedModules; // __webpack_public_path__
+ __webpack_require__.p = ''; // Load entry module and return exports
+ return __webpack_require__(0);
+ })([
+ /* 0 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ exports.default = _PDFJSAnnotate2.default;
+ module.exports = exports['default'];
+ },
+ /* 1 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _StoreAdapter = __webpack_require__(2);
+ var _StoreAdapter2 = _interopRequireDefault(_StoreAdapter);
+ var _LocalStoreAdapter = __webpack_require__(8);
+ var _LocalStoreAdapter2 = _interopRequireDefault(_LocalStoreAdapter);
+ var _render = __webpack_require__(10);
+ var _render2 = _interopRequireDefault(_render);
+ var _UI = __webpack_require__(28);
+ var _UI2 = _interopRequireDefault(_UI);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ exports.default = {
+ /**
+ * Abstract class that needs to be defined so PDFJSAnnotate
+ * knows how to communicate with your server.
+ */ StoreAdapter: _StoreAdapter2.default,
+ /**
+ * Implementation of StoreAdapter that stores annotation data to localStorage.
+ */ LocalStoreAdapter: _LocalStoreAdapter2.default,
+ /**
+ * Abstract instance of StoreAdapter
+ */ __storeAdapter: new _StoreAdapter2.default(),
+ /**
+ * Getter for the underlying StoreAdapter property
+ *
+ * @return {StoreAdapter}
+ */ getStoreAdapter: function getStoreAdapter() {
+ return this.__storeAdapter;
+ },
+ /**
+ * Setter for the underlying StoreAdapter property
+ *
+ * @param {StoreAdapter} adapter The StoreAdapter implementation to be used.
+ */ setStoreAdapter: function setStoreAdapter(adapter) {
+ // TODO this throws an error when bundled
+ // if (!(adapter instanceof StoreAdapter)) {
+ // throw new Error('adapter must be an instance of StoreAdapter');
+ // }
+ this.__storeAdapter = adapter;
+ },
+ /**
+ * UI is a helper for instrumenting UI interactions for creating,
+ * editing, and deleting annotations in the browser.
+ */ UI: _UI2.default,
+ /**
+ * Render the annotations for a page in the PDF Document
+ *
+ * @param {SVGElement} svg The SVG element that annotations should be rendered to
+ * @param {PageViewport} viewport The PDFPage.getViewport data
+ * @param {Object} data The StoreAdapter.getAnnotations data
+ * @return {Promise}
+ */ render: _render2.default,
+ /**
+ * Convenience method for getting annotation data
+ *
+ * @alias StoreAdapter.getAnnotations
+ * @param {String} documentId The ID of the document
+ * @param {String} pageNumber The page number
+ * @return {Promise}
+ */ getAnnotations: function getAnnotations(documentId, pageNumber) {
+ var _getStoreAdapter;
+ return (_getStoreAdapter = this.getStoreAdapter()).getAnnotations.apply(
+ _getStoreAdapter,
+ arguments
+ );
+ },
+ };
+ module.exports = exports['default'];
+ },
+ /* 2 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _createClass = (function () {
+ function defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ('value' in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+ return function (Constructor, protoProps, staticProps) {
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) defineProperties(Constructor, staticProps);
+ return Constructor;
+ };
+ })();
+ var _abstractFunction = __webpack_require__(3);
+ var _abstractFunction2 = _interopRequireDefault(_abstractFunction);
+ var _event = __webpack_require__(4);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ function _classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError('Cannot call a class as a function');
+ }
+ }
+ // Adapter should never be invoked publicly
+ var StoreAdapter = (function () {
+ /**
+ * Create a new StoreAdapter instance
+ *
+ * @param {Object} [definition] The definition to use for overriding abstract methods
+ */ function StoreAdapter() {
+ var _this = this;
+ var definition =
+ arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
+ _classCallCheck(this, StoreAdapter); // Copy each function from definition if it is a function we know about
+ Object.keys(definition).forEach(function (key) {
+ if (
+ typeof definition[key] === 'function' &&
+ typeof _this[key] === 'function'
+ ) {
+ _this[key] = definition[key];
+ }
+ });
+ }
+ _createClass(StoreAdapter, [
+ /**
+ * Get all the annotations for a given document and page number.
+ *
+ * @param {String} documentId The ID for the document the annotations belong to
+ * @param {Number} pageNumber The number of the page the annotations belong to
+ * @return {Promise}
+ */
+ {
+ key: '__getAnnotations',
+ value: function __getAnnotations(documentId, pageNumber) {
+ (0, _abstractFunction2.default)('getAnnotations');
+ },
+ },
+ /**
+ * Get the definition for a specific annotation.
+ *
+ * @param {String} documentId The ID for the document the annotation belongs to
+ * @param {String} annotationId The ID for the annotation
+ * @return {Promise}
+ */
+ {
+ key: 'getAnnotation',
+ value: function getAnnotation(documentId, annotationId) {
+ (0, _abstractFunction2.default)('getAnnotation');
+ },
+ },
+ /**
+ * Add an annotation
+ *
+ * @param {String} documentId The ID for the document to add the annotation to
+ * @param {String} pageNumber The page number to add the annotation to
+ * @param {Object} annotation The definition for the new annotation
+ * @return {Promise}
+ */
+ {
+ key: '__addAnnotation',
+ value: function __addAnnotation(documentId, pageNumber, annotation) {
+ (0, _abstractFunction2.default)('addAnnotation');
+ },
+ },
+ /**
+ * Edit an annotation
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} pageNumber the page number of the annotation
+ * @param {Object} annotation The definition of the modified annotation
+ * @return {Promise}
+ */
+ {
+ key: '__editAnnotation',
+ value: function __editAnnotation(
+ documentId,
+ page,
+ annotationId,
+ annotation
+ ) {
+ (0, _abstractFunction2.default)('editAnnotation');
+ },
+ },
+ // Original:
+ // {key:'__editAnnotation',value:function __editAnnotation(documentId,pageNumber,annotation){
+ // (0,_abstractFunction2.default)('editAnnotation');
+ // }
+ // },
+ /**
+ * Delete an annotation
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} annotationId The ID for the annotation
+ * @return {Promise}
+ */
+ {
+ key: '__deleteAnnotation',
+ value: function __deleteAnnotation(documentId, annotationId) {
+ (0, _abstractFunction2.default)('deleteAnnotation');
+ },
+ },
+ /**
+ * Get all the comments for an annotation
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} annotationId The ID for the annotation
+ * @return {Promise}
+ */
+ {
+ key: 'getComments',
+ value: function getComments(documentId, annotationId) {
+ (0, _abstractFunction2.default)('getComments');
+ },
+ },
+
+ /**
+ * Get all the questions of one page
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} pageNumber The number of the requested page
+ * @return {Promise}
+ */
+ {
+ key: 'getQuestions',
+ value: function getQuestions(documentId, pageNumber, pattern) {
+ (0, _abstractFunction2.default)('getQuestions');
+ },
+ },
+ /**
+ * Get all the questions of one page
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} pageNumber The number of the requested page
+ * @return {Promise}
+ */
+ {
+ key: '__getQuestions',
+ value: function getQuestions(documentId, pageNumber, pattern) {
+ (0, _abstractFunction2.default)('getQuestions');
+ },
+ },
+ /**
+ * Add a new comment
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} annotationId The ID for the annotation
+ * @param {Object} content The definition of the comment
+ * @return {Promise}
+ *
+ */
+ {
+ key: '__addComment',
+ value: function __addComment(documentId, annotationId, content) {
+ (0, _abstractFunction2.default)('addComment');
+ },
+ },
+ /**
+ * Report a new comment
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} commentId The id of the comment that is to be reported
+ * @param {String} reason for reporting the comment: 'inaccurate', 'inappropriate' or 'other'
+ * @param {Object} content The definition of the complaint
+ * @return {Promise}
+ *
+ */
+ {
+ key: '__reportComment',
+ value: function reportComment(documentId, commentId, reason, content) {
+ (0, _abstractFunction2.default)('reportComment');
+ },
+ },
+ /**
+ * Delete a comment
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} commentId The ID for the comment
+ * @return {Promise}
+ */
+ {
+ key: '__deleteComment',
+ value: function __deleteComment(documentId, commentId) {
+ (0, _abstractFunction2.default)('deleteComment');
+ },
+ },
+ /**
+ * Hide a comment from participants view (i.e. display it as deleted)
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} commentId The ID for the comment
+ * @return {Promise}
+ */
+ {
+ key: '__hideComment',
+ value: function __hideComment(documentId, commentId) {
+ (0, _abstractFunction2.default)('hideComment');
+ },
+ },
+ /**
+ * Redisplay a comment for participants
+ *
+ * @param {String} documentId The ID for the document
+ * @param {String} commentId The ID for the comment
+ * @return {Promise}
+ */
+ {
+ key: '__redisplayComment',
+ value: function __redisplayComment(documentId, commentId) {
+ (0, _abstractFunction2.default)('redisplayComment');
+ },
+ },
+ /**
+ * Vote for a comment
+ * @param {String} documentId The ID for the document
+ * @param {String} commentId The ID for the comment
+ * @return {Promise}
+ */
+ {
+ key: '__getInformation',
+ value: function __getInformation(documentId, annotationId) {
+ (0, _abstractFunction2.default)('getInformation');
+ },
+ },
+
+ /**
+ * Vote for a comment
+ * @param {String} documentId The ID for the document
+ * @param {String} commentId The ID for the comment
+ * @return {Promise}
+ */
+ {
+ key: '__voteComment',
+ value: function __voteComment(documentId, commentId) {
+ (0, _abstractFunction2.default)('voteComment');
+ },
+ },
+
+ /**
+ * Edit a comment
+ * @param {String} documentId The ID for the document
+ * @param {String} commentId The ID for the comment
+ * @return {Promise}
+ */
+ {
+ key: '__editComment',
+ value: function __editComment(documentId, commentId) {
+ (0, _abstractFunction2.default)('editComment');
+ },
+ },
+
+ /**
+ * Subscribe to a question
+ * @param {String} documentId The ID for the document
+ * @param {String} commentId The ID for the comment
+ * @return {Promise}
+ */
+ {
+ key: '__subscribeQuestion',
+ value: function __subscribeQuestion(documentId, annotationId) {
+ (0, _abstractFunction2.default)('subscribeQuestion');
+ },
+ },
+
+ {
+ key: '__unsubscribeQuestion',
+ value: function __unsubscribeQuestion(documentId, annotationId) {
+ (0, _abstractFunction2.default)('unsubscribeQuestion');
+ },
+ },
+
+ {
+ key: '__markSolved',
+ value: function __markSolved(documentId, comment) {
+ (0, _abstractFunction2.default)('markSolved');
+ },
+ },
+
+ {
+ key: '__getCommentsToPrint',
+ value: function __getCommentsToPrint(documentId) {
+ (0, _abstractFunction2.default)('getCommentsToPrint');
+ },
+ },
+
+ {
+ key: 'getAnnotations',
+ get: function get() {
+ return this.__getAnnotations;
+ },
+ set: function set(fn) {
+ this.__getAnnotations = function getAnnotations(
+ documentId,
+ pageNumber
+ ) {
+ return fn.apply(undefined, arguments).then(function (annotations) {
+ // TODO may be best to have this happen on the server
+ if (annotations.annotations) {
+ annotations.annotations.forEach(function (a) {
+ a.documentId = documentId;
+ });
+ }
+ return annotations;
+ });
+ };
+ },
+ },
+ {
+ key: 'addAnnotation',
+ get: function get() {
+ return this.__addAnnotation;
+ },
+ set: function set(fn) {
+ this.__addAnnotation = function addAnnotation(
+ documentId,
+ pageNumber,
+ annotation
+ ) {
+ return fn.apply(undefined, arguments).then(function (annotation) {
+ (0,
+ _event.fireEvent)('annotation:add', documentId, pageNumber, annotation);
+ return annotation;
+ });
+ };
+ },
+ },
+ {
+ key: 'editAnnotation',
+ get: function get() {
+ return this.__editAnnotation;
+ },
+ set: function set(fn) {
+ this.__editAnnotation = function editAnnotation(
+ documentId,
+ page,
+ annotationId,
+ annotation
+ ) {
+ return fn.apply(undefined, arguments).then(function (annotation) {
+ (0,
+ _event.fireEvent)('annotation:edit', documentId, annotationId, annotation);
+ return annotation;
+ });
+ };
+ },
+ },
+ {
+ key: 'deleteAnnotation',
+ get: function get() {
+ return this.__deleteAnnotation;
+ },
+ set: function set(fn) {
+ this.__deleteAnnotation = function deleteAnnotation(
+ documentId,
+ annotationId
+ ) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'annotation:delete',
+ documentId,
+ annotationId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'addComment',
+ get: function get() {
+ return this.__addComment;
+ },
+ set: function set(fn) {
+ this.__addComment = function addComment(
+ documentId,
+ annotationId,
+ content
+ ) {
+ return fn.apply(undefined, arguments).then(function (comment) {
+ (0,
+ _event.fireEvent)('comment:add', documentId, annotationId, comment);
+ return comment;
+ });
+ };
+ },
+ },
+ {
+ key: 'reportComment',
+ get: function get() {
+ return this.__reportComment;
+ },
+ set: function set(fn) {
+ this.__reportComment = function reportComment(
+ documentId,
+ commentId,
+ reason,
+ content
+ ) {
+ return fn.apply(undefined, arguments).then(function (comment) {
+ (0,
+ _event.fireEvent)('comment:report', documentId, commentId, reason, content);
+ return comment;
+ });
+ };
+ },
+ },
+ {
+ key: 'deleteComment',
+ get: function get() {
+ return this.__deleteComment;
+ },
+ set: function set(fn) {
+ this.__deleteComment = function deleteComment(documentId, commentId) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'comment:delete',
+ documentId,
+ commentId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'hideComment',
+ get: function get() {
+ return this.__hideComment;
+ },
+ set: function set(fn) {
+ this.__hideComment = function hideComment(documentId, commentId) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'comment:hide',
+ documentId,
+ commentId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'redisplayComment',
+ get: function get() {
+ return this.__redisplayComment;
+ },
+ set: function set(fn) {
+ this.__redisplayComment = function redisplayComment(
+ documentId,
+ commentId
+ ) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'comment:redisplay',
+ documentId,
+ commentId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'getInformation',
+ get: function get() {
+ return this.__getInformation;
+ },
+ set: function set(fn) {
+ this.__getInformation = function getInformation(
+ documentId,
+ annotationId
+ ) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'annotation:getInformation',
+ documentId,
+ annotationId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'voteComment',
+ get: function get() {
+ return this.__voteComment;
+ },
+ set: function set(fn) {
+ this.__voteComment = function voteComment(documentId, commentId) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'comment:vote',
+ documentId,
+ commentId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'editComment',
+ get: function get() {
+ return this.__editComment;
+ },
+ set: function set(fn) {
+ this.__editComment = function editComment(documentId, commentId) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'comment:edit',
+ documentId,
+ commentId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'subscribeQuestion',
+ get: function get() {
+ return this.__subscribeQuestion;
+ },
+ set: function set(fn) {
+ this.__subscribeQuestion = function subscribeQuestion(
+ documentId,
+ annotationId
+ ) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'comment:subscribe',
+ documentId,
+ annotationId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'unsubscribeQuestion',
+ get: function get() {
+ return this.__unsubscribeQuestion;
+ },
+ set: function set(fn) {
+ this.__unsubscribeQuestion = function unsubscribeQuestion(
+ documentId,
+ annotationId
+ ) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'comment:unsubscribe',
+ documentId,
+ annotationId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'markSolved',
+ get: function get() {
+ return this.__markSolved;
+ },
+ set: function set(fn) {
+ this.__markSolved = function markSolved(documentId, comment) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'comment:markSolved',
+ documentId,
+ comment
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ {
+ key: 'getCommentsToPrint',
+ get: function get() {
+ return this.__getCommentsToPrint;
+ },
+ set: function set(fn) {
+ this.__getCommentsToPrint = function getCommentsToPrint(documentId) {
+ return fn.apply(undefined, arguments).then(function (success) {
+ if (success) {
+ (0, _event.fireEvent)(
+ 'document:printannotations',
+ documentId
+ );
+ }
+ return success;
+ });
+ };
+ },
+ },
+ ]);
+ return StoreAdapter;
+ })(); //Ende StoreAdapter
+ exports.default = StoreAdapter;
+ module.exports = exports['default'];
+ },
+ /* 3 */
+ function (module, exports) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = abstractFunction;
+ /**
+ * Throw an Error for an abstract function that hasn't been implemented.
+ *
+ * @param {String} name The name of the abstract function
+ */
+ function abstractFunction(name) {
+ throw new Error(name + ' is not implemented');
+ }
+ module.exports = exports['default'];
+ },
+ /* 4 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.fireEvent = fireEvent;
+ exports.addEventListener = addEventListener;
+ exports.removeEventListener = removeEventListener;
+ exports.handleDocClick = handleDocumentClickFunction;
+ var _events = __webpack_require__(5);
+ var _events2 = _interopRequireDefault(_events);
+ var _utils = __webpack_require__(6);
+ var _editoverlay = __webpack_require__(29);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ var emitter = new _events2.default();
+ var clickNode = void 0;
+ var count = 0;
+
+ /**
+ * This function handles the document click. It looks for annotations under the click point.
+ * If there are more than one annotation, a modal window pops up and the user can select, which one he/she wanted to click.
+ * @param {type} e the event object of the click
+ * @param {type} commid
+ * @returns {undefined}
+ */
+ function handleDocumentClickFunction(e, commid = null) {
+ let tar = $('#' + e.target.id);
+ if (tar.hasClass('moodle-dialogue') || tar.parents('.moodle-dialogue').length > 0) {
+ return; //Dialog (for example from atto-editor) was clicked.
+ }
+ //the last parameter is true to get an array instead of the first annotation found.
+ var target = (0, _utils.findAnnotationAtPoint)(e.clientX, e.clientY, true);
+
+ if (
+ target != null &&
+ Object.prototype.toString.call(target) === '[object Array]' &&
+ target.length > 1
+ ) {
+ //creats a modal window to select which one of the overlapping annotation should be selected.
+ var modal = document.createElement('div');
+ modal.id = 'myModal';
+ modal.className = 'modal hide fade';
+ modal.setAttribute('tabindex', -1);
+ modal.setAttribute('role', 'dialog');
+ modal.setAttribute('aria-labelledby', 'myModalLabel');
+ modal.setAttribute('aria-hidden', 'true');
+ var modaldialog = document.createElement('div');
+ modaldialog.className = 'modal-dialog';
+ var modalcontent = document.createElement('div');
+ modalcontent.className = 'modal-content';
+ var modalheader = document.createElement('div');
+ modalheader.className = 'modal-header';
+ var headerClose = document.createElement('button');
+ headerClose.setAttribute('type', 'button');
+ headerClose.className = 'close';
+ headerClose.setAttribute('data-dismiss', 'modal');
+ headerClose.setAttribute('aria-hidden', 'true');
+ headerClose.innerHTML = 'x';
+
+ headerClose.addEventListener('click', function () {
+ $('body').removeClass('modal-open');
+ $('#myModal').remove();
+ });
+
+ var headertitle = document.createElement('h3');
+ headertitle.id = 'myModalLabel';
+ headertitle.innerHTML = M.util.get_string('decision', 'pdfannotator');
+ headertitle.style.display = 'inline-block';
+ modalheader.appendChild(headertitle);
+ modalheader.appendChild(headerClose);
+
+ var modalbody = document.createElement('div');
+ modalbody.className = 'modal-body';
+ var bodytext = document.createElement('p');
+ bodytext.innerHTML = M.util.get_string(
+ 'decision:overlappingAnnotation',
+ 'pdfannotator'
+ );
+ modalbody.appendChild(bodytext);
+
+ modalcontent.appendChild(modalheader);
+ modalcontent.appendChild(modalbody);
+
+ modaldialog.appendChild(modalcontent);
+ modal.appendChild(modaldialog);
+
+ $('#body-wrapper').append(modal);
+ $('#myModal').modal({ backdrop: false });
+ for (var i = 0; i < target.length; i++) {
+ (function (innerI) {
+ var elemUse = document.createElement('button');
+ var elemType = target[innerI].getAttribute('data-pdf-annotate-type');
+ var elemImg = document.createElement('img');
+ elemImg.setAttribute('style', 'pointer-events:none;');
+ switch (elemType) {
+ case 'point':
+ elemImg.alt = M.util.get_string('point', 'pdfannotator');
+ elemImg.title = M.util.get_string('point', 'pdfannotator');
+ elemImg.src = M.util.image_url('pinbild', 'pdfannotator');
+ break;
+ case 'area':
+ elemImg.alt = M.util.get_string('rectangle', 'pdfannotator');
+ elemImg.title = M.util.get_string('rectangle', 'pdfannotator');
+ elemImg.src = M.util.image_url('i/completion-manual-n', 'core');
+ break;
+ case 'highlight':
+ elemImg.alt = M.util.get_string('highlight', 'pdfannotator');
+ elemImg.title = M.util.get_string('highlight', 'pdfannotator');
+ elemImg.src = M.util.image_url(
+ 'text_highlight_picker',
+ 'pdfannotator'
+ );
+ break;
+ case 'strikeout':
+ elemImg.alt = M.util.get_string('strikeout', 'pdfannotator');
+ elemImg.title = M.util.get_string('strikeout', 'pdfannotator');
+ elemImg.src = M.util.image_url('strikethrough', 'pdfannotator');
+ break;
+ case 'textbox':
+ elemImg.alt = M.util.get_string('textbox', 'pdfannotator');
+ elemImg.title = M.util.get_string('textbox', 'pdfannotator');
+ elemImg.src = M.util.image_url(
+ 'text_color_picker',
+ 'pdfannotator'
+ );
+ break;
+ case 'drawing':
+ elemImg.alt = M.util.get_string('drawing', 'pdfannotator');
+ elemImg.title = M.util.get_string('drawing', 'pdfannotator');
+ elemImg.src = M.util.image_url('editstring', 'pdfannotator');
+ break;
+ case 'default':
+ elemImg.alt = 'undefined';
+ elemImg.title = 'undefined';
+ elemImg.src = '';
+ }
+
+ elemUse.appendChild(elemImg);
+
+ elemUse.addEventListener('click', function () {
+ // Emit annotation:blur if clickNode is no longer clicked
+ if (clickNode && clickNode !== target[innerI]) {
+ emitter.emit('annotation:blur', clickNode);
+ } // Emit annotation:click if target was clicked
+ if (target[innerI]) {
+ emitter.emit('annotation:click', target[innerI]);
+ }
+ clickNode = target[innerI];
+ $('body').removeClass('modal-open');
+ $('#myModal').remove();
+ });
+ elemUse.addEventListener('mouseover', function () {
+ _editoverlay.createEditOverlay(target[innerI]);
+ });
+ elemUse.addEventListener('mouseout', function () {
+ _editoverlay.destroyEditOverlay(target[innerI]);
+ });
+ modalbody.appendChild(elemUse);
+ })(i);
+ }
+ } else {
+ // Emit annotation:blur if clickNode is no longer clicked, but not if another node is clicked.
+ if (clickNode && !target) {
+ emitter.emit('annotation:blur', clickNode);
+ }
+ // Emit annotation:click if target was clicked.
+ if (target) {
+ if (commid !== null) {
+ target.markCommentid = commid;
+ }
+ emitter.emit('annotation:click', target);
+ }
+ clickNode = target;
+ }
+
+ return;
+ }
+
+ document.addEventListener('click', function handleDocumentClick(e) {
+ //R: The ClickEvent should only be happen, if the cursor is selected.
+ if (document.querySelector('.cursor').className.indexOf('active') === -1) {
+ return;
+ }
+ //if the click is in atto editor nothing should happen.
+ var editorNodes = document.querySelectorAll('div.editor_atto_wrap')[0];
+ var clickedElement;
+ if (e.target.id) {
+ clickedElement = '#' + e.target.id;
+ } else if (e.target.className[0]) {
+ clickedElement = '.' + e.target.className;
+ } else {
+ clickedElement = '';
+ }
+ if (clickedElement && editorNodes && editorNodes.querySelector(clickedElement)) {
+ return;
+ }
+ //If moodle Modal beeing clicked.
+ var modal = document.querySelectorAll('.modal.show')[0];
+ if (modal) {
+ if (clickedElement && modal.querySelector(clickedElement)) {
+ return;
+ }
+ }
+
+ //If Modal Dialogue beeing clicked.
+ var clickedMoodleDialogue = e.target.closest('.moodle-dialogue-base');
+ if (clickedMoodleDialogue) {
+ return;
+ }
+
+ //if the click is on an input field or link or icon in editor toolbar ('I') nothing should happen.
+ if (
+ e.target.tagName === 'INPUT' ||
+ e.target.tagName === 'A' ||
+ e.target.tagName === 'SELECT' ||
+ e.target.tagName === 'I' ||
+ e.target.tagName === 'BUTTON'
+ ) {
+ return;
+ }
+ //R: if the click is on the Commentlist nothing should happen.
+ if (
+ (typeof e.target.getAttribute('id') != 'string' &&
+ e.target.id.indexOf('comment') !== -1) ||
+ e.target.className.indexOf('comment') !== -1 ||
+ e.target.parentNode.className.indexOf('comment') !== -1 ||
+ e.target.parentNode.className.indexOf('chat') !== -1
+ ) {
+ return;
+ }
+ if (!(0, _utils.findSVGAtPoint)(e.clientX, e.clientY, true)) {
+ return;
+ }
+
+ handleDocumentClickFunction(e);
+ });
+
+ function fireEvent() {
+ if (arguments[0] === 'annotation:click') {
+ clickNode = arguments[1];
+ }
+ emitter.emit.apply(emitter, arguments);
+ }
+ function addEventListener() {
+ emitter.on.apply(emitter, arguments);
+ }
+ function removeEventListener() {
+ emitter.removeListener.apply(emitter, arguments);
+ }
+ },
+ /* 5 */
+ function (module, exports) {
+ // Copyright Joyent, Inc. and other Node contributors.
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a
+ // copy of this software and associated documentation files (the
+ // "Software"), to deal in the Software without restriction, including
+ // without limitation the rights to use, copy, modify, merge, publish,
+ // distribute, sublicense, and/or sell copies of the Software, and to permit
+ // persons to whom the Software is furnished to do so, subject to the
+ // following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included
+ // in all copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
+ function EventEmitter() {
+ this._events = this._events || {};
+ this._maxListeners = this._maxListeners || undefined;
+ }
+ module.exports = EventEmitter; // Backwards-compat with node 0.10.x
+ EventEmitter.EventEmitter = EventEmitter;
+ EventEmitter.prototype._events = undefined;
+ EventEmitter.prototype._maxListeners = undefined;
+ // By default EventEmitters will print a warning if more than 10 listeners are
+ // added to it. This is a useful default which helps finding memory leaks.
+ EventEmitter.defaultMaxListeners = 10;
+ // Obviously not all Emitters should be limited to 10. This function allows
+ // that to be increased. Set to zero for unlimited.
+ EventEmitter.prototype.setMaxListeners = function (n) {
+ if (!isNumber(n) || n < 0 || isNaN(n))
+ throw TypeError('n must be a positive number');
+ this._maxListeners = n;
+ return this;
+ };
+ EventEmitter.prototype.emit = function (type) {
+ var er, handler, len, args, i, listeners;
+ if (!this._events) this._events = {}; // If there is no 'error' event listener then throw.
+ if (type === 'error') {
+ if (
+ !this._events.error ||
+ (isObject(this._events.error) && !this._events.error.length)
+ ) {
+ er = arguments[1];
+ if (er instanceof Error) {
+ throw er; // Unhandled 'error' event
+ }
+ throw TypeError('Uncaught, unspecified "error" event.');
+ }
+ }
+ handler = this._events[type];
+ if (isUndefined(handler)) return false;
+ if (isFunction(handler)) {
+ switch (
+ arguments.length // fast cases
+ ) {
+ case 1:
+ handler.call(this);
+ break;
+ case 2:
+ handler.call(this, arguments[1]);
+ break;
+ case 3:
+ handler.call(this, arguments[1], arguments[2]);
+ break; // slower
+ default:
+ args = Array.prototype.slice.call(arguments, 1);
+ handler.apply(this, args);
+ }
+ } else if (isObject(handler)) {
+ args = Array.prototype.slice.call(arguments, 1);
+ listeners = handler.slice();
+ len = listeners.length;
+ for (i = 0; i < len; i++) {
+ listeners[i].apply(this, args);
+ }
+ }
+ return true;
+ };
+ EventEmitter.prototype.addListener = function (type, listener) {
+ var m;
+ if (!isFunction(listener)) throw TypeError('listener must be a function');
+ if (!this._events) this._events = {}; // To avoid recursion in the case that type === "newListener"! Before
+ // adding it to the listeners, first emit "newListener".
+ if (this._events.newListener)
+ this.emit(
+ 'newListener',
+ type,
+ isFunction(listener.listener) ? listener.listener : listener
+ );
+ if (!this._events[type])
+ // Optimize the case of one listener. Don't need the extra array object.
+ this._events[type] = listener;
+ else if (isObject(this._events[type]))
+ // If we've already got an array, just append.
+ this._events[type].push(listener);
+ // Adding the second element, need to change to array.
+ else this._events[type] = [this._events[type], listener]; // Check for listener leak
+ if (isObject(this._events[type]) && !this._events[type].warned) {
+ if (!isUndefined(this._maxListeners)) {
+ m = this._maxListeners;
+ } else {
+ m = EventEmitter.defaultMaxListeners;
+ }
+ if (m && m > 0 && this._events[type].length > m) {
+ this._events[type].warned = true;
+ console.error(
+ '(node) warning: possible EventEmitter memory ' +
+ 'leak detected. %d listeners added. ' +
+ 'Use emitter.setMaxListeners() to increase limit.',
+ this._events[type].length
+ );
+ if (typeof console.trace === 'function') {
+ // not supported in IE 10
+ console.trace();
+ }
+ }
+ }
+ return this;
+ };
+ EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+ EventEmitter.prototype.once = function (type, listener) {
+ if (!isFunction(listener)) throw TypeError('listener must be a function');
+ var fired = false;
+ function g() {
+ this.removeListener(type, g);
+ if (!fired) {
+ fired = true;
+ listener.apply(this, arguments);
+ }
+ }
+ g.listener = listener;
+ this.on(type, g);
+ return this;
+ };
+ // emits a 'removeListener' event iff the listener was removed
+ EventEmitter.prototype.removeListener = function (type, listener) {
+ var list, position, length, i;
+ if (!isFunction(listener)) throw TypeError('listener must be a function');
+ if (!this._events || !this._events[type]) return this;
+ list = this._events[type];
+ length = list.length;
+ position = -1;
+ if (
+ list === listener ||
+ (isFunction(list.listener) && list.listener === listener)
+ ) {
+ delete this._events[type];
+ if (this._events.removeListener) this.emit('removeListener', type, listener);
+ } else if (isObject(list)) {
+ for (i = length; i-- > 0; ) {
+ if (
+ list[i] === listener ||
+ (list[i].listener && list[i].listener === listener)
+ ) {
+ position = i;
+ break;
+ }
+ }
+ if (position < 0) return this;
+ if (list.length === 1) {
+ list.length = 0;
+ delete this._events[type];
+ } else {
+ list.splice(position, 1);
+ }
+ if (this._events.removeListener) this.emit('removeListener', type, listener);
+ }
+ return this;
+ };
+ EventEmitter.prototype.removeAllListeners = function (type) {
+ var key, listeners;
+ if (!this._events) return this; // not listening for removeListener, no need to emit
+ if (!this._events.removeListener) {
+ if (arguments.length === 0) this._events = {};
+ else if (this._events[type]) delete this._events[type];
+ return this;
+ } // emit removeListener for all listeners on all events
+ if (arguments.length === 0) {
+ for (key in this._events) {
+ if (key === 'removeListener') continue;
+ this.removeAllListeners(key);
+ }
+ this.removeAllListeners('removeListener');
+ this._events = {};
+ return this;
+ }
+ listeners = this._events[type];
+ if (isFunction(listeners)) {
+ this.removeListener(type, listeners);
+ } else if (listeners) {
+ // LIFO order
+ while (listeners.length) {
+ this.removeListener(type, listeners[listeners.length - 1]);
+ }
+ }
+ delete this._events[type];
+ return this;
+ };
+ EventEmitter.prototype.listeners = function (type) {
+ var ret;
+ if (!this._events || !this._events[type]) ret = [];
+ else if (isFunction(this._events[type])) ret = [this._events[type]];
+ else ret = this._events[type].slice();
+ return ret;
+ };
+ EventEmitter.prototype.listenerCount = function (type) {
+ if (this._events) {
+ var evlistener = this._events[type];
+ if (isFunction(evlistener)) return 1;
+ else if (evlistener) return evlistener.length;
+ }
+ return 0;
+ };
+ EventEmitter.listenerCount = function (emitter, type) {
+ return emitter.listenerCount(type);
+ };
+ function isFunction(arg) {
+ return typeof arg === 'function';
+ }
+ function isNumber(arg) {
+ return typeof arg === 'number';
+ }
+ function isObject(arg) {
+ return (
+ (typeof arg === 'undefined' ? 'undefined' : _typeof2(arg)) === 'object' &&
+ arg !== null
+ );
+ }
+ function isUndefined(arg) {
+ return arg === void 0;
+ }
+ },
+ /* 6 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.BORDER_COLOR = undefined;
+ exports.findSVGContainer = findSVGContainer;
+ exports.findSVGAtPoint = findSVGAtPoint;
+ exports.findAnnotationAtPoint = findAnnotationAtPoint;
+ exports.pointIntersectsRect = pointIntersectsRect;
+ exports.getOffsetAnnotationRect = getOffsetAnnotationRect;
+ exports.getAnnotationRect = getAnnotationRect;
+ exports.scaleUp = scaleUp;
+ exports.scaleDown = scaleDown;
+ exports.getScroll = getScroll;
+ exports.getOffset = getOffset;
+ exports.disableUserSelect = disableUserSelect;
+ exports.enableUserSelect = enableUserSelect;
+ exports.getMetadata = getMetadata;
+ //R: Function to round digits
+ exports.roundDigits = roundDigits;
+ var _createStylesheet = __webpack_require__(7);
+ var _createStylesheet2 = _interopRequireDefault(_createStylesheet);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ var BORDER_COLOR = (exports.BORDER_COLOR = '#00BFFF');
+ var userSelectStyleSheet = (0, _createStylesheet2.default)({
+ body: {
+ '-webkit-user-select': 'none',
+ '-moz-user-select': 'none',
+ '-ms-user-select': 'none',
+ 'user-select': 'none',
+ },
+ });
+ userSelectStyleSheet.setAttribute('data-pdf-annotate-user-select', 'true');
+ /**
+ * Find the SVGElement that contains all the annotations for a page
+ *
+ * @param {Element} node An annotation within that container
+ * @return {SVGElement} The container SVG or null if it can't be found
+ */ function findSVGContainer(node) {
+ var parentNode = node;
+ while ((parentNode = parentNode.parentNode) && parentNode !== document) {
+ if (
+ parentNode.nodeName.toUpperCase() === 'SVG' &&
+ parentNode.getAttribute('data-pdf-annotate-container') === 'true'
+ ) {
+ return parentNode;
+ }
+ }
+ return null;
+ }
+ /**
+ * Find an SVGElement container at a given point
+ *
+ * @param {Number} x The x coordinate of the point
+ * @param {Number} y The y coordinate of the point
+ * @param {Boolean} array If the return value should be an array or a single svg object.
+ * @return {SVGElement} The container SVG or null if one can't be found. If more than one and array=true the return value is an array of SVGs.
+ */ function findSVGAtPoint(x, y, array) {
+ var elements = document.querySelectorAll('svg[data-pdf-annotate-container="true"]');
+ if (array) {
+ var ret = [];
+ //end R
+ for (var i = 0, l = elements.length; i < l; i++) {
+ var el = elements[i];
+ var rect = el.getBoundingClientRect();
+ if (pointIntersectsRect(x, y, rect)) {
+ ret.push(el);
+ }
+ }
+ if (ret.length > 0) {
+ return ret;
+ }
+ } else {
+ for (var i = 0, l = elements.length; i < l; i++) {
+ var el = elements[i];
+ var rect = el.getBoundingClientRect();
+ if (pointIntersectsRect(x, y, rect)) {
+ return el;
+ }
+ }
+ }
+ return null;
+ }
+ /**
+ * Find an Element that represents an annotation at a given point
+ *
+ * @param {Number} x The x coordinate of the point
+ * @param {Number} y The y coordinate of the point
+ * @param {Boolean} array If the return value should be an array or a single svg object.
+ * @return {Element} The annotation element or null if one can't be found. If array=true an array with annotations elements.
+ */ function findAnnotationAtPoint(x, y, array) {
+ var svg = findSVGAtPoint(x, y, array);
+ if (!svg) {
+ return;
+ }
+ if (array) {
+ var elements = [];
+ for (var j = 0; j < svg.length; j++) {
+ elements.push(svg[j].querySelectorAll('[data-pdf-annotate-type]'));
+ } // Find a target element within SVG
+ var ret = [];
+ for (var i = 0, l = elements.length; i < l; i++) {
+ for (var inner = 0; inner < elements[i].length; inner++) {
+ var el = elements[i][inner];
+ if (pointIntersectsRect(x, y, getOffsetAnnotationRect(el))) {
+ ret.push(el);
+ }
+ }
+ }
+ if (ret.length === 1) {
+ return ret[0];
+ }
+ if (ret.length > 0) {
+ return ret;
+ }
+ } else {
+ elements = svg.querySelectorAll('[data-pdf-annotate-type]');
+ for (var i = 0, l = elements.length; i < l; i++) {
+ var el = elements[i][inner];
+ if (pointIntersectsRect(x, y, getOffsetAnnotationRect(el))) {
+ return el;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Determine if a point intersects a rect
+ *
+ * @param {Number} x The x coordinate of the point
+ * @param {Number} y The y coordinate of the point
+ * @param {Object} rect The points of a rect (likely from getBoundingClientRect)
+ * @return {Boolean} True if a collision occurs, otherwise false
+ */ function pointIntersectsRect(x, y, rect) {
+ return y >= rect.top && y <= rect.bottom && x >= rect.left && x <= rect.right;
+ }
+ /**
+ * Get the rect of an annotation element accounting for offset.
+ *
+ * @param {Element} el The element to get the rect of
+ * @return {Object} The dimensions of the element
+ */ function getOffsetAnnotationRect(el) {
+ var rect = getAnnotationRect(el);
+ var _getOffset = getOffset(el);
+ var offsetLeft = _getOffset.offsetLeft;
+ var offsetTop = _getOffset.offsetTop;
+ return {
+ top: rect.top + offsetTop,
+ left: rect.left + offsetLeft,
+ right: rect.right + offsetLeft,
+ bottom: rect.bottom + offsetTop,
+ };
+ }
+ /**
+ * Get the rect of an annotation element.
+ *
+ * @param {Element} el The element to get the rect of
+ * @return {Object} The dimensions of the element
+ */ function getAnnotationRect(el) {
+ var h = 0,
+ w = 0,
+ x = 0,
+ y = 0;
+ var rect = el.getBoundingClientRect();
+ // TODO this should be calculated somehow
+ var LINE_OFFSET = 16;
+ var isFirefox = /firefox/i.test(navigator.userAgent);
+ switch (el.nodeName.toLowerCase()) {
+ case 'path':
+ var minX = void 0,
+ maxX = void 0,
+ minY = void 0,
+ maxY = void 0;
+ el.getAttribute('d')
+ .replace(/Z/, '')
+ .split('M')
+ .splice(1)
+ .forEach(function (p) {
+ var s = p.split(' ').map(function (i) {
+ return parseInt(i, 10);
+ });
+ if (typeof minX === 'undefined' || s[0] < minX) {
+ minX = s[0];
+ }
+ if (typeof maxX === 'undefined' || s[2] > maxX) {
+ maxX = s[2];
+ }
+ if (typeof minY === 'undefined' || s[1] < minY) {
+ minY = s[1];
+ }
+ if (typeof maxY === 'undefined' || s[3] > maxY) {
+ maxY = s[3];
+ }
+ });
+ // +2 and -1 make the path 1 larger in each direction. This makes thin straight lines clickable.
+ h = maxY - minY + 2;
+ w = maxX - minX + 2;
+ x = minX - 1;
+ y = minY - 1;
+ break;
+ case 'line':
+ h =
+ parseInt(el.getAttribute('y2'), 10) -
+ parseInt(el.getAttribute('y1'), 10);
+ w =
+ parseInt(el.getAttribute('x2'), 10) -
+ parseInt(el.getAttribute('x1'), 10);
+ x = parseInt(el.getAttribute('x1'), 10);
+ y = parseInt(el.getAttribute('y1'), 10);
+ if (h === 0) {
+ h += LINE_OFFSET;
+ y -= LINE_OFFSET / 2;
+ }
+ break;
+ case 'text':
+ h = rect.height;
+ w = rect.width;
+ x = parseInt(el.getAttribute('x'), 10);
+ y = parseInt(el.getAttribute('y'), 10) - h;
+ break;
+ case 'g':
+ var _getOffset2 = getOffset(el);
+ var offsetLeft = _getOffset2.offsetLeft;
+ var offsetTop = _getOffset2.offsetTop;
+ h = rect.height;
+ w = rect.width;
+ x = rect.left - offsetLeft;
+ y = rect.top - offsetTop;
+ if (el.getAttribute('data-pdf-annotate-type') === 'strikeout') {
+ h += LINE_OFFSET;
+ y -= LINE_OFFSET / 2;
+ }
+ break;
+ case 'rect':
+ case 'svg':
+ h = parseInt(el.getAttribute('height'), 10);
+ w = parseInt(el.getAttribute('width'), 10);
+ x = parseInt(el.getAttribute('x'), 10);
+ y = parseInt(el.getAttribute('y'), 10);
+ break;
+ } // Result provides same properties as getBoundingClientRect
+ var result = {
+ top: y,
+ left: x,
+ width: w,
+ height: h,
+ right: x + w,
+ bottom: y + h,
+ }; // For the case of nested SVG (point annotations) and grouped
+ // lines or rects no adjustment needs to be made for scale.
+ // I assume that the scale is already being handled
+ // natively by virtue of the `transform` attribute.
+ if (!['svg', 'g'].includes(el.nodeName.toLowerCase())) {
+ result = scaleUp(findSVGAtPoint(rect.left, rect.top), result);
+ }
+ // FF scales nativly and uses always the 100%-Attributes, so the svg has to be scaled up to proof, if it is on the same position.
+ if (isFirefox && ['svg'].includes(el.nodeName.toLowerCase())) {
+ var svgTMP;
+ if ((svgTMP = findSVGAtPoint(rect.left, rect.top)) !== null) {
+ result = scaleUp(svgTMP, result);
+ }
+ }
+ return result;
+ }
+ /**
+ * Adjust scale from normalized scale (100%) to rendered scale.
+ *
+ * @param {SVGElement} svg The SVG to gather metadata from
+ * @param {Object} rect A map of numeric values to scale
+ * @return {Object} A copy of `rect` with values scaled up
+ */ function scaleUp(svg, rect) {
+ if (svg === null) {
+ return rect;
+ }
+ var result = {};
+ var _getMetadata = getMetadata(svg);
+ var viewport = _getMetadata.viewport;
+ Object.keys(rect).forEach(function (key) {
+ result[key] = rect[key] * viewport.scale;
+ });
+ return result;
+ }
+ /**
+ * Adjust scale from rendered scale to a normalized scale (100%).
+ *
+ * @param {SVGElement} svg The SVG to gather metadata from
+ * @param {Object} rect A map of numeric values to scale
+ * @return {Object} A copy of `rect` with values scaled down
+ */ function scaleDown(svg, rect) {
+ var result = {};
+ var _getMetadata2 = getMetadata(svg);
+ var viewport = _getMetadata2.viewport;
+ Object.keys(rect).forEach(function (key) {
+ result[key] = rect[key] / viewport.scale;
+ });
+ return result;
+ }
+ /**
+ * Get the scroll position of an element, accounting for parent elements
+ *
+ * @param {Element} el The element to get the scroll position for
+ * @return {Object} The scrollTop and scrollLeft position
+ */ function getScroll(el) {
+ var scrollTop = 0;
+ var scrollLeft = 0;
+ var parentNode = el;
+ while ((parentNode = parentNode.parentNode) && parentNode !== document) {
+ scrollTop += parentNode.scrollTop;
+ scrollLeft += parentNode.scrollLeft;
+ }
+ return { scrollTop: scrollTop, scrollLeft: scrollLeft };
+ }
+ /**
+ * Get the offset position of an element, accounting for parent elements
+ *
+ * @param {Element} el The element to get the offset position for
+ * @return {Object} The offsetTop and offsetLeft position
+ */ function getOffset(el) {
+ var parentNode = el;
+ while ((parentNode = parentNode.parentNode) && parentNode !== document) {
+ if (parentNode.nodeName.toUpperCase() === 'SVG') {
+ break;
+ }
+ }
+ var rect = parentNode.getBoundingClientRect();
+ return { offsetLeft: rect.left, offsetTop: rect.top };
+ }
+ /**
+ * Disable user ability to select text on page
+ */ function disableUserSelect() {
+ if (!userSelectStyleSheet.parentNode) {
+ document.head.appendChild(userSelectStyleSheet);
+ }
+ }
+ /**
+ * Enable user ability to select text on page
+ */ function enableUserSelect() {
+ if (userSelectStyleSheet.parentNode) {
+ userSelectStyleSheet.parentNode.removeChild(userSelectStyleSheet);
+ }
+ }
+ /**
+ * Get the metadata for a SVG container
+ *
+ * @param {SVGElement} svg The SVG container to get metadata for
+ */ function getMetadata(svg) {
+ return {
+ documentId: svg.getAttribute('data-pdf-annotate-document'),
+ pageNumber: parseInt(svg.getAttribute('data-pdf-annotate-page'), 10),
+ viewport: JSON.parse(svg.getAttribute('data-pdf-annotate-viewport')),
+ };
+ }
+
+ /*
+ * This function rounds a digit
+ * @param {type} num digit, which should be rounded
+ * @param {type} places
+ * @return {undefined}
+ */
+ function roundDigits(num, places) {
+ return +(Math.round(num + 'e+' + places) + 'e-' + places);
+ }
+ },
+ /* 7 */
+ function (module, exports) {
+ module.exports = function createStyleSheet(blocks) {
+ var style = document.createElement('style');
+ var text = Object.keys(blocks)
+ .map(function (selector) {
+ return processRuleSet(selector, blocks[selector]);
+ })
+ .join('\n');
+ style.setAttribute('type', 'text/css');
+ style.appendChild(document.createTextNode(text));
+ return style;
+ };
+ function processRuleSet(selector, block) {
+ return selector + ' {\n' + processDeclarationBlock(block) + '\n}';
+ }
+ function processDeclarationBlock(block) {
+ return Object.keys(block)
+ .map(function (prop) {
+ return processDeclaration(prop, block[prop]);
+ })
+ .join('\n');
+ }
+ function processDeclaration(prop, value) {
+ if (!isNaN(value) && value != 0) {
+ value = value + 'px';
+ }
+ return hyphenate(prop) + ': ' + value + ';';
+ }
+ function hyphenate(prop) {
+ return prop.replace(/[A-Z]/g, function (match) {
+ return '-' + match.toLowerCase();
+ });
+ }
+ },
+ /* 8 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _uuid = __webpack_require__(9);
+ var _uuid2 = _interopRequireDefault(_uuid);
+ var _StoreAdapter2 = __webpack_require__(2);
+ var _StoreAdapter3 = _interopRequireDefault(_StoreAdapter2);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ function _classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError('Cannot call a class as a function');
+ }
+ }
+ function _possibleConstructorReturn(self, call) {
+ if (!self) {
+ throw new ReferenceError(
+ "this hasn't been initialised - super() hasn't been called"
+ );
+ }
+ return call &&
+ ((typeof call === 'undefined' ? 'undefined' : _typeof2(call)) === 'object' ||
+ typeof call === 'function')
+ ? call
+ : self;
+ }
+ function _inherits(subClass, superClass) {
+ if (typeof superClass !== 'function' && superClass !== null) {
+ throw new TypeError(
+ 'Super expression must either be null or a function, not ' +
+ (typeof superClass === 'undefined' ? 'undefined' : _typeof2(superClass))
+ );
+ }
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
+ constructor: {
+ value: subClass,
+ enumerable: false,
+ writable: true,
+ configurable: true,
+ },
+ });
+ if (superClass)
+ Object.setPrototypeOf
+ ? Object.setPrototypeOf(subClass, superClass)
+ : (subClass.__proto__ = superClass);
+ }
+ // StoreAdapter for working with localStorage
+ // This is ideal for testing, examples, and prototyping
+ var LocalStoreAdapter = (function (_StoreAdapter) {
+ _inherits(LocalStoreAdapter, _StoreAdapter);
+ function LocalStoreAdapter() {
+ _classCallCheck(this, LocalStoreAdapter);
+ return _possibleConstructorReturn(
+ this,
+ Object.getPrototypeOf(LocalStoreAdapter).call(this, {
+ getAnnotations: function getAnnotations(documentId, pageNumber) {
+ return new Promise(function (resolve, reject) {
+ var annotations = _getAnnotations(documentId).filter(function (
+ i
+ ) {
+ return i.page === pageNumber && i.class === 'Annotation';
+ });
+ resolve({
+ documentId: documentId,
+ pageNumber: pageNumber,
+ annotations: annotations,
+ });
+ });
+ },
+ getAnnotation: function getAnnotation(documentId, annotationId) {
+ return Promise.resolve(
+ _getAnnotations(documentId)[
+ findAnnotation(documentId, annotationId)
+ ]
+ );
+ },
+ addAnnotation: function addAnnotation(
+ documentId,
+ pageNumber,
+ annotation
+ ) {
+ return new Promise(function (resolve, reject) {
+ annotation.class = 'Annotation';
+ annotation.uuid = (0, _uuid2.default)();
+ annotation.page = pageNumber;
+ var annotations = _getAnnotations(documentId);
+ annotations.push(annotation);
+ updateAnnotations(documentId, annotations);
+ resolve(annotation);
+ });
+ },
+ editAnnotation: function editAnnotation(
+ documentId,
+ annotationId,
+ annotation
+ ) {
+ return new Promise(function (resolve, reject) {
+ var annotations = _getAnnotations(documentId);
+ annotations[findAnnotation(documentId, annotationId)] =
+ annotation;
+ updateAnnotations(documentId, annotations);
+ resolve(annotation);
+ });
+ },
+ deleteAnnotation: function deleteAnnotation(documentId, annotationId) {
+ return new Promise(function (resolve, reject) {
+ var index = findAnnotation(documentId, annotationId);
+ if (index > -1) {
+ var annotations = _getAnnotations(documentId);
+ annotations.splice(index, 1);
+ updateAnnotations(documentId, annotations);
+ }
+ resolve(true);
+ });
+ },
+ getComments: function getComments(documentId, annotationId) {
+ return new Promise(function (resolve, reject) {
+ resolve(
+ _getAnnotations(documentId).filter(function (i) {
+ return (
+ i.class === 'Comment' &&
+ i.annotation === annotationId
+ );
+ })
+ );
+ });
+ },
+ addComment: function addComment(documentId, annotationId, content) {
+ return new Promise(function (resolve, reject) {
+ var comment = {
+ class: 'Comment',
+ uuid: (0, _uuid2.default)(),
+ annotation: annotationId,
+ content: content,
+ };
+ var annotations = _getAnnotations(documentId);
+ annotations.push(comment);
+ updateAnnotations(documentId, annotations);
+ resolve(comment);
+ });
+ },
+ deleteComment: function deleteComment(documentId, commentId) {
+ return new Promise(function (resolve, reject) {
+ _getAnnotations(documentId);
+ var index = -1;
+ var annotations = _getAnnotations(documentId);
+ for (var i = 0, l = annotations.length; i < l; i++) {
+ if (annotations[i].uuid === commentId) {
+ index = i;
+ break;
+ }
+ }
+ if (index > -1) {
+ annotations.splice(index, 1);
+ updateAnnotations(documentId, annotations);
+ }
+ resolve(true);
+ });
+ },
+ })
+ );
+ }
+ return LocalStoreAdapter;
+ })(_StoreAdapter3.default);
+ exports.default = LocalStoreAdapter;
+ function _getAnnotations(documentId) {
+ return JSON.parse(localStorage.getItem(documentId + '/annotations')) || [];
+ }
+ function updateAnnotations(documentId, annotations) {
+ localStorage.setItem(documentId + '/annotations', JSON.stringify(annotations));
+ }
+ function findAnnotation(documentId, annotationId) {
+ var index = -1;
+ var annotations = _getAnnotations(documentId);
+ for (var i = 0, l = annotations.length; i < l; i++) {
+ if (annotations[i].uuid === annotationId) {
+ index = i;
+ break;
+ }
+ }
+ return index;
+ }
+ module.exports = exports['default'];
+ },
+ /* 9 */
+ function (module, exports) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = uuid;
+ var REGEXP = /[xy]/g;
+ var PATTERN = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
+ function replacement(c) {
+ var r = (Math.random() * 16) | 0;
+ var v = c == 'x' ? r : (r & 0x3) | 0x8;
+ return v.toString(16);
+ }
+ /**
+ * Generate a univierally unique identifier
+ *
+ * @return {String}
+ */ function uuid() {
+ return PATTERN.replace(REGEXP, replacement);
+ }
+ module.exports = exports['default'];
+ },
+ /* 10 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = render;
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _appendChild = __webpack_require__(11);
+ var _appendChild2 = _interopRequireDefault(_appendChild);
+ var _renderScreenReaderHints = __webpack_require__(20);
+ var _renderScreenReaderHints2 = _interopRequireDefault(_renderScreenReaderHints);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ /**
+ * Render the response from PDFJSAnnotate.getStoreAdapter().getAnnotations to SVG
+ *
+ * @param {SVGElement} svg The SVG element to render the annotations to
+ * @param {Object} viewport The page viewport data
+ * @param {Object} data The response from PDFJSAnnotate.getStoreAdapter().getAnnotations
+ * @return {Promise} Settled once rendering has completed
+ * A settled Promise will be either:
+ * - fulfilled: SVGElement
+ * - rejected: Error
+ */ function render(svg, viewport, data) {
+ return new Promise(function (resolve, reject) {
+ // Reset the content of the SVG
+ svg.innerHTML = '';
+ svg.setAttribute('data-pdf-annotate-container', true);
+ svg.setAttribute('data-pdf-annotate-viewport', JSON.stringify(viewport));
+ svg.removeAttribute('data-pdf-annotate-document');
+ svg.removeAttribute('data-pdf-annotate-page'); // If there's no data nothing can be done
+ if (!data) {
+ return resolve(svg);
+ }
+ svg.setAttribute('data-pdf-annotate-document', data.documentId);
+ svg.setAttribute('data-pdf-annotate-page', data.pageNumber); // Make sure annotations is an array
+ if (!Array.isArray(data.annotations) || data.annotations.length === 0) {
+ return resolve(svg);
+ } // Append annotation to svg
+
+ data.annotations.forEach(function (a) {
+ (0, _appendChild2.default)(svg, a, viewport);
+ });
+ resolve(svg);
+ });
+ }
+ module.exports = exports['default'];
+ },
+ /* 11 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = appendChild;
+ var _objectAssign = __webpack_require__(12);
+ var _objectAssign2 = _interopRequireDefault(_objectAssign);
+ var _renderLine = __webpack_require__(13);
+ var _renderLine2 = _interopRequireDefault(_renderLine);
+ var _renderPath = __webpack_require__(16);
+ var _renderPath2 = _interopRequireDefault(_renderPath);
+ var _renderPoint = __webpack_require__(17);
+ var _renderPoint2 = _interopRequireDefault(_renderPoint);
+ var _renderRect = __webpack_require__(18);
+ var _renderRect2 = _interopRequireDefault(_renderRect);
+ var _renderText = __webpack_require__(19);
+ var _renderText2 = _interopRequireDefault(_renderText);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ var isFirefox = /firefox/i.test(navigator.userAgent);
+ /**
+ * Get the x/y translation to be used for transforming the annotations
+ * based on the rotation of the viewport.
+ *
+ * @param {Object} viewport The viewport data from the page
+ * @return {Object}
+ */ function getTranslation(viewport) {
+ var x = void 0;
+ var y = void 0; // Modulus 360 on the rotation so that we only
+ // have to worry about four possible values.
+ switch (viewport.rotation % 360) {
+ case 0:
+ x = y = 0;
+ break;
+ case 90:
+ x = 0;
+ y = (viewport.width / viewport.scale) * -1;
+ break;
+ case 180:
+ x = (viewport.width / viewport.scale) * -1;
+ y = (viewport.height / viewport.scale) * -1;
+ break;
+ case 270:
+ x = (viewport.height / viewport.scale) * -1;
+ y = 0;
+ break;
+ }
+ return { x: x, y: y };
+ }
+ /**
+ * Transform the rotation and scale of a node using SVG's native transform attribute.
+ *
+ * @param {Node} node The node to be transformed
+ * @param {Object} viewport The page's viewport data
+ * @return {Node}
+ */ function transform(node, viewport) {
+ var trans = getTranslation(viewport); // Let SVG natively transform the element
+ node.setAttribute(
+ 'transform',
+ 'scale(' +
+ viewport.scale +
+ ') rotate(' +
+ viewport.rotation +
+ ') translate(' +
+ trans.x +
+ ', ' +
+ trans.y +
+ ')'
+ );
+ // Manually adjust x/y for nested SVG nodes
+ if (!isFirefox && node.nodeName.toLowerCase() === 'svg') {
+ node.setAttribute('x', parseInt(node.getAttribute('x'), 10) * viewport.scale);
+ node.setAttribute('y', parseInt(node.getAttribute('y'), 10) * viewport.scale);
+ var x = parseInt(node.getAttribute('x', 10));
+ var y = parseInt(node.getAttribute('y', 10));
+ var width = parseInt(node.getAttribute('width'), 10);
+ var height = parseInt(node.getAttribute('height'), 10);
+ var path = node.querySelector('path');
+ var svg = path.parentNode; // Scale width/height
+ [node, svg, path, node.querySelector('circle')].forEach(function (n) {
+ n.setAttribute(
+ 'width',
+ parseInt(n.getAttribute('width'), 10) * viewport.scale
+ );
+ n.setAttribute(
+ 'height',
+ parseInt(n.getAttribute('height'), 10) * viewport.scale
+ );
+ });
+ // Transform path but keep scale at 100% since it will be handled natively
+ transform(path, (0, _objectAssign2.default)({}, viewport, { scale: 1 }));
+ switch (viewport.rotation % 360) {
+ case 90:
+ node.setAttribute('x', viewport.width - y - width);
+ node.setAttribute('y', x);
+ svg.setAttribute('x', 1);
+ svg.setAttribute('y', 0);
+ break;
+ case 180:
+ node.setAttribute('x', viewport.width - x - width);
+ node.setAttribute('y', viewport.height - y - height);
+ svg.setAttribute('y', 2);
+ break;
+ case 270:
+ node.setAttribute('x', y);
+ node.setAttribute('y', viewport.height - x - height);
+ svg.setAttribute('x', -1);
+ svg.setAttribute('y', 0);
+ break;
+ }
+ }
+ return node;
+ }
+ /**
+ * Append an annotation as a child of an SVG.
+ *
+ * @param {SVGElement} svg The SVG element to append the annotation to
+ * @param {Object} annotation The annotation definition to render and append
+ * @param {Object} viewport The page's viewport data
+ * @return {SVGElement} A node that was created and appended by this function
+ */ function appendChild(svg, annotation, viewport) {
+ if (!viewport) {
+ viewport = JSON.parse(svg.getAttribute('data-pdf-annotate-viewport'));
+ }
+ annotation.viewport = viewport;
+ var child = void 0;
+ switch (annotation.type) {
+ case 'area':
+ case 'highlight':
+ child = (0, _renderRect2.default)(annotation);
+ break;
+ case 'strikeout':
+ child = (0, _renderLine2.default)(annotation);
+ break;
+ case 'point':
+ child = (0, _renderPoint2.default)(annotation);
+ break;
+ case 'textbox':
+ child = (0, _renderText2.default)(annotation);
+ break;
+ case 'drawing':
+ child = (0, _renderPath2.default)(annotation);
+ break;
+ } // If no type was provided for an annotation it will result in node being null.
+ // Skip appending/transforming if node doesn't exist.
+ if (child) {
+ // Set attributes
+ child.setAttribute('data-pdf-annotate-id', annotation.uuid);
+ child.setAttribute('data-pdf-annotate-type', annotation.type);
+ child.setAttribute('data-pdf-annotate-owner', annotation.owner);
+ child.setAttribute('aria-hidden', true);
+ svg.appendChild(transform(child, viewport));
+ }
+ return child;
+ }
+ module.exports = exports['default'];
+ },
+ /* 12 */
+ function (module, exports) {
+ /* eslint-disable no-unused-vars */
+ 'use strict';
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
+ var propIsEnumerable = Object.prototype.propertyIsEnumerable;
+ function toObject(val) {
+ if (val === null || val === undefined) {
+ throw new TypeError('Object.assign cannot be called with null or undefined');
+ }
+ return Object(val);
+ }
+ module.exports =
+ Object.assign ||
+ function (target, source) {
+ var from;
+ var to = toObject(target);
+ var symbols;
+ for (var s = 1; s < arguments.length; s++) {
+ from = Object(arguments[s]);
+ for (var key in from) {
+ if (hasOwnProperty.call(from, key)) {
+ to[key] = from[key];
+ }
+ }
+ if (Object.getOwnPropertySymbols) {
+ symbols = Object.getOwnPropertySymbols(from);
+ for (var i = 0; i < symbols.length; i++) {
+ if (propIsEnumerable.call(from, symbols[i])) {
+ to[symbols[i]] = from[symbols[i]];
+ }
+ }
+ }
+ }
+ return to;
+ };
+ },
+ /* 13 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = renderLine;
+ var _setAttributes = __webpack_require__(14);
+ var _setAttributes2 = _interopRequireDefault(_setAttributes);
+ var _normalizeColor = __webpack_require__(15);
+ var _normalizeColor2 = _interopRequireDefault(_normalizeColor);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ /**
+ * Create SVGLineElements from an annotation definition.
+ * This is used for anntations of type `strikeout`.
+ *
+ * @param {Object} a The annotation definition
+ * @return {SVGGElement} A group of all lines to be rendered
+ */ function renderLine(a) {
+ var group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
+ (0, _setAttributes2.default)(group, {
+ stroke: (0, _normalizeColor2.default)(a.color || '#f00'),
+ strokeWidth: 1,
+ });
+ a.rectangles.forEach(function (r) {
+ var line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
+ (0,
+ _setAttributes2.default)(line, { x1: r.x, y1: r.y, x2: r.x + r.width, y2: r.y });
+ group.appendChild(line);
+ });
+ return group;
+ }
+ module.exports = exports['default'];
+ },
+ /* 14 */
+ function (module, exports) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = setAttributes;
+ var UPPER_REGEX = /[A-Z]/g;
+ // Don't convert these attributes from camelCase to hyphenated-attributes
+ var BLACKLIST = ['viewBox'];
+ var keyCase = function keyCase(key) {
+ if (BLACKLIST.indexOf(key) === -1) {
+ key = key.replace(UPPER_REGEX, function (match) {
+ return '-' + match.toLowerCase();
+ });
+ }
+ return key;
+ };
+ /**
+ * Set attributes for a node from a map
+ *
+ * @param {Node} node The node to set attributes on
+ * @param {Object} attributes The map of key/value pairs to use for attributes
+ */ function setAttributes(node, attributes) {
+ Object.keys(attributes).forEach(function (key) {
+ node.setAttribute(keyCase(key), attributes[key]);
+ });
+ }
+ module.exports = exports['default'];
+ },
+ /* 15 */
+ function (module, exports) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = normalizeColor;
+ var REGEX_HASHLESS_HEX = /^([a-f0-9]{6}|[a-f0-9]{3})$/i;
+ /**
+ * Normalize a color value
+ *
+ * @param {String} color The color to normalize
+ * @return {String}
+ */ function normalizeColor(color) {
+ if (REGEX_HASHLESS_HEX.test(color)) {
+ color = '#' + color;
+ }
+ return color;
+ }
+ module.exports = exports['default'];
+ },
+ /* 16 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = renderPath;
+ var _setAttributes = __webpack_require__(14);
+ var _setAttributes2 = _interopRequireDefault(_setAttributes);
+ var _normalizeColor = __webpack_require__(15);
+ var _normalizeColor2 = _interopRequireDefault(_normalizeColor);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ /**
+ * Create SVGPathElement from an annotation definition.
+ * This is used for anntations of type `drawing`.
+ *
+ * @param {Object} a The annotation definition
+ * @return {SVGPathElement} The path to be rendered
+ */ function renderPath(a) {
+ var d = [];
+ var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
+ for (var i = 0, l = a.lines.length; i < l; i++) {
+ var p1 = a.lines[i];
+ var p2 = a.lines[i + 1];
+ if (p2) {
+ d.push('M' + p1[0] + ' ' + p1[1] + ' ' + p2[0] + ' ' + p2[1]);
+ }
+ }
+ (0, _setAttributes2.default)(path, {
+ d: d.join(' ') + 'Z',
+ stroke: (0, _normalizeColor2.default)(a.color || '#000'),
+ strokeWidth: a.width || 1,
+ fill: 'none',
+ });
+ return path;
+ }
+ module.exports = exports['default'];
+ },
+ /* 17 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = renderPoint;
+ var _setAttributes = __webpack_require__(14);
+ var _setAttributes2 = _interopRequireDefault(_setAttributes);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ var SIZE = 20;
+ var D =
+ 'M499.968 214.336q-113.832 0 -212.877 38.781t-157.356 104.625 -58.311 142.29q0 62.496 39.897 119.133t112.437 97.929l48.546 27.9 -15.066 53.568q-13.392 50.778 -39.06 95.976 84.816 -35.154 153.45 -95.418l23.994 -21.204 31.806 3.348q38.502 4.464 72.54 4.464 113.832 0 212.877 -38.781t157.356 -104.625 58.311 -142.29 -58.311 -142.29 -157.356 -104.625 -212.877 -38.781z';
+ /**
+ * Create SVGElement from an annotation definition.
+ * This is used for anntations of type `comment`.
+ *
+ * @param {Object} a The annotation definition
+ * @return {SVGElement} A svg to be rendered
+ */ function renderPoint(a) {
+ let posX = a.x;
+ let posY = a.y;
+
+ let colorInner;
+ let colorLine;
+ if (a.color) {
+ colorInner = 'rgba(255,237,0,.8)';
+ colorLine = 'rgb(246,168,0)';
+ } else {
+ colorInner = 'rgba(142,186,229,.8)';
+ colorLine = 'rgb(0,84,159)';
+ }
+
+ var outerSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+ var innerSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+ var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
+ var path2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
+ var circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
+ (0, _setAttributes2.default)(outerSVG, {
+ width: SIZE / 2 + 1,
+ height: SIZE,
+ x: posX - SIZE / 4,
+ y: posY - SIZE,
+ });
+ (0, _setAttributes2.default)(innerSVG, {
+ width: SIZE,
+ height: SIZE,
+ x: 0,
+ y: SIZE * 0.05 * -1,
+ viewBox: '-16 -18 64 64',
+ });
+ (0, _setAttributes2.default)(path, {
+ d: 'M0,47 Q0,28 10,15 A15,15 0,1,0 -10,15 Q0,28 0,47',
+ stroke: 'none',
+ fill: colorInner,
+ transform: '',
+ });
+ (0, _setAttributes2.default)(path2, {
+ d: 'M0,47 Q0,28 10,15 A15,15 0,1,0 -10,15 Q0,28 0,47',
+ strokeWidth: 1,
+ stroke: colorLine,
+ fill: 'none',
+ });
+ (0, _setAttributes2.default)(circle, {
+ cx: 0,
+ cy: 4,
+ r: 4,
+ stroke: 'none',
+ fill: colorLine,
+ });
+ innerSVG.appendChild(path);
+ innerSVG.appendChild(path2);
+ innerSVG.appendChild(circle);
+ outerSVG.appendChild(innerSVG);
+
+ return outerSVG;
+ }
+ module.exports = exports['default'];
+ },
+ /* 18 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _typeof =
+ typeof Symbol === 'function' && _typeof2(Symbol.iterator) === 'symbol'
+ ? function (obj) {
+ return typeof obj === 'undefined' ? 'undefined' : _typeof2(obj);
+ }
+ : function (obj) {
+ return obj && typeof Symbol === 'function' && obj.constructor === Symbol
+ ? 'symbol'
+ : typeof obj === 'undefined'
+ ? 'undefined'
+ : _typeof2(obj);
+ };
+ exports.default = renderRect;
+ var _setAttributes = __webpack_require__(14);
+ var _setAttributes2 = _interopRequireDefault(_setAttributes);
+ var _normalizeColor = __webpack_require__(15);
+ var _normalizeColor2 = _interopRequireDefault(_normalizeColor);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ /**
+ * Create SVGRectElements from an annotation definition.
+ * This is used for anntations of type `area` and `highlight`.
+ *
+ * @param {Object} a The annotation definition
+ * @return {SVGGElement|SVGRectElement} A group of all rects to be rendered
+ */ function renderRect(a) {
+ if (a.type === 'highlight') {
+ var _ret = (function () {
+ var group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
+ (0, _setAttributes2.default)(group, {
+ fill: (0, _normalizeColor2.default)(a.color || 'rgb(142,186,229)'),
+ fillOpacity: 0.35,
+ });
+ a.rectangles.forEach(function (r) {
+ group.appendChild(createRect(r));
+ });
+ return { v: group };
+ })();
+ if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === 'object')
+ return _ret.v;
+ } else {
+ var rect = createRect(a);
+ (0, _setAttributes2.default)(rect, {
+ stroke: (0, _normalizeColor2.default)(a.color || 'rgb(0,84,159)'),
+ fill: 'none',
+ });
+ return rect;
+ }
+ }
+ function createRect(r) {
+ var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ (0, _setAttributes2.default)(rect, {
+ x: r.x,
+ y: r.y,
+ width: r.width,
+ height: r.height,
+ });
+ return rect;
+ }
+ module.exports = exports['default'];
+ },
+ /* 19 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = renderText;
+ var _setAttributes = __webpack_require__(14);
+ var _setAttributes2 = _interopRequireDefault(_setAttributes);
+ var _normalizeColor = __webpack_require__(15);
+ var _normalizeColor2 = _interopRequireDefault(_normalizeColor);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ /**
+ * Create SVGTextElement from an annotation definition.
+ * This is used for anntations of type `textbox`.
+ *
+ * @param {Object} a The annotation definition
+ * @return {SVGTextElement} A text to be rendered
+ */ function renderText(a) {
+ var text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
+ (0, _setAttributes2.default)(text, {
+ x: a.x,
+ y: a.y + parseInt(a.size, 10),
+ fill: (0, _normalizeColor2.default)(a.color || '#000'),
+ fontSize: a.size,
+ });
+ text.innerHTML = a.content;
+ return text;
+ }
+ module.exports = exports['default'];
+ },
+ /* 20 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = renderScreenReaderHints;
+ var _insertScreenReaderHint = __webpack_require__(21);
+ var _insertScreenReaderHint2 = _interopRequireDefault(_insertScreenReaderHint);
+ var _initEventHandlers = __webpack_require__(27);
+ var _initEventHandlers2 = _interopRequireDefault(_initEventHandlers);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ // TODO This is not the right place for this to live
+ (0, _initEventHandlers2.default)();
+ /**
+ * Insert hints into the DOM for screen readers.
+ *
+ * @param {Array} annotations The annotations that hints are inserted for
+ */ function renderScreenReaderHints(annotations) {
+ annotations = Array.isArray(annotations) ? annotations : []; // Insert hints for each type
+ Object.keys(SORT_TYPES).forEach(function (type) {
+ var sortBy = SORT_TYPES[type];
+ annotations
+ .filter(function (a) {
+ return a.type === type;
+ })
+ .sort(sortBy)
+ .forEach(function (a, i) {
+ return (0, _insertScreenReaderHint2.default)(a, i + 1);
+ });
+ });
+ }
+ // Sort annotations first by y, then by x.
+ // This allows hints to be injected in the order they appear,
+ // which makes numbering them easier.
+ function sortByPoint(a, b) {
+ if (a.y < b.y) {
+ return a.x - b.x;
+ } else {
+ return 1;
+ }
+ } // Sort annotation by it's first rectangle
+ function sortByRectPoint(a, b) {
+ return sortByPoint(a.rectangles[0], b.rectangles[0]);
+ } // Sort annotation by it's first line
+ function sortByLinePoint(a, b) {
+ var lineA = a.lines[0];
+ var lineB = b.lines[0];
+ return sortByPoint({ x: lineA[0], y: lineA[1] }, { x: lineB[0], y: lineB[1] });
+ } // Arrange supported types and associated sort methods
+ var SORT_TYPES = {
+ highlight: sortByRectPoint,
+ strikeout: sortByRectPoint,
+ drawing: sortByLinePoint,
+ textbox: sortByPoint,
+ point: sortByPoint,
+ area: sortByPoint,
+ };
+ module.exports = exports['default'];
+ },
+ /* 21 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = insertScreenReaderHint;
+ var _createScreenReaderOnly = __webpack_require__(22);
+ var _createScreenReaderOnly2 = _interopRequireDefault(_createScreenReaderOnly);
+ var _insertElementWithinChildren = __webpack_require__(23);
+ var _insertElementWithinChildren2 =
+ _interopRequireDefault(_insertElementWithinChildren);
+ var _insertElementWithinElement = __webpack_require__(24);
+ var _insertElementWithinElement2 = _interopRequireDefault(_insertElementWithinElement);
+ var _renderScreenReaderComments = __webpack_require__(25);
+ var _renderScreenReaderComments2 = _interopRequireDefault(_renderScreenReaderComments);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ } // Annotation types that support comments
+ var COMMENT_TYPES = ['highlight', 'point', 'area', 'strikeout'];
+ /**
+ * Insert a hint into the DOM for screen readers for a specific annotation.
+ *
+ * @param {Object} annotation The annotation to insert a hint for
+ * @param {Number} num The number of the annotation out of all annotations of the same type
+ */ function insertScreenReaderHint(annotation) {
+ var num = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
+ switch (annotation.type) {
+ case 'highlight':
+ case 'strikeout':
+ var rects = annotation.rectangles;
+ var first = rects[0];
+ var last = rects[rects.length - 1];
+ (0, _insertElementWithinElement2.default)(
+ (0, _createScreenReaderOnly2.default)(
+ 'Begin ' + annotation.type + ' annotation ' + num,
+ annotation.uuid
+ ),
+ first.x,
+ first.y,
+ annotation.page,
+ true
+ );
+ (0, _insertElementWithinElement2.default)(
+ (0, _createScreenReaderOnly2.default)(
+ 'End ' + annotation.type + ' annotation ' + num,
+ annotation.uuid + '-end'
+ ),
+ last.x + last.width,
+ last.y,
+ annotation.page,
+ false
+ );
+ break;
+ case 'textbox':
+ case 'point':
+ var text =
+ annotation.type === 'textbox'
+ ? ' (content: ' + annotation.content + ')'
+ : '';
+ (0, _insertElementWithinChildren2.default)(
+ (0, _createScreenReaderOnly2.default)(
+ annotation.type + ' annotation ' + num + text,
+ annotation.uuid
+ ),
+ annotation.x,
+ annotation.y,
+ annotation.page
+ );
+ break;
+ case 'drawing':
+ case 'area':
+ var x =
+ typeof annotation.x !== 'undefined'
+ ? annotation.x
+ : annotation.lines[0][0];
+ var y =
+ typeof annotation.y !== 'undefined'
+ ? annotation.y
+ : annotation.lines[0][1];
+ (0, _insertElementWithinChildren2.default)(
+ (0, _createScreenReaderOnly2.default)(
+ 'Unlabeled drawing',
+ annotation.uuid
+ ),
+ x,
+ y,
+ annotation.page
+ );
+ break;
+ } // Include comments in screen reader hint
+ if (COMMENT_TYPES.includes(annotation.type)) {
+ (0, _renderScreenReaderComments2.default)(
+ annotation.documentId,
+ annotation.uuid
+ );
+ }
+ }
+ module.exports = exports['default'];
+ },
+ /* 22 */
+ function (module, exports) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = createScreenReaderOnly;
+ /**
+ * Create a node that is only visible to screen readers
+ *
+ * @param {String} content The text content that should be read by screen reader
+ * @param {String} [annotationId] The ID of the annotation assocaited
+ * @return {Element} An Element that is only visible to screen readers
+ */ function createScreenReaderOnly(content, annotationId) {
+ var node = document.createElement('div');
+ var text = document.createTextNode(content);
+ node.appendChild(text);
+ node.setAttribute('id', 'pdf-annotate-screenreader-' + annotationId);
+ node.style.position = 'absolute';
+ node.style.left = '-10000px';
+ node.style.top = 'auto';
+ node.style.width = '1px';
+ node.style.height = '1px';
+ node.style.overflow = 'hidden';
+ return node;
+ }
+ module.exports = exports['default'];
+ },
+ /* 23 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = insertElementWithinChildren;
+ var _insertElementWithinElement = __webpack_require__(24);
+ var _insertElementWithinElement2 = _interopRequireDefault(_insertElementWithinElement);
+ var _utils = __webpack_require__(6);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ function _toConsumableArray(arr) {
+ if (Array.isArray(arr)) {
+ for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
+ arr2[i] = arr[i];
+ }
+ return arr2;
+ } else {
+ return Array.from(arr);
+ }
+ }
+ /**
+ * Insert an element at a point within the document.
+ * This algorithm will try to insert between elements if possible.
+ * It will however use `insertElementWithinElement` if it is more accurate.
+ *
+ * @param {Element} el The element to be inserted
+ * @param {Number} x The x coordinate of the point
+ * @param {Number} y The y coordinate of the point
+ * @param {Number} pageNumber The page number to limit elements to
+ * @return {Boolean} True if element was able to be inserted, otherwise false
+ */ function insertElementWithinChildren(el, x, y, pageNumber) {
+ // Try and use most accurate method of inserting within an element
+ if ((0, _insertElementWithinElement2.default)(el, x, y, pageNumber, true)) {
+ return true;
+ } // Fall back to inserting between elements
+ var svg = document.querySelector(
+ 'svg[data-pdf-annotate-page="' + pageNumber + '"]'
+ );
+ var rect = svg.getBoundingClientRect();
+ var nodes = [].concat(
+ _toConsumableArray(svg.parentNode.querySelectorAll('.textLayer > div'))
+ );
+ y = (0, _utils.scaleUp)(svg, { y: y }).y + rect.top;
+ x = (0, _utils.scaleUp)(svg, { x: x }).x + rect.left; // Find the best node to insert before
+ for (var i = 0, l = nodes.length; i < l; i++) {
+ var n = nodes[i];
+ var r = n.getBoundingClientRect();
+ if (y <= r.top) {
+ n.parentNode.insertBefore(el, n);
+ return true;
+ }
+ } // If all else fails try to append to the bottom
+ var textLayer = svg.parentNode.querySelector('.textLayer');
+ if (textLayer) {
+ var textRect = textLayer.getBoundingClientRect();
+ if ((0, _utils.pointIntersectsRect)(x, y, textRect)) {
+ textLayer.appendChild(el);
+ return true;
+ }
+ }
+ return false;
+ }
+ module.exports = exports['default'];
+ },
+ /* 24 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = insertElementWithinElement;
+ var _utils = __webpack_require__(6);
+ function _toConsumableArray(arr) {
+ if (Array.isArray(arr)) {
+ for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
+ arr2[i] = arr[i];
+ }
+ return arr2;
+ } else {
+ return Array.from(arr);
+ }
+ }
+ /**
+ * Insert an element at a point within the document.
+ * This algorithm will only insert within an element amidst it's text content.
+ *
+ * @param {Element} el The element to be inserted
+ * @param {Number} x The x coordinate of the point
+ * @param {Number} y The y coordinate of the point
+ * @param {Number} pageNumber The page number to limit elements to
+ * @param {Boolean} insertBefore Whether the element is to be inserted before or after x
+ * @return {Boolean} True if element was able to be inserted, otherwise false
+ */ function insertElementWithinElement(el, x, y, pageNumber, insertBefore) {
+ var OFFSET_ADJUST = 2; // If inserting before adjust `x` by looking for element a few px to the right
+ // Otherwise adjust a few px to the left
+ // This is to allow a little tolerance by searching within the box, instead
+ // of getting a false negative by testing right on the border.
+ x = Math.max(x + OFFSET_ADJUST * (insertBefore ? 1 : -1), 0);
+ var node = textLayerElementFromPoint(x, y + OFFSET_ADJUST, pageNumber);
+ if (!node) {
+ return false;
+ } // Now that node has been found inverse the adjustment for `x`.
+ // This is done to accomodate tolerance by cutting off on the outside of the
+ // text boundary, instead of missing a character by cutting off within.
+ x = x + OFFSET_ADJUST * (insertBefore ? -1 : 1);
+ var svg = document.querySelector(
+ 'svg[data-pdf-annotate-page="' + pageNumber + '"]'
+ );
+ var left =
+ (0, _utils.scaleDown)(svg, { left: node.getBoundingClientRect().left }).left -
+ svg.getBoundingClientRect().left;
+ var temp = node.cloneNode(true);
+ var head = temp.innerHTML.split('');
+ var tail = []; // Insert temp off screen
+ temp.style.position = 'absolute';
+ temp.style.top = '-10000px';
+ temp.style.left = '-10000px';
+ document.body.appendChild(temp);
+ while (head.length) {
+ // Don't insert within HTML tags
+ if (head[head.length - 1] === '>') {
+ while (head.length) {
+ tail.unshift(head.pop());
+ if (tail[0] === '<') {
+ break;
+ }
+ }
+ } // Check if width of temp based on current head value satisfies x
+ temp.innerHTML = head.join('');
+ var width = (0, _utils.scaleDown)(svg, {
+ width: temp.getBoundingClientRect().width,
+ }).width;
+ if (left + width <= x) {
+ break;
+ }
+ tail.unshift(head.pop());
+ } // Update original node with new markup, including element to be inserted
+ node.innerHTML = head.join('') + el.outerHTML + tail.join('');
+ temp.parentNode.removeChild(temp);
+ return true;
+ }
+ /**
+ * Get a text layer element at a given point on a page
+ *
+ * @param {Number} x The x coordinate of the point
+ * @param {Number} y The y coordinate of the point
+ * @param {Number} pageNumber The page to limit elements to
+ * @return {Element} First text layer element found at the point
+ */ function textLayerElementFromPoint(x, y, pageNumber) {
+ var svg = document.querySelector(
+ 'svg[data-pdf-annotate-page="' + pageNumber + '"]'
+ );
+ var rect = svg.getBoundingClientRect();
+ y = (0, _utils.scaleUp)(svg, { y: y }).y + rect.top;
+ x = (0, _utils.scaleUp)(svg, { x: x }).x + rect.left;
+ return []
+ .concat(
+ _toConsumableArray(
+ svg.parentNode.querySelectorAll('.textLayer [data-canvas-width]')
+ )
+ )
+ .filter(function (el) {
+ return (0, _utils.pointIntersectsRect)(x, y, el.getBoundingClientRect());
+ })[0];
+ }
+ module.exports = exports['default'];
+ },
+ /* 25 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = renderScreenReaderComments;
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _insertScreenReaderComment = __webpack_require__(26);
+ var _insertScreenReaderComment2 = _interopRequireDefault(_insertScreenReaderComment);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ /**
+ * Insert the comments into the DOM to be available by screen reader
+ *
+ * Example output:
+ *
+ *
Begin highlight 1
+ *
+ * - Foo
+ * - Bar
+ * - Baz
+ * - Qux
+ *
+ *
+ * Some highlighted text goes here...
+ * End highlight 1
+ *
+ * NOTE: `screenReaderOnly` is not a real class, just used for brevity
+ *
+ * @param {String} documentId The ID of the document
+ * @param {String} annotationId The ID of the annotation
+ * @param {Array} [comments] Optionally preloaded comments to be rendered
+ * @return {Promise}
+ */ function renderScreenReaderComments(documentId, annotationId, comments) {
+ var promise = void 0;
+ if (Array.isArray(comments)) {
+ promise = Promise.resolve(comments);
+ } else {
+ promise = _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .getComments(documentId, annotationId);
+ }
+ return promise.then(function (comments) {
+ // Node needs to be found by querying DOM as it may have been inserted as innerHTML
+ // leaving `screenReaderNode` as an invalid reference (see `insertElementWithinElement`).
+ var node = document.getElementById('pdf-annotate-screenreader-' + annotationId);
+ if (node) {
+ var list = document.createElement('ol');
+ list.setAttribute(
+ 'id',
+ 'pdf-annotate-screenreader-comment-list-' + annotationId
+ );
+ list.setAttribute('aria-label', 'Comments');
+ node.appendChild(list);
+ // comments.forEach(_insertScreenReaderComment2.default);
+
+ for (var i = 0; i < comments.length; i++) {
+ _insertScreenReaderComment2.default(comments[i]);
+ }
+ }
+ });
+ }
+ module.exports = exports['default'];
+ },
+ /* 26 */
+ function (module, exports) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = insertScreenReaderComment;
+ /**
+ * Insert a comment into the DOM to be available by screen reader
+ *
+ * @param {Object} comment The comment to be inserted
+ */ function insertScreenReaderComment(comment) {
+ if (!comment) {
+ return;
+ }
+ var list = document.querySelector(
+ '#pdf-annotate-screenreader-' + comment.annotation + ' ol'
+ );
+ if (list) {
+ var item = document.createElement('li');
+ item.setAttribute('id', 'pdf-annotate-screenreader-comment-' + comment.uuid);
+ item.appendChild(document.createTextNode('' + comment.content));
+ list.appendChild(item);
+ }
+ }
+ module.exports = exports['default'];
+ },
+ /* 27 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.default = initEventHandlers;
+ var _insertScreenReaderHint = __webpack_require__(21);
+ var _insertScreenReaderHint2 = _interopRequireDefault(_insertScreenReaderHint);
+ var _renderScreenReaderHints = __webpack_require__(20);
+ var _renderScreenReaderHints2 = _interopRequireDefault(_renderScreenReaderHints);
+ var _insertScreenReaderComment = __webpack_require__(26);
+ var _insertScreenReaderComment2 = _interopRequireDefault(_insertScreenReaderComment);
+ var _renderScreenReaderComments = __webpack_require__(25);
+ var _renderScreenReaderComments2 = _interopRequireDefault(_renderScreenReaderComments);
+ var _event = __webpack_require__(4);
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ /**
+ * Initialize the event handlers for keeping screen reader hints synced with data
+ */ function initEventHandlers() {
+ (0, _event.addEventListener)(
+ 'annotation:add',
+ function (documentId, pageNumber, annotation) {
+ reorderAnnotationsByType(documentId, pageNumber, annotation.type);
+ }
+ );
+ (0, _event.addEventListener)(
+ 'annotation:edit',
+ function (documentId, annotationId, annotation) {
+ reorderAnnotationsByType(documentId, annotation.page, annotation.type);
+ }
+ );
+ (0, _event.addEventListener)('annotation:delete', removeAnnotation);
+ (0, _event.addEventListener)('comment:add', insertComments);
+ (0, _event.addEventListener)('comment:delete', removeComment);
+ }
+ /**
+ * Reorder the annotation numbers by annotation type
+ *
+ * @param {String} documentId The ID of the document
+ * @param {Number} pageNumber The page number of the annotations
+ * @param {Strig} type The annotation type
+ */ function reorderAnnotationsByType(documentId, pageNumber, type) {
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .getAnnotations(documentId, pageNumber)
+ .then(function (annotations) {
+ return annotations.annotations.filter(function (a) {
+ return a.type === type;
+ });
+ })
+ .then(function (annotations) {
+ annotations.forEach(function (a) {
+ removeAnnotation(documentId, a.uuid);
+ });
+ return annotations;
+ })
+ .then(/*_renderScreenReaderHints2.default*/);
+ }
+ /**
+ * Remove the screen reader hint for an annotation
+ *
+ * @param {String} documentId The ID of the document
+ * @param {String} annotationId The Id of the annotation
+ */ function removeAnnotation(documentId, annotationId) {
+ removeElementById('pdf-annotate-screenreader-' + annotationId);
+ removeElementById('pdf-annotate-screenreader-' + annotationId + '-end');
+ }
+ /**
+ * Insert a screen reader hint for a comment
+ *
+ * @param {String} documentId The ID of the document
+ * @param {String} annotationId The ID of tha assocated annotation
+ * @param {Object} comment The comment to insert a hint for
+ */ function insertComments(documentId, annotationId, comment) {
+ var list = document.querySelector(
+ 'pdf-annotate-screenreader-comment-list-' + annotationId
+ );
+ var promise = void 0;
+ if (!list) {
+ promise = (0, _renderScreenReaderComments2.default)(
+ documentId,
+ annotationId,
+ []
+ ).then(function () {
+ list = document.querySelector(
+ 'pdf-annotate-screenreader-comment-list-' + annotationId
+ );
+ return true;
+ });
+ } else {
+ promise = Promise.resolve(true);
+ }
+ promise.then(function () {
+ (0, _insertScreenReaderComment2.default)(comment);
+ });
+ }
+ /**
+ * Remove a screen reader hint for a comment
+ *
+ * @param {String} documentId The ID of the document
+ * @param {String} commentId The ID of the comment
+ */ function removeComment(documentId, commentId) {
+ removeElementById('pdf-annotate-screenreader-comment-' + commentId);
+ }
+ /**
+ * Remove an element from the DOM by it's ID if it exists
+ *
+ * @param {String} elementID The ID of the element to be removed
+ */ function removeElementById(elementId) {
+ var el = document.getElementById(elementId);
+ if (el) {
+ el.parentNode.removeChild(el);
+ }
+ }
+ module.exports = exports['default'];
+ },
+ /* 28 */ /* Combines the UI functions to export for parent-module 1 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _event = __webpack_require__(4);
+ var _edit = __webpack_require__(29);
+ var _pen = __webpack_require__(30);
+ var _point = __webpack_require__(31);
+ var _rect = __webpack_require__(32);
+ var _text = __webpack_require__(33);
+ var _page = __webpack_require__(34);
+ var _pickAnno = __webpack_require__(37);
+ var _questionsRenderer = __webpack_require__(38);
+ var _shortText = __webpack_require__(39);
+ var _newAnnotations = __webpack_require__(40);
+ var _ajaxloader = __webpack_require__(36);
+ var _commentWrapper = __webpack_require__(35);
+ exports.default = {
+ addEventListener: _event.addEventListener,
+ removeEventListener: _event.removeEventListener,
+ fireEvent: _event.fireEvent,
+ disableEdit: _edit.disableEdit,
+ enableEdit: _edit.enableEdit,
+ disablePen: _pen.disablePen,
+ enablePen: _pen.enablePen,
+ setPen: _pen.setPen,
+ disablePoint: _point.disablePoint,
+ enablePoint: _point.enablePoint,
+ disableRect: _rect.disableRect,
+ enableRect: _rect.enableRect,
+ disableText: _text.disableText,
+ enableText: _text.enableText,
+ setText: _text.setText,
+ createPage: _page.createPage,
+ renderPage: _page.renderPage,
+ showLoader: _ajaxloader.showLoader,
+ hideLoader: _ajaxloader.hideLoader,
+ pickAnnotation: _pickAnno.pickAnnotation,
+ renderQuestions: _questionsRenderer.renderQuestions,
+ renderAllQuestions: _questionsRenderer.renderAllQuestions,
+ shortenTextDynamic: _shortText.shortenTextDynamic,
+ /*mathJaxAndShortenText: _shortText.mathJaxAndShortenText,*/
+ loadNewAnnotations: _newAnnotations.load,
+ loadEditor: _commentWrapper.loadEditor,
+ };
+ module.exports = exports['default'];
+ },
+ /* 29 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _slicedToArray = (function () {
+ function sliceIterator(arr, i) {
+ var _arr = [];
+ var _n = true;
+ var _d = false;
+ var _e = undefined;
+ try {
+ for (
+ var _i = arr[Symbol.iterator](), _s;
+ !(_n = (_s = _i.next()).done);
+ _n = true
+ ) {
+ _arr.push(_s.value);
+ if (i && _arr.length === i) break;
+ }
+ } catch (err) {
+ _d = true;
+ _e = err;
+ } finally {
+ try {
+ if (!_n && _i['return']) _i['return']();
+ } finally {
+ if (_d) throw _e;
+ }
+ }
+ return _arr;
+ }
+ return function (arr, i) {
+ if (Array.isArray(arr)) {
+ return arr;
+ } else if (Symbol.iterator in Object(arr)) {
+ return sliceIterator(arr, i);
+ } else {
+ throw new TypeError('Invalid attempt to destructure non-iterable instance');
+ }
+ };
+ })();
+ exports.enableEdit = enableEdit;
+ exports.disableEdit = disableEdit;
+ exports.createEditOverlay = createEditOverlay;
+ exports.destroyEditOverlay = destroyEditOverlay;
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _appendChild = __webpack_require__(11);
+ var _appendChild2 = _interopRequireDefault(_appendChild);
+ var _event = __webpack_require__(4);
+ var _utils = __webpack_require__(6);
+ var _ajaxloader = __webpack_require__(36);
+ var _renderPoint = __webpack_require__(17);
+ var _questionsRenderer = __webpack_require__(38);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ function _toConsumableArray(arr) {
+ if (Array.isArray(arr)) {
+ for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
+ arr2[i] = arr[i];
+ }
+ return arr2;
+ } else {
+ return Array.from(arr);
+ }
+ }
+ var _enabled = false;
+ var isDragging = false,
+ overlay = void 0,
+ overlayOld = void 0,
+ annoId = 0,
+ isMoved = true;
+ var dragOffsetX = void 0,
+ dragOffsetY = void 0,
+ dragStartX = void 0,
+ dragStartY = void 0;
+ var OVERLAY_BORDER_SIZE = 3;
+ var SIZE = 20;
+ /**
+ * Create an overlay for editing an annotation.
+ *
+ * @param {Element} target The annotation element to apply overlay for
+ */ function createEditOverlay(target) {
+ destroyEditOverlay();
+ overlay = document.createElement('div');
+ var anchor = document.createElement('a');
+ var node = (0, _utils.findSVGContainer)(target);
+ if (node) {
+ var parentNode = node.parentNode;
+ var id = target.getAttribute('data-pdf-annotate-id');
+ var rect = (0, _utils.getAnnotationRect)(target);
+ var styleLeft = rect.left - OVERLAY_BORDER_SIZE;
+ var styleTop = rect.top - OVERLAY_BORDER_SIZE;
+ overlay.setAttribute('id', 'pdf-annotate-edit-overlay');
+ overlay.setAttribute('data-target-id', id);
+ overlay.style.boxSizing = 'content-box';
+ overlay.style.position = 'absolute';
+ overlay.style.top = styleTop + 'px';
+ overlay.style.left = styleLeft + 'px';
+ overlay.style.width = rect.width + 'px';
+ overlay.style.height = rect.height + 'px';
+ overlay.style.border = OVERLAY_BORDER_SIZE + 'px solid ' + _utils.BORDER_COLOR;
+ overlay.style.borderRadius = OVERLAY_BORDER_SIZE + 'px';
+ overlay.style.zIndex = 22;
+ anchor.innerHTML = 'x';
+ anchor.setAttribute('href', 'javascript://');
+ anchor.style.background = '#fff';
+ anchor.style.borderRadius = '20px';
+ anchor.style.border = '1px solid #bbb';
+ anchor.style.color = '#bbb';
+ anchor.style.fontSize = '12px';
+ anchor.style.padding = '0px 3px 7px';
+ anchor.style.textAlign = 'center';
+ anchor.style.textDecoration = 'none';
+ anchor.style.position = 'absolute';
+ anchor.style.top = '-10px';
+ anchor.style.right = '-10px';
+ anchor.style.width = '11px';
+ anchor.style.height = '11px';
+ anchor.style.boxSizing = 'content-box';
+ overlay.appendChild(anchor);
+ parentNode.appendChild(overlay);
+ document.addEventListener('click', handleDocumentClick);
+ document.addEventListener('keyup', handleDocumentKeyup);
+ document.addEventListener('mousedown', handleDocumentMousedown);
+ anchor.addEventListener('click', deleteAnnotation);
+ anchor.addEventListener('mouseover', function () {
+ anchor.style.color = '#35A4DC';
+ anchor.style.borderColor = '#999';
+ anchor.style.boxShadow = '0 1px 1px #ccc';
+ });
+ anchor.addEventListener('mouseout', function () {
+ anchor.style.color = '#bbb';
+ anchor.style.borderColor = '#bbb';
+ anchor.style.boxShadow = '';
+ });
+ overlay.addEventListener('mouseover', function () {
+ if (!isDragging) {
+ anchor.style.display = '';
+ }
+ });
+ overlay.addEventListener('mouseout', function () {
+ anchor.style.display = 'none';
+ });
+ overlayOld = { x: overlay.style.top, y: overlay.style.left };
+ }
+ }
+ /**
+ * Destroy the edit overlay if it exists.
+ */ function destroyEditOverlay() {
+ if (overlay && overlay.parentNode !== null) {
+ overlay.parentNode.removeChild(overlay);
+ overlay = null;
+ }
+ document.removeEventListener('click', handleDocumentClick);
+ document.removeEventListener('keyup', handleDocumentKeyup);
+ document.removeEventListener('mousedown', handleDocumentMousedown);
+ document.removeEventListener('mousemove', handleDocumentMousemove);
+ document.removeEventListener('mouseup', handleDocumentMouseup);
+ (0, _utils.enableUserSelect)();
+ }
+ /**
+ * Delete currently selected annotation
+ */ function deleteAnnotation() {
+ if (!overlay) {
+ return;
+ }
+ annoId = overlay.getAttribute('data-target-id');
+ if (_capabilities.deleteany) {
+ notification.confirm(
+ M.util.get_string('deletingCommentTitle', 'pdfannotator'),
+ M.util.get_string('deletingAnnotation_manager', 'pdfannotator'),
+ M.util.get_string('yesButton', 'pdfannotator'),
+ M.util.get_string('cancelButton', 'pdfannotator'),
+ deleteAnnotationCallback
+ );
+ } else {
+ notification.confirm(
+ M.util.get_string('deletingCommentTitle', 'pdfannotator'),
+ M.util.get_string('deletingAnnotation_student', 'pdfannotator'),
+ M.util.get_string('yesButton', 'pdfannotator'),
+ M.util.get_string('cancelButton', 'pdfannotator'),
+ deleteAnnotationCallback
+ );
+ }
+ }
+ /**
+ * Is called if the user confirms to delete the annotation.
+ * This function destroys the annotation and deletes it from the database
+ * @returns {undefined}
+ */
+ function deleteAnnotationCallback() {
+ var annotationId;
+ if (!overlay) {
+ annotationId = annoId;
+ } else {
+ annotationId = overlay.getAttribute('data-target-id');
+ }
+ var nodes = document.querySelectorAll(
+ '[data-pdf-annotate-id="' + annotationId + '"]'
+ );
+
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .deleteAnnotation(_documentObject.annotatorid, annotationId)
+ .then(
+ function (data) {
+ if (data.status === 'success') {
+ // destroy blue box (overlay)
+ destroyEditOverlay();
+ // destroy annotation DOM element
+ [].concat(_toConsumableArray(nodes)).forEach(function (n) {
+ n.parentNode.removeChild(n);
+ });
+ // destroy Commentsfield
+ document.querySelector('.comment-list-container').innerHTML = '';
+ document
+ .querySelector('.comment-list-form')
+ .setAttribute('style', 'display:none');
+ var visiblePageNum = document.getElementById('currentPage').value;
+ _questionsRenderer.renderQuestions(
+ _documentObject.annotatorid,
+ visiblePageNum
+ );
+ } else {
+ }
+ },
+ function (err) {
+ notification.addNotification({
+ message: M.util.get_string(
+ 'error:deleteAnnotation',
+ 'pdfannotator'
+ ),
+ type: 'error',
+ });
+ console.error(
+ M.util.get_string('error:deleteAnnotation', 'pdfannotator')
+ );
+ }
+ );
+ }
+
+ /**
+ * Handle document.click event
+ *
+ * @param {Event} e The DOM event that needs to be handled
+ */ function handleDocumentClick(e) {
+ //if the click is on an input field or link or icon in editor toolbar ('I') nothing should happen.
+ if (
+ e.target.tagName === 'INPUT' ||
+ e.target.tagName === 'TEXTAREA' ||
+ e.target.tagName === 'BUTTON' ||
+ e.target.tagName === 'I'
+ ) {
+ return;
+ }
+ //if the click is on the Commentlist nothing should happen.
+ if (
+ (typeof e.target.getAttribute('id') != 'string' &&
+ e.target.id.indexOf('comment') !== -1) ||
+ e.target.className.indexOf('comment') !== -1 ||
+ e.target.parentNode.className.indexOf('comment') !== -1 ||
+ e.target.parentNode.className.indexOf('chat') !== -1
+ ) {
+ return;
+ }
+ if (!(0, _utils.findSVGAtPoint)(e.clientX, e.clientY)) {
+ return;
+ } // Remove current overlay
+ var overlay = document.getElementById('pdf-annotate-edit-overlay');
+ if (overlay) {
+ if (isDragging || e.target === overlay) {
+ return;
+ }
+ destroyEditOverlay();
+ }
+ isMoved = false;
+ }
+ /**
+ * Handle document.keyup event
+ *
+ * @param {Event} e The DOM event that needs to be handled
+ */ function handleDocumentKeyup(e) {
+ if (
+ overlay &&
+ e.keyCode === 46 &&
+ !e.target.closest('.edit-comment-form') &&
+ !e.target.closest('.comment-list-form')
+ ) {
+ deleteAnnotation();
+ }
+ }
+ /**
+ * Handle document.mousedown event
+ *
+ * @param {Event} e The DOM event that needs to be handled
+ */ function handleDocumentMousedown(e) {
+ if (e.target !== overlay) {
+ return;
+ } // Highlight and strikeout annotations are bound to text within the document.
+ // It doesn't make sense to allow repositioning these types of annotations.
+ var annotationId = overlay.getAttribute('data-target-id');
+ var target = document.querySelector(
+ '[data-pdf-annotate-id="' + annotationId + '"]'
+ );
+ var type = target.getAttribute('data-pdf-annotate-type');
+ if (type === 'highlight' || type === 'strikeout') {
+ return;
+ }
+ isDragging = true;
+ dragOffsetX = e.clientX;
+ dragOffsetY = e.clientY;
+ dragStartX = overlay.offsetLeft;
+ dragStartY = overlay.offsetTop;
+ overlay.style.background = 'rgba(255, 255, 255, 0.7)';
+ overlay.style.setProperty('cursor', 'move', 'important');
+ overlay.querySelector('a').style.display = 'none';
+ document.addEventListener('mousemove', handleDocumentMousemove);
+ document.addEventListener('mouseup', handleDocumentMouseup);
+ (0, _utils.disableUserSelect)();
+ }
+ /**
+ * Handle document.mousemove event
+ *
+ *
+ * @param {Event} e The DOM event that needs to be handled
+ */ function handleDocumentMousemove(e) {
+ var annotationId = overlay.getAttribute('data-target-id');
+ var parentNode = overlay.parentNode;
+ var rect = parentNode.getBoundingClientRect();
+ var y = dragStartY + (e.clientY - dragOffsetY);
+ var x = dragStartX + (e.clientX - dragOffsetX);
+ var minY = 0;
+ var maxY = rect.height;
+ var minX = 0;
+ var maxX = rect.width;
+ if (y > minY && y + overlay.offsetHeight < maxY) {
+ overlay.style.top = y + 'px';
+ }
+ if (x > minX && x + overlay.offsetWidth < maxX) {
+ overlay.style.left = x + 'px';
+ }
+ isMoved = true;
+ }
+ /**
+ * Handle document.mouseup event
+ * This function is responsible for shifting areas, pins, textboxes and drawings
+ *
+ * @param {Event} e The DOM event that needs to be handled
+ */ function handleDocumentMouseup(e) {
+ var annotationId = overlay.getAttribute('data-target-id');
+ var target = document.querySelectorAll(
+ '[data-pdf-annotate-id="' + annotationId + '"]'
+ );
+ var type = target[0].getAttribute('data-pdf-annotate-type');
+ var svg = overlay.parentNode.querySelector('svg.annotationLayer');
+ var _getMetadata2 = (0, _utils.getMetadata)(svg);
+ var documentId = _getMetadata2.documentId;
+ var pageNumber = _getMetadata2.pageNumber;
+ var isFirefox = /firefox/i.test(navigator.userAgent);
+
+ overlay.querySelector('a').style.display = '';
+ function getDelta(propX, propY) {
+ return calcDelta(
+ parseInt(target[0].getAttribute(propX), 10),
+ parseInt(target[0].getAttribute(propY), 10)
+ );
+ }
+ function calcDelta(x, y) {
+ return {
+ deltaX:
+ OVERLAY_BORDER_SIZE +
+ (0, _utils.scaleDown)(svg, { x: overlay.offsetLeft }).x -
+ x,
+ deltaY:
+ OVERLAY_BORDER_SIZE +
+ (0, _utils.scaleDown)(svg, { y: overlay.offsetTop }).y -
+ y,
+ };
+ }
+ (0, _ajaxloader.showLoader)();
+ var oldX = 0;
+ var oldY = 0;
+ var viewY = dragStartY;
+ var viewX = dragStartX;
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .getAnnotation(documentId, annotationId)
+ .then(
+ function (annotation) {
+ oldX = annotation['annotation'].x;
+ oldY = annotation['annotation'].y;
+ (0, _ajaxloader.showLoader)();
+ if (['area', 'point', 'textbox'].indexOf(type) > -1) {
+ (function () {
+ var _getDelta = getDelta('x', 'y');
+ var deltaX = _getDelta.deltaX;
+ var deltaY = _getDelta.deltaY;
+ [].concat(_toConsumableArray(target)).forEach(function (t, i) {
+ // adjust y coordinate if necessary
+ if (deltaY !== 0) {
+ var modelY = parseInt(t.getAttribute('y'), 10) + deltaY;
+ viewY = modelY;
+ if (type === 'point') {
+ //+SIZE, because the pin should not be rendered right under the click point, instead it should be rendered centered above the click point
+ modelY += SIZE;
+ }
+ if (type === 'textbox') {
+ viewY += parseInt(
+ annotation['annotation'].size,
+ 10
+ );
+ }
+ if (type === 'point' && !isFirefox) {
+ viewY = (0, _utils.scaleUp)(svg, {
+ viewY: viewY,
+ }).viewY;
+ }
+ if (isFirefox) {
+ viewY -= 6;
+ }
+ if (annotation.rectangles) {
+ annotation.rectangles[i].y = modelY;
+ } else {
+ annotation['annotation'].y = modelY; // .toString();
+ }
+ }
+ // adjust x coordinate if necessary
+ if (deltaX !== 0) {
+ var modelX = parseInt(t.getAttribute('x'), 10) + deltaX;
+ viewX = modelX;
+ //+(1/4)Size, because the pin should be rendered centered of the click point not on the righthand side.
+ if (type === 'point') {
+ modelX += SIZE / 4;
+ }
+ if (type === 'point' && !isFirefox) {
+ viewX = (0, _utils.scaleUp)(svg, {
+ viewX: viewX,
+ }).viewX;
+ }
+ if (isFirefox) {
+ viewX -= 6;
+ }
+ //t.setAttribute('x',viewX);
+ if (annotation.rectangles) {
+ annotation.rectangles[i].x = modelX;
+ } else {
+ annotation['annotation'].x = modelX; // .toString();
+ }
+ }
+ });
+ })();
+ } else if (type === 'drawing') {
+ (function () {
+ var rect = (0, _utils.scaleDown)(
+ svg,
+ (0, _utils.getAnnotationRect)(target[0])
+ );
+
+ var _annotation$lines$ = _slicedToArray(
+ annotation['annotation'].lines[0],
+ 2
+ );
+
+ var originX = _annotation$lines$[0];
+ var originY = _annotation$lines$[1];
+
+ var _calcDelta = calcDelta(originX, originY);
+
+ var deltaX = _calcDelta.deltaX;
+
+ var deltaY = _calcDelta.deltaY; // origin isn't necessarily at 0/0 in relation to overlay x/y
+ // adjust the difference between overlay and drawing coords
+
+ deltaY += originY - rect.top;
+ deltaX += originX - rect.left;
+
+ annotation['annotation'].lines.forEach(function (line, i) {
+ var _annotation$lines$i = _slicedToArray(
+ annotation['annotation'].lines[i],
+ 2
+ );
+ var x = _annotation$lines$i[0];
+ var y = _annotation$lines$i[1];
+ annotation['annotation'].lines[i][0] = (0,
+ _utils.roundDigits)(x + deltaX, 4);
+ annotation['annotation'].lines[i][1] = (0,
+ _utils.roundDigits)(y + deltaY, 4);
+ });
+ })();
+ }
+ (function editAnnotation() {
+ if (!overlay) {
+ return;
+ }
+ if (dragStartX === viewX && dragStartY === viewY) {
+ return;
+ }
+ annoId = overlay.getAttribute('data-target-id');
+ notification.confirm(
+ M.util.get_string('editAnnotationTitle', 'pdfannotator'),
+ M.util.get_string('editAnnotation', 'pdfannotator'),
+ M.util.get_string('yesButton', 'pdfannotator'),
+ M.util.get_string('cancelButton', 'pdfannotator'),
+ editAnnotationCallback,
+ overlayToOldPlace
+ );
+ })();
+
+ function overlayToOldPlace() {
+ // Overlay back to old place.
+ overlay.style.top = overlayOld.x;
+ overlay.style.left = overlayOld.y;
+ // Show comments.
+ _event.fireEvent('annotation:click', target[0]);
+ }
+ /**
+ * Is called if the user confirms to move the annotation.
+ * This function destroys the annotation and deletes it from the database
+ * @returns {undefined}
+ */
+ function editAnnotationCallback() {
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .editAnnotation(
+ documentId,
+ pageNumber,
+ annotationId,
+ annotation
+ )
+ .then(
+ function (success) {
+ (0, _ajaxloader.hideLoader)();
+ if (!success) {
+ overlayToOldPlace();
+
+ // Notification, that the annotation could not be edited.
+ notification.addNotification({
+ message: M.util.get_string(
+ 'editNotAllowed',
+ 'pdfannotator'
+ ),
+ type: 'error',
+ });
+ setTimeout(function () {
+ let notificationpanel =
+ document.getElementById(
+ 'user-notifications'
+ );
+ while (notificationpanel.hasChildNodes()) {
+ notificationpanel.removeChild(
+ notificationpanel.firstChild
+ );
+ }
+ }, 4000);
+ } else {
+ if (
+ ['area', 'point', 'textbox'].indexOf(type) > -1
+ ) {
+ (function () {
+ []
+ .concat(_toConsumableArray(target))
+ .forEach(function (t, i) {
+ t.setAttribute('y', viewY);
+ t.setAttribute('x', viewX);
+ });
+ })();
+ } else if (type === 'drawing') {
+ target[0].parentNode.removeChild(target[0]);
+ (0, _appendChild2.default)(
+ svg,
+ annotation['annotation']
+ );
+ }
+ //_renderPoint(annotation['annotation']);
+ _event.fireEvent('annotation:click', target[0]);
+ }
+ },
+ function (err) {
+ overlayToOldPlace();
+
+ notification.addNotification({
+ message: M.util.get_string(
+ 'error:editAnnotation',
+ 'pdfannotator'
+ ),
+ type: 'error',
+ });
+ }
+ );
+ }
+ },
+ function (err) {
+ notification.addNotification({
+ message: M.util.get_string('error:getAnnotation', 'pdfannotator'),
+ type: 'error',
+ });
+ }
+ );
+ // getComments(_fileid, annotationId);
+ setTimeout(function () {
+ isDragging = false;
+ }, 0);
+ overlay.style.background = '';
+ overlay.style.cursor = '';
+ document.removeEventListener('mousemove', handleDocumentMousemove);
+ document.removeEventListener('mouseup', handleDocumentMouseup);
+ (0, _utils.enableUserSelect)();
+ }
+
+ /**
+ * Handle annotation.click event
+ *
+ * @param {Element} e The annotation element that was clicked
+ */ function handleAnnotationClick(target) {
+ if (isDragging) {
+ return;
+ }
+ createEditOverlay(target);
+ }
+ /**
+ * Enable edit mode behavior.
+ */ function enableEdit() {
+ if (_enabled) {
+ return;
+ }
+ _enabled = true;
+ document.getElementById('content-wrapper').classList.add('cursor-edit');
+ (0, _event.addEventListener)('annotation:click', handleAnnotationClick);
+ }
+ /**
+ * Disable edit mode behavior.
+ */ function disableEdit() {
+ destroyEditOverlay();
+ if (!_enabled) {
+ return;
+ }
+ _enabled = false;
+ document.getElementById('content-wrapper').classList.remove('cursor-edit');
+ (0, _event.removeEventListener)('annotation:click', handleAnnotationClick);
+ }
+ },
+ /* 30 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.setPen = setPen;
+ exports.enablePen = enablePen;
+ exports.disablePen = disablePen;
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _appendChild = __webpack_require__(11);
+ var _appendChild2 = _interopRequireDefault(_appendChild);
+ var _utils = __webpack_require__(6);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ var _enabled = false;
+ var _penSize = void 0;
+ var _penColor = void 0;
+ var path = void 0;
+ var lines = void 0;
+ var _svg = void 0;
+ /**
+ * Handle document.mousedown event
+ */ function handleDocumentMousedown() {
+ path = null;
+ lines = [];
+ document.addEventListener('mousemove', handleDocumentMousemove);
+ document.addEventListener('mouseup', handleDocumentMouseup);
+ }
+ /**
+ * Handle document.mouseup event
+ *
+ * @param {Event} e The DOM event to be handled
+ */ function handleDocumentMouseup(e) {
+ var svg = void 0;
+ if (lines.length > 1 && (svg = (0, _utils.findSVGAtPoint)(e.clientX, e.clientY))) {
+ var _getMetadata = (0, _utils.getMetadata)(svg);
+ var documentId = _getMetadata.documentId;
+ var pageNumber = _getMetadata.pageNumber;
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .addAnnotation(documentId, pageNumber, {
+ type: 'drawing',
+ width: _penSize,
+ color: _penColor,
+ lines: lines,
+ })
+ .then(
+ function (annotation) {
+ if (path) {
+ svg.removeChild(path);
+ }
+ (0, _appendChild2.default)(svg, annotation);
+ },
+ function (err) {
+ // Remove path
+ if (path) {
+ svg.removeChild(path);
+ }
+ notification.addNotification({
+ message: M.util.get_string(
+ 'error:addAnnotation',
+ 'pdfannotator'
+ ),
+ type: 'error',
+ });
+ }
+ );
+ }
+ document.removeEventListener('mousemove', handleDocumentMousemove);
+ document.removeEventListener('mouseup', handleDocumentMouseup);
+ }
+ /**
+ * Handle document.mousemove event
+ *
+ * @param {Event} e The DOM event to be handled
+ */ function handleDocumentMousemove(e) {
+ savePoint(e.clientX, e.clientY);
+ }
+ /**
+ * Handle document.keyup event
+ *
+ * @param {Event} e The DOM event to be handled
+ */ function handleDocumentKeyup(e) {
+ // Cancel rect if Esc is pressed
+ if (e.keyCode === 27) {
+ lines = null;
+ path.parentNode.removeChild(path);
+ document.removeEventListener('mousemove', handleDocumentMousemove);
+ document.removeEventListener('mouseup', handleDocumentMouseup);
+ }
+ }
+ /**
+ * Save a point to the line being drawn.
+ *
+ * @param {Number} x The x coordinate of the point
+ * @param {Number} y The y coordinate of the point
+ */
+ function savePoint(x, y) {
+ var svg = (0, _utils.findSVGAtPoint)(x, y);
+ if (!svg) {
+ return;
+ }
+ var rect = svg.getBoundingClientRect();
+ var point = (0, _utils.scaleDown)(svg, {
+ x: (0, _utils.roundDigits)(x - rect.left, 4),
+ y: (0, _utils.roundDigits)(y - rect.top, 4),
+ });
+ lines.push([point.x, point.y]);
+ if (lines.length <= 1) {
+ return;
+ }
+ if (path) {
+ svg.removeChild(path);
+ }
+ path = (0, _appendChild2.default)(svg, {
+ type: 'drawing',
+ color: _penColor,
+ width: _penSize,
+ lines: lines,
+ });
+ }
+ function handleContentTouchstart(e) {
+ path = null;
+ lines = [];
+ _svg = (0, _utils.findSVGAtPoint)(e.touches[0].clientX, e.touches[0].clientY);
+ saveTouchPoint(e.touches[0].clientX, e.touches[0].clientY);
+ }
+ function handleContentTouchmove(e) {
+ e.preventDefault();
+ saveTouchPoint(e.touches[0].clientX, e.touches[0].clientY);
+ }
+ function handleContentTouchend(e) {
+ if (lines.length > 1) {
+ var _getMetadata = (0, _utils.getMetadata)(_svg);
+ var documentId = _getMetadata.documentId;
+ var pageNumber = _getMetadata.pageNumber;
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .addAnnotation(documentId, pageNumber, {
+ type: 'drawing',
+ width: _penSize,
+ color: _penColor,
+ lines: lines,
+ })
+ .then(
+ function (annotation) {
+ if (path) {
+ _svg.removeChild(path);
+ }
+ (0, _appendChild2.default)(_svg, annotation);
+ },
+ function (err) {
+ // Remove path
+ if (path) {
+ _svg.removeChild(path);
+ }
+ notification.addNotification({
+ message: M.util.get_string(
+ 'error:addAnnotation',
+ 'pdfannotator'
+ ),
+ type: 'error',
+ });
+ }
+ );
+ }
+ }
+ function handleContentTouchcancel(e) {
+ lines = null;
+ path.parentNode.removeChild(path);
+ }
+
+ /* Save a touchpoint to the line being drawn.
+ *
+ * @param {Number} x The x coordinate of the point
+ * @param {Number} y The y coordinate of the point
+ */ function saveTouchPoint(x, y) {
+ if (!_svg) {
+ return;
+ }
+ var rect = _svg.getBoundingClientRect();
+ var point = (0, _utils.scaleDown)(_svg, {
+ x: (0, _utils.roundDigits)(x - rect.left, 4),
+ y: (0, _utils.roundDigits)(y - rect.top, 4),
+ });
+ lines.push([point.x, point.y]);
+ if (lines.length <= 1) {
+ return;
+ }
+ if (path) {
+ _svg.removeChild(path);
+ }
+ path = (0, _appendChild2.default)(_svg, {
+ type: 'drawing',
+ color: _penColor,
+ width: _penSize,
+ lines: lines,
+ });
+ }
+
+ /**
+ * Set the attributes of the pen.
+ *
+ * @param {Number} penSize The size of the lines drawn by the pen
+ * @param {String} penColor The color of the lines drawn by the pen
+ */ function setPen() {
+ var penSize =
+ arguments.length <= 0 || arguments[0] === undefined ? 1 : arguments[0];
+ var penColor =
+ arguments.length <= 1 || arguments[1] === undefined ? '000000' : arguments[1];
+ _penSize = parseInt(penSize, 10);
+ _penColor = penColor;
+ }
+ /**
+ * Enable the pen behavior
+ */ function enablePen() {
+ if (_enabled) {
+ return;
+ }
+ _enabled = true;
+ var contentWrapper = document.getElementById('content-wrapper');
+ contentWrapper.classList.add('cursor-pen');
+ document.addEventListener('mousedown', handleDocumentMousedown);
+ document.addEventListener('keyup', handleDocumentKeyup);
+ contentWrapper.addEventListener('touchstart', handleContentTouchstart);
+ contentWrapper.addEventListener('touchmove', handleContentTouchmove);
+ contentWrapper.addEventListener('touchend', handleContentTouchend);
+ contentWrapper.addEventListener('touchcancel', handleContentTouchcancel);
+ (0, _utils.disableUserSelect)();
+ }
+ /**
+ * Disable the pen behavior
+ */ function disablePen() {
+ if (!_enabled) {
+ return;
+ }
+ _enabled = false;
+ var contentWrapper = document.getElementById('content-wrapper');
+ contentWrapper.classList.remove('cursor-pen');
+ document.removeEventListener('mousedown', handleDocumentMousedown);
+ document.removeEventListener('keyup', handleDocumentKeyup);
+ contentWrapper.removeEventListener('touchstart', handleContentTouchstart);
+ contentWrapper.removeEventListener('touchmove', handleContentTouchmove);
+ contentWrapper.removeEventListener('touchend', handleContentTouchend);
+ contentWrapper.removeEventListener('touchcancel', handleContentTouchcancel);
+ (0, _utils.enableUserSelect)();
+ }
+ },
+ /* 31 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _typeof =
+ typeof Symbol === 'function' && _typeof2(Symbol.iterator) === 'symbol'
+ ? function (obj) {
+ return typeof obj === 'undefined' ? 'undefined' : _typeof2(obj);
+ }
+ : function (obj) {
+ return obj && typeof Symbol === 'function' && obj.constructor === Symbol
+ ? 'symbol'
+ : typeof obj === 'undefined'
+ ? 'undefined'
+ : _typeof2(obj);
+ };
+ exports.enablePoint = enablePoint;
+ exports.disablePoint = disablePoint;
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _appendChild = __webpack_require__(11);
+ var _appendChild2 = _interopRequireDefault(_appendChild);
+ var _utils = __webpack_require__(6);
+ var _commentWrapper = __webpack_require__(35);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ var _enabled = false;
+ var data = void 0;
+ var _svg = void 0;
+ var _rect = void 0;
+ var dragging = false;
+ //Test
+ var textarea = void 0;
+ var submitbutton = void 0;
+ var form = void 0;
+ var annotationObj;
+ var documentId = -1;
+ var pageNumber = 1;
+
+ /**
+ * Handle document.mouseup event
+ *
+ * @param {Event} The DOM event to be handled
+ */ function handleDocumentMouseup(e) {
+ //if the click is in comment wrapper area nothing should happen.
+ var commentWrapperNodes = document.querySelectorAll('div#comment-wrapper')[0];
+ var clickedElement;
+ if (e.target.id) {
+ clickedElement = '#' + e.target.id;
+ } else if (e.target.className[0]) {
+ clickedElement = '.' + e.target.className;
+ } else {
+ clickedElement = '';
+ }
+ if (clickedElement && commentWrapperNodes.querySelector(clickedElement)) {
+ return;
+ }
+
+ //If Modal Dialogue beeing clicked.
+ var clickedMoodleDialogue = e.target.closest('.moodle-dialogue-base');
+ if (clickedMoodleDialogue) {
+ return;
+ }
+
+ //if the click is on the Commentlist nothing should happen.
+ if (
+ (typeof e.target.getAttribute('id') == 'string' &&
+ e.target.id.indexOf('comment') !== -1) ||
+ e.target.className.indexOf('comment') !== -1 ||
+ e.target.parentNode.className.indexOf('comment') !== -1 ||
+ e.target.parentNode.className.indexOf('chat') !== -1 ||
+ e.target.tagName == 'INPUT' ||
+ e.target.tagName == 'LABEL'
+ ) {
+ return;
+ }
+ _svg = (0, _utils.findSVGAtPoint)(e.clientX, e.clientY);
+ if (!_svg) {
+ return;
+ }
+ var _getMetadata = (0, _utils.getMetadata)(_svg);
+ documentId = _getMetadata.documentId;
+ pageNumber = _getMetadata.pageNumber;
+ deleteUndefinedPin();
+ var fn = () => {
+ [textarea, data] = (0, _commentWrapper.openComment)(
+ e,
+ handleCancelClick,
+ handleSubmitClick,
+ handleToolbarClick,
+ handleSubmitBlur,
+ 'pin'
+ );
+ renderPin();
+ };
+ _commentWrapper.loadEditor('add', 0, fn);
+ }
+
+ // Reset dragging to false.
+ function handleContentTouchstart(e) {
+ dragging = false;
+ }
+ // Set dragging to true, so we stop the handleContentTouchend function from running.
+ function handleContentTouchmove(e) {
+ dragging = true;
+ }
+ /**
+ * Handle content.touchend event
+ *
+ * @param {Event} The DOM event to be handled
+ */ function handleContentTouchend(e) {
+ // If the mobile user was scrolling return from this function.
+ if (dragging) {
+ return;
+ }
+ //if the click is on the Commentlist nothing should happen.
+ if (
+ (typeof e.target.getAttribute('id') == 'string' &&
+ e.target.id.indexOf('comment') !== -1) ||
+ e.target.className.indexOf('comment') !== -1 ||
+ e.target.parentNode.className.indexOf('comment') !== -1 ||
+ e.target.parentNode.className.indexOf('chat') !== -1 ||
+ e.target.tagName == 'INPUT' ||
+ e.target.tagName == 'LABEL'
+ ) {
+ return;
+ }
+ let svg = (0, _utils.findSVGAtPoint)(
+ e.changedTouches[0].clientX,
+ e.changedTouches[0].clientY
+ );
+ if (!svg) {
+ return;
+ }
+ var _getMetadata = (0, _utils.getMetadata)(svg);
+ documentId = _getMetadata.documentId;
+ pageNumber = _getMetadata.pageNumber;
+ deleteUndefinedPin();
+ var coordinates = {
+ x: e.changedTouches[0].clientX,
+ y: e.changedTouches[0].clientY,
+ };
+ renderPinTouchscreen(coordinates);
+ [textarea, data] = (0, _commentWrapper.openCommentTouchscreen)(
+ e,
+ handleCancelClick,
+ handleSubmitClick,
+ handleToolbarClick,
+ handleSubmitBlur,
+ 'pin'
+ );
+ }
+
+ /**
+ * If the toolbar is clicked, the point tool should be disabled and the commentswrapper should be closed
+ * @param {type} e
+ * @returns {undefined}
+ */
+ function handleToolbarClick(e) {
+ disablePoint();
+ document.querySelector('.toolbar').removeEventListener('click', handleToolbarClick);
+
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ false
+ );
+ deleteUndefinedPin();
+ textarea = void 0;
+ }
+
+ function handleSubmitClick(e) {
+ savePoint(_svg);
+ return false;
+ }
+ function handleCancelClick(e) {
+ textarea = void 0;
+ //delete the temporay rendered Pin
+ deleteUndefinedPin();
+ enablePoint();
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ false
+ );
+ }
+ function handleSubmitBlur() {
+ disablePoint();
+ textarea = void 0;
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ false
+ );
+ }
+ /**
+ * Handle input.blur event
+ */ function handleInputBlur() {
+ /*disablePoint();*/ savePoint();
+ }
+ /**
+ * Handle input.keyup event
+ *
+ * @param {Event} e The DOM event to handle
+ */ function handleInputKeyup(e) {
+ if (e.keyCode === 27) {
+ disablePoint();
+ closeInput();
+ } else if (e.keyCode === 13) {
+ /*disablePoint();*/ savePoint();
+ }
+ }
+
+ function renderPin() {
+ var clientX = (0, _utils.roundDigits)(data.x, 4);
+ var clientY = (0, _utils.roundDigits)(data.y, 4);
+ var content = textarea.value.trim();
+ var svg = (0, _utils.findSVGAtPoint)(clientX, clientY);
+ if (!svg) {
+ return { v: void 0 };
+ }
+ _rect = svg.getBoundingClientRect();
+ var annotation = initializeAnnotation(_rect, svg);
+ annotationObj = annotation;
+ annotation.color = true;
+ (0, _appendChild2.default)(svg, annotation);
+ }
+ function renderPinTouchscreen(coordinates) {
+ var clientX = (0, _utils.roundDigits)(coordinates.x, 4);
+ var clientY = (0, _utils.roundDigits)(coordinates.y, 4);
+ var svg = (0, _utils.findSVGAtPoint)(clientX, clientY);
+ if (!svg) {
+ return { v: void 0 };
+ }
+ _rect = svg.getBoundingClientRect();
+ var annotation = initializeAnnotationTouchscreen(_rect, svg, coordinates);
+ annotationObj = annotation;
+ annotation.color = true;
+ (0, _appendChild2.default)(svg, annotation);
+ }
+
+ /**
+ * This function deletes all annotations which data-pdf-annotate-id is undefined. An annotation is undefined, if it is only temporarily displayed.
+ * @returns {undefined}
+ */
+ function deleteUndefinedPin() {
+ let n = document.querySelector('[data-pdf-annotate-id="undefined"]');
+ if (n) {
+ n.parentNode.removeChild(n);
+ }
+ }
+
+ function initializeAnnotation(rect, svg) {
+ var clientX = (0, _utils.roundDigits)(data.x, 4);
+ var clientY = (0, _utils.roundDigits)(data.y, 4);
+ return Object.assign(
+ { type: 'point' },
+ (0, _utils.scaleDown)(svg, {
+ x: clientX - (0, _utils.roundDigits)(rect.left, 4),
+ y: clientY - (0, _utils.roundDigits)(rect.top, 4),
+ })
+ );
+ }
+ function initializeAnnotationTouchscreen(rect, svg, coordinates) {
+ var clientX = (0, _utils.roundDigits)(coordinates.x, 4);
+ var clientY = (0, _utils.roundDigits)(coordinates.y, 4);
+ return Object.assign(
+ { type: 'point' },
+ (0, _utils.scaleDown)(svg, {
+ x: clientX - (0, _utils.roundDigits)(rect.left, 4),
+ y: clientY - (0, _utils.roundDigits)(rect.top, 4),
+ })
+ );
+ }
+ /**
+ * Save a new point annotation from input
+ */
+ function savePoint(svg = null) {
+ if (textarea.value.trim().length > 0) {
+ disablePoint();
+ var page = pageNumber;
+ if (!svg) {
+ var elements = document.querySelectorAll(
+ 'svg[data-pdf-annotate-container="true"]'
+ );
+ var svg = elements[page - 1];
+ }
+ var _ret = (function () {
+ var clientX = (0, _utils.roundDigits)(data.x, 4);
+ var clientY = (0, _utils.roundDigits)(data.y, 4);
+ var content = textarea.value.trim();
+ if (!svg) {
+ return { v: void 0 };
+ }
+ var rect = svg.getBoundingClientRect();
+
+ var _getMetadata = (0, _utils.getMetadata)(svg);
+ var documentId = _getMetadata.documentId;
+ var pageNumber = page;
+ var annotation = Object.assign(
+ { type: 'point' },
+ (0, _utils.scaleDown)(svg, {
+ x: clientX - (0, _utils.roundDigits)(_rect.left, 4),
+ y: clientY - (0, _utils.roundDigits)(_rect.top, 4),
+ })
+ );
+ var commentVisibility = read_visibility_of_checkbox();
+ var isquestion = 1; //The Point was created so the comment is a question
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .addAnnotation(documentId, pageNumber, annotation)
+ .then(
+ function (annotation) {
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .addComment(
+ documentId,
+ annotation.uuid,
+ content,
+ commentVisibility,
+ isquestion
+ )
+ .then(function (msg) {
+ if (!msg) {
+ throw new Error();
+ }
+ deleteUndefinedPin();
+ //get old y-koordniate, because of scrolling
+ annotation.y = annotationObj.y;
+ (0, _appendChild2.default)(svg, annotation);
+ document
+ .querySelector('.toolbar')
+ .removeEventListener('click', handleToolbarClick);
+ document.querySelector('button.cursor').click();
+ (0,
+ _commentWrapper.showCommentsAfterCreation)(annotation.uuid);
+ })
+ .catch(function (err) {
+ /*if there is an error in addComment, the annotation will be deleted!*/
+ var annotationid = annotation.uuid;
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .deleteAnnotation(documentId, annotationid, false);
+ });
+ },
+ function (err) {
+ deleteUndefinedPin();
+ notification.addNotification({
+ message: M.util.get_string(
+ 'error:addAnnotation',
+ 'pdfannotator'
+ ),
+ type: 'error',
+ });
+ }
+ );
+ })();
+ if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === 'object') {
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ true
+ );
+ return _ret.v;
+ }
+ textarea = void 0;
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ true
+ );
+ } else {
+ notification.addNotification({
+ message: M.util.get_string('min0Chars', 'pdfannotator'),
+ type: 'error',
+ });
+ textarea.focus();
+ }
+ }
+ function closeInput() {
+ data.removeEventListener('blur', handleInputBlur);
+ data.removeEventListener('keyup', handleInputKeyup);
+ document.body.removeChild(data);
+ data = null;
+ }
+ /**
+ * Enable point annotation behavior
+ */ function enablePoint() {
+ if (_enabled) {
+ return;
+ }
+ _enabled = true;
+ document.getElementById('content-wrapper').classList.add('cursor-point');
+ document.addEventListener('mouseup', handleDocumentMouseup);
+ document.addEventListener('touchstart', handleContentTouchstart);
+ document.addEventListener('touchmove', handleContentTouchmove);
+ document.addEventListener('touchend', handleContentTouchend);
+ }
+ /**
+ * Disable point annotation behavior
+ */ function disablePoint() {
+ _enabled = false;
+ document.getElementById('content-wrapper').classList.remove('cursor-point');
+ document.removeEventListener('mouseup', handleDocumentMouseup);
+ document.removeEventListener('touchstart', handleContentTouchstart);
+ document.removeEventListener('touchmove', handleContentTouchmove);
+ document.removeEventListener('touchend', handleContentTouchend);
+ }
+ },
+ /* 32 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.enableRect = enableRect;
+ exports.disableRect = disableRect;
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _appendChild = __webpack_require__(11);
+ var _appendChild2 = _interopRequireDefault(_appendChild);
+ var _setAttributes = __webpack_require__(14);
+ var _setAttributes2 = _interopRequireDefault(_setAttributes);
+ var _utils = __webpack_require__(6);
+ var _event = __webpack_require__(4);
+
+ var _commentWrapper = __webpack_require__(35);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ function _toConsumableArray(arr) {
+ if (Array.isArray(arr)) {
+ for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
+ arr2[i] = arr[i];
+ }
+ return arr2;
+ } else {
+ return Array.from(arr);
+ }
+ }
+ var _enabled = false;
+ var _type = void 0;
+ var overlay = void 0;
+ var originY = void 0;
+ var originX = void 0;
+ var documentId = -1;
+ var pageNumber = 1;
+
+ var textarea = void 0;
+ var submitbutton = void 0;
+ var resetbutton = void 0;
+ var form = void 0;
+ var data = void 0;
+ var rectsSelection = void 0;
+ var rectObj;
+ var _svg = void 0;
+ var rect = void 0;
+
+ /**
+ * Get the current window selection as rects
+ *
+ * @return {Array} An Array of rects
+ */
+ function getSelectionRects() {
+ try {
+ var selection = window.getSelection();
+ try {
+ var helper = selection.anchorNode.className.indexOf('helper');
+ } catch (e) {
+ helper = null;
+ }
+ if (helper !== null && helper !== -1) {
+ return null;
+ }
+ var range = selection.getRangeAt(0);
+ var rects = range.getClientRects();
+ if (rects.length > 0 && rects[0].width > 0 && rects[0].height > 0) {
+ return rects;
+ }
+ } catch (e) {}
+ return null;
+ }
+ /**
+ * Handle document.mousedown event
+ *
+ * @param {Event} e The DOM event to handle
+ */
+ function handleDocumentMousedown(e) {
+ if (
+ !(_svg = (0, _utils.findSVGAtPoint)(e.clientX, e.clientY)) ||
+ _type !== 'area'
+ ) {
+ return;
+ }
+ rect = _svg.getBoundingClientRect();
+ originY = e.clientY;
+ originX = e.clientX;
+ overlay = document.createElement('div');
+ overlay.style.position = 'absolute';
+ overlay.id = 'overlay-rect';
+ overlay.style.top = originY - rect.top + 'px';
+ overlay.style.left = originX - rect.left + 'px';
+ overlay.style.border = '3px solid ' + _utils.BORDER_COLOR;
+ overlay.style.borderRadius = '3px';
+ _svg.parentNode.appendChild(overlay);
+ document.addEventListener('mousemove', handleDocumentMousemove);
+ (0, _utils.disableUserSelect)();
+ }
+
+ // Handle document.touchstart event
+ function handleDocumentTouchstart(e) {
+ if (_type == 'highlight' || _type == 'strikeout') {
+ // Dont show the contextmenu for highlighting and strikeout.
+ document
+ .getElementById('content-wrapper')
+ .addEventListener('contextmenu', (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ event.stopImmediatePropagation();
+ return false;
+ });
+ }
+
+ if (
+ !(_svg = (0, _utils.findSVGAtPoint)(
+ e.touches[0].clientX,
+ e.touches[0].clientY
+ )) ||
+ _type !== 'area'
+ ) {
+ return;
+ }
+ // Disable scrolling on the page.
+ document.documentElement.style.overflow = 'hidden';
+ document.getElementById('content-wrapper').style.overflow = 'hidden';
+
+ rect = _svg.getBoundingClientRect();
+ originY = e.touches[0].clientY;
+ originX = e.touches[0].clientX;
+ overlay = document.createElement('div');
+ overlay.style.position = 'absolute';
+ overlay.style.top = originY - rect.top + 'px';
+ overlay.style.left = originX - rect.left + 'px';
+ overlay.style.border = '3px solid ' + _utils.BORDER_COLOR;
+ overlay.style.borderRadius = '3px';
+ _svg.parentNode.appendChild(overlay);
+ document.addEventListener('touchmove', handleDocumentTouchmove);
+
+ (0, _utils.disableUserSelect)();
+ }
+
+ /**
+ * Handle document.mousemove event
+ *
+ * @param {Event} e The DOM event to handle
+ */
+ function handleDocumentMousemove(e) {
+ if (originX + (e.clientX - originX) < rect.right) {
+ overlay.style.width = e.clientX - originX + 'px';
+ }
+ if (originY + (e.clientY - originY) < rect.bottom) {
+ overlay.style.height = e.clientY - originY + 'px';
+ }
+ }
+
+ // Handle document.touchmove event
+ function handleDocumentTouchmove(e) {
+ if (originX + (e.touches[0].clientX - originX) < rect.right) {
+ overlay.style.width = e.touches[0].clientX - originX + 'px';
+ }
+ if (originY + (e.touches[0].clientY - originY) < rect.bottom) {
+ overlay.style.height = e.touches[0].clientY - originY + 'px';
+ }
+ }
+
+ /**
+ * Tests if the overlay is too small. An overlay is too small if the width or height are less 10 px or are NaN
+ * @param {type} overlay
+ * @returns {unresolved}
+ */
+ function isOverlayTooSmall(overlay) {
+ var width = parseInt(overlay.style.width);
+ var height = parseInt(overlay.style.height);
+ return isNaN(width) || isNaN(height) || width < 10 || height < 10;
+ }
+ /**
+ * Handle document.mouseup event
+ * concerns area,highlight and strikeout
+ * @param {Event} e The DOM event to handle
+ */
+ function handleDocumentMouseup(e) {
+ //if the cursor is clicked nothing should happen!
+ if (
+ typeof e.target.getAttribute('className') != 'string' &&
+ e.target.className.indexOf('cursor') === -1
+ ) {
+ document.removeEventListener('mousemove', handleDocumentMousemove);
+ disableRect();
+ if (_type === 'area' && overlay) {
+ if (isOverlayTooSmall(overlay)) {
+ overlay.parentNode.removeChild(overlay);
+ overlay = null;
+ enableRect(_type);
+ return;
+ }
+ renderRect(
+ _type,
+ [
+ {
+ top: parseInt(overlay.style.top, 10) + rect.top,
+ left: parseInt(overlay.style.left, 10) + rect.left,
+ width: parseInt(overlay.style.width, 10),
+ height: parseInt(overlay.style.height, 10),
+ },
+ ],
+ null
+ );
+
+ let fn = () => {
+ [textarea, data] = (0, _commentWrapper.openComment)(
+ e,
+ handleCancelClick,
+ handleSubmitClick,
+ handleToolbarClick,
+ handleSubmitBlur,
+ _type
+ );
+ };
+ _commentWrapper.loadEditor('add', 0, fn);
+ } else if ((rectsSelection = getSelectionRects()) && _type !== 'area') {
+ renderRect(
+ _type,
+ [].concat(_toConsumableArray(rectsSelection)).map(function (r) {
+ return {
+ top: r.top,
+ left: r.left,
+ width: r.width,
+ height: r.height,
+ };
+ }),
+ null
+ );
+
+ let fn = () => {
+ [textarea, data] = (0, _commentWrapper.openComment)(
+ e,
+ handleCancelClick,
+ handleSubmitClick,
+ handleToolbarClick,
+ handleSubmitBlur,
+ _type
+ );
+ };
+ _commentWrapper.loadEditor('add', 0, fn);
+ } else {
+ enableRect(_type);
+ //Do nothing!
+ }
+ }
+ }
+ // Handle document.touchend event
+ function handleDocumentTouchend(e) {
+ // Enable the scrolling again
+ document.documentElement.style.overflow = 'auto';
+ document.getElementById('content-wrapper').style.overflow = 'auto';
+
+ //if the cursor is clicked nothing should happen!
+ if (
+ typeof e.target.getAttribute('className') != 'string' &&
+ e.target.className.indexOf('cursor') === -1
+ ) {
+ document.removeEventListener('touchmove', handleDocumentTouchmove);
+ disableRect();
+ if (_type === 'area' && overlay) {
+ if (isOverlayTooSmall(overlay)) {
+ overlay.parentNode.removeChild(overlay);
+ overlay = null;
+ enableRect(_type);
+ return;
+ }
+ var _svg = overlay.parentNode.querySelector('svg.annotationLayer');
+ renderRect(
+ _type,
+ [
+ {
+ top: parseInt(overlay.style.top, 10) + rect.top,
+ left: parseInt(overlay.style.left, 10) + rect.left,
+ width: parseInt(overlay.style.width, 10),
+ height: parseInt(overlay.style.height, 10),
+ },
+ ],
+ null
+ );
+
+ [textarea, data] = (0, _commentWrapper.openComment)(
+ e,
+ handleCancelTouch,
+ handleSubmitClick,
+ handleToolbarClick,
+ handleSubmitBlur,
+ _type
+ );
+ } else if ((rectsSelection = getSelectionRects()) && _type !== 'area') {
+ renderRect(
+ _type,
+ [].concat(_toConsumableArray(rectsSelection)).map(function (r) {
+ return {
+ top: r.top,
+ left: r.left,
+ width: r.width,
+ height: r.height,
+ };
+ }),
+ null
+ );
+ [textarea, data] = (0, _commentWrapper.openComment)(
+ e,
+ handleCancelTouch,
+ handleSubmitClick,
+ handleToolbarClick,
+ handleSubmitBlur,
+ _type
+ );
+ } else {
+ enableRect(_type);
+ //Do nothing!
+ }
+ }
+ }
+
+ function handleToolbarClick(e) {
+ //delete Overlay
+ if (_type === 'area' && overlay) {
+ if (overlay.parentNode) {
+ overlay.parentNode.removeChild(overlay);
+ overlay = null;
+ }
+ }
+ document.querySelector('.toolbar').removeEventListener('click', handleToolbarClick);
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ false
+ );
+ deleteUndefinedRect();
+ }
+
+ function handleSubmitClick(e) {
+ var rects = void 0;
+ if (_type !== 'area' && (rects = rectsSelection)) {
+ saveRect(
+ _type,
+ [].concat(_toConsumableArray(rects)).map(function (r) {
+ return {
+ top: r.top,
+ left: r.left,
+ width: r.width,
+ height: r.height,
+ };
+ }),
+ null,
+ e
+ );
+ } else if (_type === 'area' && overlay) {
+ saveRect(
+ _type,
+ [
+ {
+ top: parseInt(overlay.style.top, 10) + rect.top,
+ left: parseInt(overlay.style.left, 10) + rect.left,
+ width: parseInt(overlay.style.width, 10),
+ height: parseInt(overlay.style.height, 10),
+ },
+ ],
+ null,
+ e,
+ overlay
+ );
+ }
+ return false;
+ }
+
+ function handleCancelClick(e) {
+ //delete Overlay
+ if (_type === 'area' && overlay) {
+ overlay.parentNode.removeChild(overlay);
+ overlay = null;
+ }
+ //Hide the form for Comments
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ false
+ );
+ deleteUndefinedRect();
+ //register EventListeners to allow new Annotations
+ enableRect(_type);
+ (0, _utils.enableUserSelect)();
+ }
+
+ function handleCancelTouch(e) {
+ // When using on mobile devices scrolling will be prevented, here we have to allow it again.
+ document.documentElement.style.overflow = 'auto';
+ document.getElementById('content-wrapper').style.overflow = 'auto';
+
+ //delete Overlay
+ if (_type === 'area' && overlay) {
+ overlay.parentNode.removeChild(overlay);
+ overlay = null;
+ }
+ //Hide the form for Comments
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ false
+ );
+ deleteUndefinedRect();
+
+ // Because of a scrolling issue we have to disable the area annotation after canceling the annotation.
+ if (_type === 'area') {
+ disableRect();
+ document.querySelector('button.cursor').click();
+ } else {
+ enableRect(_type);
+ (0, _utils.enableUserSelect)();
+ }
+ }
+
+ function handleSubmitBlur() {
+ if (overlay) {
+ overlay.parentNode.removeChild(overlay);
+ overlay = null;
+ }
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ false
+ );
+ deleteUndefinedRect();
+ }
+
+ /**
+ * Handle document.keyup event
+ *
+ * @param {Event} e The DOM event to handle
+ */
+ function handleDocumentKeyup(e) {
+ // Cancel rect if Esc is pressed
+ if (e.keyCode === 27) {
+ var selection = window.getSelection();
+ selection.removeAllRanges();
+ if (overlay && overlay.parentNode) {
+ overlay.parentNode.removeChild(overlay);
+ overlay = null;
+ document.removeEventListener('mousemove', handleDocumentMousemove);
+ }
+ }
+ }
+
+ function renderRect(type, rects, color) {
+ rect = _svg.getBoundingClientRect();
+ var _getMetadata = (0, _utils.getMetadata)(_svg);
+ documentId = _getMetadata.documentId;
+ pageNumber = _getMetadata.pageNumber;
+ var annotation = initializeAnnotation(type, rects, 'rgb(255,237,0)', _svg);
+ rectObj = [_svg, annotation];
+ (0, _appendChild2.default)(_svg, annotation);
+ }
+ /**
+ * This function deletes all annotations which data-pdf-annotate-id is undefined. An annotation is undefined, if it is only temporarily displayed.
+ * @returns {undefined}
+ */
+ function deleteUndefinedRect() {
+ let n = document.querySelector('[data-pdf-annotate-id="undefined"]');
+ if (n) {
+ n.parentNode.removeChild(n);
+ }
+ }
+
+ function initializeAnnotation(type, rects, color, svg) {
+ var node = void 0;
+ var annotation = void 0;
+ if (!svg) {
+ return;
+ }
+ if (!color) {
+ if (type === 'highlight') {
+ color = 'rgb(142,186,229)';
+ } else if (type === 'strikeout') {
+ color = 'rgb(0,84,159)';
+ }
+ }
+ // Initialize the annotation
+ annotation = {
+ type: type,
+ color: color,
+ rectangles: []
+ .concat(_toConsumableArray(rects))
+ .map(function (r) {
+ var offset = 0;
+ if (type === 'strikeout') {
+ offset = r.height / 2;
+ }
+ return (0,
+ _utils.scaleDown)(svg, { y: r.top + offset - rect.top, x: r.left - rect.left, width: r.width, height: r.height });
+ })
+ .filter(function (r) {
+ return r.width > 0 && r.height > 0 && r.x > -1 && r.y > -1;
+ }),
+ }; // Short circuit if no rectangles exist
+ if (annotation.rectangles.length === 0) {
+ return;
+ } // Special treatment for area as it only supports a single rect
+ if (type === 'area') {
+ var _rect = annotation.rectangles[0];
+ delete annotation.rectangles;
+ annotation.x = (0, _utils.roundDigits)(_rect.x, 4);
+ annotation.y = (0, _utils.roundDigits)(_rect.y, 4);
+ annotation.width = (0, _utils.roundDigits)(_rect.width, 4);
+ annotation.height = (0, _utils.roundDigits)(_rect.height, 4);
+ } else {
+ annotation.rectangles = annotation.rectangles.map(function (
+ elem,
+ index,
+ array
+ ) {
+ return {
+ x: (0, _utils.roundDigits)(elem.x, 4),
+ y: (0, _utils.roundDigits)(elem.y, 4),
+ width: (0, _utils.roundDigits)(elem.width, 4),
+ height: (0, _utils.roundDigits)(elem.height, 4),
+ };
+ });
+ }
+ return annotation;
+ }
+
+ /**
+ * Save a rect annotation
+ *
+ * @param {String} type The type of rect (area, highlight, strikeout)
+ * @param {Array} rects The rects to use for annotation
+ * @param {String} color The color of the rects
+ */
+ function saveRect(type, rects, color, e, overlay) {
+ var annotation = initializeAnnotation(type, rects, color, _svg);
+ var _getMetadata = (0, _utils.getMetadata)(_svg);
+ var documentId = _getMetadata.documentId;
+ var pageNumber = _getMetadata.pageNumber;
+ var content = textarea.value.trim();
+ if (textarea.value.trim().length > 0) {
+ (0, _commentWrapper.closeComment)(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ null,
+ true
+ );
+
+ if (_type === 'area' && overlay) {
+ overlay.parentNode.removeChild(overlay);
+ overlay = null;
+ document.removeEventListener('mousemove', handleDocumentMousemove);
+ (0, _utils.enableUserSelect)();
+ }
+ // Add the annotation
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .addAnnotation(documentId, pageNumber, annotation)
+ .then(
+ function (annotation) {
+ var commentVisibility = read_visibility_of_checkbox();
+ var isquestion = 1; //The annotation was created, so this comment has to be a question;
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .addComment(
+ documentId,
+ annotation.uuid,
+ content,
+ commentVisibility,
+ isquestion
+ )
+ .then(function (msg) {
+ if (!msg) throw new Error();
+ //delete previous annotation to render new one with the right id
+ deleteUndefinedRect();
+ //get Old rectangles because of scrolling
+ annotation.rectangles = rectObj[1].rectangles;
+
+ (0, _appendChild2.default)(_svg, annotation);
+ document
+ .querySelector('.toolbar')
+ .removeEventListener('click', handleToolbarClick);
+ //simulate an click on cursor
+ document.querySelector('button.cursor').click();
+ (0,
+ _commentWrapper.showCommentsAfterCreation)(annotation.uuid);
+ })
+ .catch(function () {
+ //if there is an error in addComment, the annotation should be deleted!
+ var annotationid = annotation.uuid;
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .deleteAnnotation(documentId, annotationid, false);
+ });
+ },
+ function (err) {
+ deleteUndefinedRect();
+ notification.addNotification({
+ message: M.util.get_string(
+ 'error:addAnnotation',
+ 'pdfannotator'
+ ),
+ type: 'error',
+ });
+ }
+ );
+ } else {
+ notification.addNotification({
+ message: M.util.get_string('min0Chars', 'pdfannotator'),
+ type: 'error',
+ });
+ handleCancelClick(e);
+ textarea.focus();
+ }
+ }
+ /**
+ * Enable rect behavior
+ */
+ function enableRect(type) {
+ _type = type;
+ if (_enabled) {
+ return;
+ }
+
+ if (_type === 'area') {
+ document.getElementById('content-wrapper').classList.add('cursor-area');
+ } else if (_type === 'highlight') {
+ document.getElementById('content-wrapper').classList.add('cursor-highlight');
+ } else if (_type === 'strikeout') {
+ document.getElementById('content-wrapper').classList.add('cursor-strikeout');
+ }
+
+ _enabled = true;
+ document.addEventListener('mouseup', handleDocumentMouseup);
+ document.addEventListener('mousedown', handleDocumentMousedown);
+ document.addEventListener('keyup', handleDocumentKeyup);
+
+ document.addEventListener('touchstart', handleDocumentTouchstart);
+ document.addEventListener('touchend', handleDocumentTouchend);
+ }
+ /**
+ * Disable rect behavior
+ */
+ function disableRect() {
+ if (!_enabled) {
+ return;
+ }
+ _enabled = false;
+ if (_type === 'area') {
+ document.getElementById('content-wrapper').classList.remove('cursor-area');
+ } else if (_type === 'highlight') {
+ document.getElementById('content-wrapper').classList.remove('cursor-highlight');
+ } else if (_type === 'strikeout') {
+ document.getElementById('content-wrapper').classList.remove('cursor-strikeout');
+ }
+ document.removeEventListener('mouseup', handleDocumentMouseup);
+ document.removeEventListener('mousedown', handleDocumentMousedown);
+ document.removeEventListener('keyup', handleDocumentKeyup);
+
+ document.removeEventListener('touchstart', handleDocumentTouchstart);
+ document.removeEventListener('touchend', handleDocumentTouchend);
+ }
+ },
+ /* 33 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _typeof =
+ typeof Symbol === 'function' && _typeof2(Symbol.iterator) === 'symbol'
+ ? function (obj) {
+ return typeof obj === 'undefined' ? 'undefined' : _typeof2(obj);
+ }
+ : function (obj) {
+ return obj && typeof Symbol === 'function' && obj.constructor === Symbol
+ ? 'symbol'
+ : typeof obj === 'undefined'
+ ? 'undefined'
+ : _typeof2(obj);
+ };
+ exports.setText = setText;
+ exports.enableText = enableText;
+ exports.disableText = disableText;
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _appendChild = __webpack_require__(11);
+ var _appendChild2 = _interopRequireDefault(_appendChild);
+ var _utils = __webpack_require__(6);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ var _enabled = false;
+ var input = void 0;
+ var pos = void 0;
+ var _textSize = void 0;
+ var _textColor = void 0;
+ var svg = void 0;
+ var rect = void 0;
+ /**
+ * Handle document.mouseup event
+ *
+ *
+ * @param {Event} e The DOM event to handle
+ */ function handleDocumentMouseup(e) {
+ // betrifft textbox
+ if (input || !(svg = (0, _utils.findSVGAtPoint)(e.clientX, e.clientY))) {
+ return;
+ }
+ let scrollTop = window.pageYOffset;
+ input = document.createElement('input');
+ input.setAttribute('id', 'pdf-annotate-text-input');
+ input.setAttribute('placeholder', M.util.get_string('enterText', 'pdfannotator'));
+ input.style.border = '3px solid ' + _utils.BORDER_COLOR;
+ input.style.borderRadius = '3px';
+ input.style.position = 'absolute';
+ input.style.top = e.clientY + scrollTop + 'px';
+ input.style.left = e.clientX + 'px';
+ input.style.fontSize = _textSize + 'px';
+ input.addEventListener('blur', handleInputBlur);
+ input.addEventListener('keyup', handleInputKeyup);
+ document.body.appendChild(input);
+ input.focus();
+ rect = svg.getBoundingClientRect();
+ pos = { x: e.clientX, y: e.clientY };
+ }
+ /**
+ * Handle input.blur event
+ */ function handleInputBlur() {
+ saveText();
+ }
+ /**
+ * Handle input.keyup event
+ *
+ * @param {Event} e The DOM event to handle
+ */ function handleInputKeyup(e) {
+ if (e.keyCode === 27) {
+ closeInput();
+ } else if (e.keyCode === 13) {
+ saveText();
+ }
+ }
+ /**
+ * Save a text annotation from input
+ */ function saveText() {
+ if (input.value.trim().length > 0) {
+ var _ret = (function () {
+ var clientX = parseInt(pos.x, 10);
+ //text size additional to y to render the text right under the mouse click
+ var clientY = parseInt(pos.y, 10);
+ //var svg=(0,_utils.findSVGAtPoint)(clientX,clientY);
+ if (!svg) {
+ return { v: void 0 };
+ }
+ var _getMetadata = (0, _utils.getMetadata)(svg);
+ var documentId = _getMetadata.documentId;
+ var pageNumber = _getMetadata.pageNumber;
+
+ var annotation = Object.assign(
+ {
+ type: 'textbox',
+ size: _textSize,
+ color: _textColor,
+ content: input.value.trim(),
+ },
+ (0, _utils.scaleDown)(svg, {
+ x: (0, _utils.roundDigits)(clientX - rect.left, 4),
+ y: (0, _utils.roundDigits)(clientY - rect.top, 4),
+ width: (0, _utils.roundDigits)(input.offsetWidth, 4),
+ height: (0, _utils.roundDigits)(input.offsetHeight, 4),
+ })
+ );
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .addAnnotation(documentId, pageNumber, annotation)
+ .then(
+ function (annotation) {
+ //annotation.y = annotation.y +parseInt(annotation.size,10);
+ (0, _appendChild2.default)(svg, annotation);
+ document.querySelector('button.cursor').click();
+ },
+ function (err) {
+ notification.addNotification({
+ message: M.util.get_string(
+ 'error:addAnnotation',
+ 'pdfannotator'
+ ),
+ type: 'error',
+ });
+ }
+ );
+ })();
+ if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === 'object')
+ return _ret.v;
+ }
+ closeInput();
+ }
+ /**
+ * Close the input
+ */ function closeInput() {
+ try {
+ if (input) {
+ input.removeEventListener('blur', handleInputBlur);
+ input.removeEventListener('keyup', handleInputKeyup);
+ document.body.removeChild(input);
+ input = null;
+ pos = null;
+ }
+ } catch {}
+ }
+ /**
+ * Set the text attributes
+ *
+ * @param {Number} textSize The size of the text
+ * @param {String} textColor The color of the text
+ */ function setText() {
+ var textSize =
+ arguments.length <= 0 || arguments[0] === undefined ? 12 : arguments[0];
+ var textColor =
+ arguments.length <= 1 || arguments[1] === undefined ? '000000' : arguments[1];
+ _textSize = parseInt(textSize, 10);
+ _textColor = textColor;
+ }
+ /**
+ * Enable text behavior
+ */ function enableText() {
+ if (_enabled) {
+ return;
+ }
+ _enabled = true;
+ document.getElementById('content-wrapper').classList.add('cursor-text');
+ document.addEventListener('mouseup', handleDocumentMouseup);
+ }
+ /**
+ * Disable text behavior
+ */ function disableText() {
+ if (!_enabled) {
+ return;
+ }
+ _enabled = false;
+ document.getElementById('content-wrapper').classList.remove('cursor-text');
+ document.removeEventListener('mouseup', handleDocumentMouseup);
+ }
+ },
+ /* 34 */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ var _slicedToArray = (function () {
+ function sliceIterator(arr, i) {
+ var _arr = [];
+ var _n = true;
+ var _d = false;
+ var _e = undefined;
+ try {
+ for (
+ var _i = arr[Symbol.iterator](), _s;
+ !(_n = (_s = _i.next()).done);
+ _n = true
+ ) {
+ _arr.push(_s.value);
+ if (i && _arr.length === i) break;
+ }
+ } catch (err) {
+ _d = true;
+ _e = err;
+ } finally {
+ try {
+ if (!_n && _i['return']) _i['return']();
+ } finally {
+ if (_d) throw _e;
+ }
+ }
+ return _arr;
+ }
+ return function (arr, i) {
+ if (Array.isArray(arr)) {
+ return arr;
+ } else if (Symbol.iterator in Object(arr)) {
+ return sliceIterator(arr, i);
+ } else {
+ throw new TypeError('Invalid attempt to destructure non-iterable instance');
+ }
+ };
+ })();
+
+ exports.createPage = createPage;
+ exports.renderPage = renderPage;
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _renderScreenReaderHints = __webpack_require__(20);
+ var _renderScreenReaderHints2 = _interopRequireDefault(_renderScreenReaderHints);
+ var _appendChild = __webpack_require__(11);
+ var _appendChild2 = _interopRequireDefault(_appendChild);
+ var _utils = __webpack_require__(6);
+ var _renderQuestions = __webpack_require__(38);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ var SIZE = 20;
+ // Template for creating a new page
+ //helper Layer as a Child of Textlayer added, because in firefox the handleDocumentClick only fires, if the click is outside of Textlayer or is on a child of Textlayer
+ var PAGE_TEMPLATE =
+ '\n \n';
+ /**
+ * Create a new page to be appended to the DOM.
+ *
+ * @param {Number} pageNumber The page number that is being created
+ * @return {HTMLElement}
+ */ function createPage(pageNumber) {
+ var temp = document.createElement('div');
+ temp.innerHTML = PAGE_TEMPLATE;
+ var page = temp.children[0];
+ var canvas = page.querySelector('canvas');
+ page.setAttribute('id', 'pageContainer' + pageNumber);
+ page.setAttribute('data-page-number', pageNumber);
+ canvas.mozOpaque = true;
+ canvas.setAttribute('id', 'page' + pageNumber);
+ return page;
+ }
+
+ let listOfPagesLoaded = [];
+ /**
+ * Render a page that has already been created.
+ *
+ * @param {Number} pageNumber The page number to be rendered
+ * @param {Object} renderOptions The options for rendering
+ * @return {Promise} Settled once rendering has completed
+ * A settled Promise will be either:
+ * - fulfilled: [pdfPage, annotations]
+ * - rejected: Error
+ */ function renderPage(pageNumber, renderOptions, reset = false) {
+ if (reset) {
+ listOfPagesLoaded = [];
+ currentAnnotations = [];
+ }
+ if (listOfPagesLoaded.indexOf(pageNumber) !== -1) {
+ return;
+ }
+ listOfPagesLoaded.push(pageNumber);
+
+ var documentId = renderOptions.documentId;
+ var pdfDocument = renderOptions.pdfDocument;
+ var scale = renderOptions.scale;
+ var _rotate = renderOptions.rotate; // Load the page and annotations
+ return Promise.all([
+ pdfDocument.getPage(pageNumber),
+ _PDFJSAnnotate2.default.getAnnotations(documentId, pageNumber),
+ ]).then(
+ function (_ref) {
+ var _ref2 = _slicedToArray(_ref, 2);
+ var pdfPage = _ref2[0];
+ var annotations = _ref2[1];
+ currentAnnotations[pageNumber] = annotations.annotations;
+
+ var page = document.getElementById('pageContainer' + pageNumber);
+ var svg = page.querySelector('.annotationLayer');
+ var canvas = page.querySelector('.canvasWrapper canvas');
+ var canvasContext = canvas.getContext('2d', { alpha: false });
+ var viewport = pdfPage.getViewport({
+ scale: scale,
+ rotation: _rotate,
+ });
+ var viewportWithoutRotate = pdfPage.getViewport({
+ scale: scale,
+ rotation: 0,
+ });
+ var transform = scalePage(pageNumber, viewport, canvasContext); // Render the page
+ return Promise.all([
+ pdfPage.render({
+ canvasContext: canvasContext,
+ viewport: viewport,
+ transform: transform,
+ }),
+ _PDFJSAnnotate2.default.render(svg, viewportWithoutRotate, annotations),
+ ])
+ .then(function () {
+ // Text content is needed for a11y, but is also necessary for creating
+ // highlight and strikeout annotations which require selecting text.
+ return pdfPage
+ .getTextContent({ normalizeWhitespace: true })
+ .then(function (textContent) {
+ return new Promise(function (resolve, reject) {
+ require([
+ 'mod_pdfannotator/pdf_viewer',
+ ], function (pdfjsViewer) {
+ // Render text layer for a11y of text content
+ var textLayer = page.querySelector('.textLayer');
+ var textLayerFactory =
+ new pdfjsViewer.DefaultTextLayerFactory();
+ var eventBus = new pdfjsViewer.EventBus();
+ // (Optionally) enable hyperlinks within PDF files.
+ var pdfLinkService = new pdfjsViewer.PDFLinkService(
+ {
+ eventBus,
+ }
+ );
+ // (Optionally) enable find controller.
+ var pdfFindController =
+ new pdfjsViewer.PDFFindController({
+ linkService: pdfLinkService,
+ eventBus,
+ });
+ var pageIdx = pageNumber - 1;
+ var highlighter = new pdfjsViewer.TextHighlighter({
+ pdfFindController,
+ eventBus,
+ pageIdx,
+ });
+ var textLayerBuilder =
+ textLayerFactory.createTextLayerBuilder(
+ textLayer,
+ pageIdx,
+ viewport,
+ true,
+ eventBus,
+ highlighter
+ );
+ pdfLinkService.setViewer(textLayerBuilder);
+ textLayerBuilder.setTextContent(textContent);
+ textLayerBuilder.render(); // Enable a11y for annotations
+
+ // Timeout is needed to wait for `textLayerBuilder.render`
+ //setTimeout(function(){try{(0,_renderScreenReaderHints2.default)(annotations.annotations);resolve();}catch(e){reject(e);}});
+ //ur weil setTimeout auskommentiert ist!!!!!
+ resolve();
+ });
+ });
+ });
+ })
+ .then(function () {
+ // Indicate that the page was loaded
+ page.setAttribute('data-loaded', 'true');
+
+ return [pdfPage, annotations];
+ });
+ },
+ function (err) {
+ notification.addNotification({
+ message: M.util.get_string('error:renderPage', 'pdfannotator'),
+ type: 'error',
+ });
+ }
+ );
+ }
+ /**
+ * Scale the elements of a page.
+ *
+ * @param {Number} pageNumber The page number to be scaled
+ * @param {Object} viewport The viewport of the PDF page (see pdfPage.getViewport(scale, rotation))
+ * @param {Object} context The canvas context that the PDF page is rendered to
+ * @return {Array} The transform data for rendering the PDF page
+ */ function scalePage(pageNumber, viewport, context) {
+ var page = document.getElementById('pageContainer' + pageNumber);
+ var canvas = page.querySelector('.canvasWrapper canvas');
+ var svg = page.querySelector('.annotationLayer');
+ var wrapper = page.querySelector('.canvasWrapper');
+ var textLayer = page.querySelector('.textLayer');
+ var outputScale = getOutputScale(context);
+ var transform = !outputScale.scaled
+ ? null
+ : [outputScale.sx, 0, 0, outputScale.sy, 0, 0];
+ var sfx = approximateFraction(outputScale.sx);
+ var sfy = approximateFraction(outputScale.sy); // Adjust width/height for scale
+ page.style.visibility = '';
+ canvas.width = roundToDivide(viewport.width * outputScale.sx, sfx[0]);
+ canvas.height = roundToDivide(viewport.height * outputScale.sy, sfy[0]);
+ canvas.style.width = roundToDivide(viewport.width, sfx[1]) + 'px';
+ canvas.style.height = roundToDivide(viewport.height, sfx[1]) + 'px';
+ svg.setAttribute('width', viewport.width);
+ svg.setAttribute('height', viewport.height);
+ svg.style.width = viewport.width + 'px';
+ svg.style.height = viewport.height + 'px';
+ page.style.width = viewport.width + 'px';
+ page.style.height = viewport.height + 'px';
+ wrapper.style.width = viewport.width + 'px';
+ wrapper.style.height = viewport.height + 'px';
+ textLayer.style.width = viewport.width + 'px';
+ textLayer.style.height = viewport.height + 'px';
+ return transform;
+ }
+ /**
+ * Approximates a float number as a fraction using Farey sequence (max order of 8).
+ *
+ * @param {Number} x Positive float number
+ * @return {Array} Estimated fraction: the first array item is a numerator,
+ * the second one is a denominator.
+ */ function approximateFraction(x) {
+ // Fast path for int numbers or their inversions.
+ if (Math.floor(x) === x) {
+ return [x, 1];
+ }
+ var xinv = 1 / x;
+ var limit = 8;
+ if (xinv > limit) {
+ return [1, limit];
+ } else if (Math.floor(xinv) === xinv) {
+ return [1, xinv];
+ }
+ var x_ = x > 1 ? xinv : x; // a/b and c/d are neighbours in Farey sequence.
+ var a = 0,
+ b = 1,
+ c = 1,
+ d = 1; // Limit search to order 8.
+ while (true) {
+ // Generating next term in sequence (order of q).
+ var p = a + c,
+ q = b + d;
+ if (q > limit) {
+ break;
+ }
+ if (x_ <= p / q) {
+ c = p;
+ d = q;
+ } else {
+ a = p;
+ b = q;
+ }
+ } // Select closest of neighbours to x.
+ if (x_ - a / b < c / d - x_) {
+ return x_ === x ? [a, b] : [b, a];
+ } else {
+ return x_ === x ? [c, d] : [d, c];
+ }
+ }
+ function getOutputScale(ctx) {
+ var devicePixelRatio = window.devicePixelRatio || 1;
+ var backingStoreRatio =
+ ctx.webkitBackingStorePixelRatio ||
+ ctx.mozBackingStorePixelRatio ||
+ ctx.msBackingStorePixelRatio ||
+ ctx.oBackingStorePixelRatio ||
+ ctx.backingStorePixelRatio ||
+ 1;
+ var pixelRatio = devicePixelRatio / backingStoreRatio;
+ return { sx: pixelRatio, sy: pixelRatio, scaled: pixelRatio !== 1 };
+ }
+ function roundToDivide(x, div) {
+ var r = x % div;
+ return r === 0 ? x : Math.round(x - r + div);
+ }
+ },
+ /* 35 */ /* own module to handle the comment wrapper */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.deleteUndefinedRect = deleteUndefinedRect;
+ exports.openComment = openComment;
+ exports.closeComment = closeComment;
+ exports.showCommentsAfterCreation = showCommentsAfterCreation;
+ exports.openCommentTouchscreen = openCommentTouchscreen;
+ exports.loadEditor = loadEditor;
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _event = __webpack_require__(4);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _setAttributes = __webpack_require__(14);
+ var _setAttributes2 = _interopRequireDefault(_setAttributes);
+ var _utils = __webpack_require__(6);
+ var _ajaxloader = __webpack_require__(36);
+ var _questionRenderer = __webpack_require__(38);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+
+ var _e = null;
+ var textarea = void 0;
+ var submitbutton = void 0;
+ var resetbutton = void 0;
+ var form = void 0;
+ var data = void 0;
+ var rectsSelection = void 0;
+
+ function deleteUndefinedRect() {
+ let n = document.querySelector('[data-pdf-annotate-id="undefined"]');
+ n.parentNode.removeChild(n);
+ }
+
+ function showCommentsAfterCreation(annoid) {
+ //Remove Loader from Comment-Container
+ (0, _ajaxloader.hideLoader)();
+
+ //Show Comments
+ let target = $('[data-pdf-annotate-id=' + annoid + ']')[0];
+ //fire annotation:click event with the annotation as target
+ _event.fireEvent('annotation:click', target);
+ }
+
+ /**
+ * This function closes the comment wrapper
+ * @param {type} documentId The id of the document (for render the questions afterwards)
+ * @param {type} pageNumber The page number (for render the questions afterwards)
+ * @param {type} handleSubmitClick Handler to remove
+ * @param {type} handleCancelClick Handler to remove
+ * @param {type} toolbarClick Handler to remove
+ * @param {boolean} loading True, if the loader should be displayed
+ * @returns {void}
+ */
+ function closeComment(
+ documentId,
+ pageNumber,
+ handleSubmitClick,
+ handleCancelClick,
+ toolbarClick,
+ loading
+ ) {
+ document.querySelector('.comment-list-form').setAttribute('style', 'display:none');
+ document
+ .querySelector('.comment-list-form')
+ .removeEventListener('onsubmit', handleSubmitClick);
+ document
+ .getElementById('commentCancel')
+ .removeEventListener('click', handleCancelClick);
+ document.querySelector('.toolbar').removeEventListener('click', toolbarClick);
+ document.getElementById('commentSubmit').value = M.util.get_string(
+ 'answerButton',
+ 'pdfannotator'
+ );
+ document.getElementById('id_pdfannotator_content').value = '';
+ document.getElementById('id_pdfannotator_content').placeholder = M.util.get_string(
+ 'addAComment',
+ 'pdfannotator'
+ );
+ // Reset the typed text for other editors.
+ var editorArea = document.querySelector('#id_pdfannotator_contenteditable'); // Atto editor.
+ if (!editorArea) {
+ // TinyMCE editor.
+ var iframe = document.getElementById('myarea_ifr');
+ if (iframe) {
+ editorArea = iframe.contentWindow.document.getElementById('tinymce');
+ }
+ }
+ if (editorArea) {
+ editorArea.innerHTML = '';
+ }
+ data = null;
+ textarea = null;
+ submitbutton = null;
+ if (loading) {
+ (0, _ajaxloader.showLoader)();
+ } else {
+ _questionRenderer.renderQuestions(documentId, pageNumber);
+ }
+ }
+
+ /**
+ * Opens the commen wrapper
+ * @param {event} e the click Event of the annotation
+ * @param {type} cancelClick EventListener to add
+ * @param {type} submitClick EventListener to add
+ * @param {type} toolbarClick EventListener to add
+ * @param {type} submitBlur EventListener to add
+ * @param {type} _type which type of annotation
+ * @returns {Array} [0] textarea [1] data (position of the annotation)
+ */
+ function openComment(e, cancelClick, submitClick, toolbarClick, submitBlur, _type) {
+ //save e for later
+ _e = e;
+
+ var button1 = document.getElementById('allQuestions'); // to be found in index template
+ button1.style.display = 'inline';
+ var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
+ button2.style.display = 'inline';
+
+ //title
+ $('#comment-wrapper h4')[0].innerHTML = M.util.get_string(
+ 'comments',
+ 'pdfannotator'
+ );
+ //add Eventlistener to Toolbar. Every Click in Toolbar should cancel the Annotation-Comment-Creation
+ document.querySelector('.toolbar').addEventListener('click', toolbarClick);
+ //Hide shown comments
+ document.querySelector('.comment-list-container').innerHTML = '';
+ form = document.querySelector('.comment-list-form');
+ $(document).ready(function () {
+ form.setAttribute('style', 'display:inherit');
+ $('#anonymousDiv').show();
+ $('#privateDiv').show();
+ $('#protectedDiv').show();
+ });
+ textarea = document.getElementById('id_pdfannotator_content');
+ textarea.placeholder = M.util.get_string('startDiscussion', 'pdfannotator');
+ submitbutton = document.getElementById('commentSubmit');
+ submitbutton.value = M.util.get_string('createAnnotation', 'pdfannotator');
+ resetbutton = document.getElementById('commentCancel');
+ resetbutton.addEventListener('click', cancelClick);
+ form.onsubmit = submitClick;
+ //fixCommentForm();
+ if (_type === 'pin') {
+ data = new Object();
+ data.x = e.clientX;
+ data.y = e.clientY;
+ } else {
+ data = document.createElement('div');
+ data.setAttribute('id', 'pdf-annotate-point-input');
+ data.style.border = '3px solid ' + _utils.BORDER_COLOR;
+ data.style.borderRadius = '3px';
+ data.style.display = 'none';
+ data.style.position = 'absolute';
+ data.style.top = e.clientY + 'px';
+ data.style.left = e.clientX + 'px';
+ }
+
+ form.addEventListener('blur', submitBlur);
+ textarea.focus();
+ return [textarea, data];
+ }
+
+ function openCommentTouchscreen(
+ e,
+ cancelClick,
+ submitClick,
+ toolbarClick,
+ submitBlur,
+ _type
+ ) {
+ //save e for later
+ _e = e;
+
+ var button1 = document.getElementById('allQuestions'); // to be found in index template
+ button1.style.display = 'inline';
+ var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
+ button2.style.display = 'inline';
+
+ //title
+ $('#comment-wrapper h4')[0].innerHTML = M.util.get_string(
+ 'comments',
+ 'pdfannotator'
+ );
+ //add Eventlistener to Toolbar. Every Click in Toolbar should cancel the Annotation-Comment-Creation
+ document.querySelector('.toolbar').addEventListener('click', toolbarClick);
+ //Hide shown comments
+ document.querySelector('.comment-list-container').innerHTML = '';
+ form = document.querySelector('.comment-list-form');
+ form.setAttribute('style', 'display:inherit');
+ $('#anonymousCheckbox').show();
+ $('#privateCheckbox').show();
+ $('#protectedCheckbox').show();
+ textarea = document.getElementById('id_pdfannotator_content');
+ textarea.placeholder = M.util.get_string('startDiscussion', 'pdfannotator');
+ submitbutton = document.getElementById('commentSubmit');
+ submitbutton.value = M.util.get_string('createAnnotation', 'pdfannotator');
+ resetbutton = document.getElementById('commentCancel');
+ resetbutton.addEventListener('click', cancelClick);
+ form.onsubmit = submitClick;
+ //fixCommentForm();
+ if (_type === 'pin') {
+ data = new Object();
+ data.x = e.changedTouches[0].clientX;
+ data.y = e.changedTouches[0].clientY;
+ } else {
+ data = document.createElement('div');
+ data.setAttribute('id', 'pdf-annotate-point-input');
+ data.style.border = '3px solid ' + _utils.BORDER_COLOR;
+ data.style.borderRadius = '3px';
+ data.style.display = 'none';
+ data.style.position = 'absolute';
+ data.style.top = e.clientY + 'px';
+ data.style.left = e.clientX + 'px';
+ }
+
+ form.addEventListener('blur', submitBlur);
+ textarea.focus();
+ return [textarea, data];
+ }
+
+ /**
+ *
+ * @param {type} action can be add for adding comments. Or edit for editing comments.
+ * @param {int} uuid
+ * @param {Function} fn a callback funtion. It will be called after the Promises in this funktion finish.
+ *
+ *
+ */
+ function loadEditor(action = 'add', uuid = 0, fn = null, fnParams = null) {
+ // search the placeholder for editor.
+ let addCommentEditor = document.querySelectorAll('#add_comment_editor_wrapper');
+ let editCommentEditor = document.querySelectorAll(
+ `#edit_comment_editor_wrapper_${uuid}`
+ );
+
+ if (action === 'add') {
+ _ajaxloader.showLoader(`.editor-loader-placeholder-${action}`);
+
+ // remove old editor and old input values of draftitemid and editorformat, if exists.
+ if (addCommentEditor.length > 0) {
+ addCommentEditor[0].remove();
+ }
+
+ let data = {};
+ templates
+ .render('mod_pdfannotator/add_comment_editor_placeholder', data)
+ .then(function (html, js) {
+ let commentListForm = document.getElementById('comment-list-form');
+ templates.prependNodeContents(commentListForm, html, js);
+ if (_editorSettings.active_editor === 'textarea_texteditor') {
+ document
+ .getElementById('id_pdfannotator_content')
+ .setAttribute('style', 'display:unset !important');
+ }
+ })
+ .then(function () {
+ let args = { action: action, cmid: _cm.id };
+ Fragment.loadFragment(
+ 'mod_pdfannotator',
+ 'open_add_comment_editor',
+ _contextId,
+ args
+ )
+ .done(function (html, js) {
+ if (!html) {
+ throw new TypeError('Invalid HMTL Input');
+ }
+ templates.replaceNode(
+ document.getElementById('editor-commentlist-inputs'),
+ html,
+ js
+ );
+ if (fn instanceof Function) {
+ (0, fn)(fnParams);
+ }
+ _ajaxloader.hideLoader(`.editor-loader-placeholder-${action}`);
+ return true;
+ })
+ .then(function () {
+ let commentText = document.getElementById(
+ 'id_pdfannotator_contenteditable'
+ );
+ if (commentText) {
+ commentText.focus();
+ }
+ });
+ })
+ .catch(notification.exception);
+ } else if (action === 'edit') {
+ _ajaxloader.showLoader(`.editor-loader-placeholder-${action}-${uuid}`);
+
+ // remove old editor and old input values of draftitemid and editorformat, if exists.
+ if (editCommentEditor.length > 0) {
+ editCommentEditor[0].remove();
+ }
+
+ let data = { uuid: uuid };
+ templates
+ .render('mod_pdfannotator/edit_comment_editor_placeholder', data)
+ .then(function (html, js) {
+ let editForm = document.getElementById(`edit${uuid}`);
+ templates.prependNodeContents(editForm, html, js);
+ return true;
+ })
+ .then(function () {
+ let args = { action: action, cmid: _cm.id, uuid: uuid };
+ Fragment.loadFragment(
+ 'mod_pdfannotator',
+ 'open_edit_comment_editor',
+ _contextId,
+ args
+ )
+ .then(function (html, js) {
+ if (!html) {
+ throw new TypeError('Invalid HMTL Input');
+ }
+ //templates.runTemplateJS(js);
+ let editCommentEditorElement = document.getElementById(
+ `edit_comment_editor_wrapper_${uuid}`
+ );
+ html = html.split('displaycontent:');
+ let isreplaced = templates.appendNodeContents(
+ editCommentEditorElement,
+ html[0],
+ js
+ );
+ let editTextarea = document.getElementById(`editarea${uuid}`);
+ editTextarea.innerText = html[1];
+
+ _ajaxloader.hideLoader(
+ `.editor-loader-placeholder-${action}-${uuid}`
+ );
+
+ let editForm = document.getElementById(`edit${uuid}`);
+ let chatMessage = document.getElementById(`chatmessage${uuid}`);
+ let editAreaEditable = document.getElementById(
+ `editarea${uuid}editable`
+ );
+ if (editAreaEditable) {
+ // Does not exist for tinymce editor.
+ editAreaEditable.innerHTML = editTextarea.value;
+ }
+ if (editForm.style.display === 'none') {
+ editForm.style.cssText += ';display:block;';
+ chatMessage.innerHTML = '';
+ }
+ return true;
+ })
+ .then(function () {
+ let commentText = document.getElementById(`editarea${uuid}`);
+ if (commentText) {
+ commentText.focus();
+ }
+ if (fn instanceof Function) {
+ (0, fn)(fnParams);
+ }
+ });
+ })
+ .catch(notification.exception);
+ } else {
+ // nothing to do.
+ }
+ }
+ },
+ /* 36 */ /*OWN Module! To show and hide ajaxloader */
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.showLoader = showLoader;
+ exports.hideLoader = hideLoader;
+
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+
+ /**
+ * hides the loading animation
+ * @returns {undefined}
+ */
+ function hideLoader(selector = '.comment-list-container') {
+ let loader = document.querySelector('#ajaxLoaderCreation');
+ if (loader !== null) {
+ let commentContainer = document.querySelectorAll(`${selector}`)[0];
+ commentContainer.removeChild(loader);
+ }
+ }
+
+ /**
+ * Shows an loading animation in the comment wrapper
+ * @returns {undefined}
+ */
+ function showLoader(selector = '.comment-list-container') {
+ let commentContainer = document.querySelector(`${selector}`);
+ commentContainer.innerHTML = '';
+ let img = document.createElement('img');
+ img.id = 'ajaxLoaderCreation';
+ img.src = M.util.image_url('i/loading');
+ img.alt = M.util.get_string('loading', 'pdfannotator');
+ img.classList.add('icon');
+ img.style = 'display: block; margin-left: auto;margin-right: auto;';
+ commentContainer.appendChild(img);
+ }
+ },
+ /* 37 */ /*OWN Module! To pick an annotation*/
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.pickAnnotation = pickAnnotation;
+ var _event = __webpack_require__(4);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+
+ /**
+ * This function scrolls to the specific annotation and selects the annotation
+ * @param {type} page of the annotation
+ * @param {type} annoid the id of the picked annotation
+ * @param {type} commid id of the comment, if a comment should be marked, else null
+ * @return {void}
+ */
+ function pickAnnotation(page, annoid, commid) {
+ //[0] for only first element (it only can be one element)
+ var target = $('[data-pdf-annotate-id=' + annoid + ']')[0];
+ if (commid !== null) {
+ target.markCommentid = commid;
+ }
+ _event.fireEvent('annotation:click', target);
+
+ //Scroll to defined page (because of the picked annotation (new annotation, new answer or report) from overview)
+ var targetDiv = $('[data-target-id=' + annoid + ']')[0];
+ var pageOffset = document.getElementById('pageContainer' + page).offsetTop;
+
+ var contentWrapper = $('#content-wrapper');
+ contentWrapper.scrollTop(pageOffset + targetDiv.offsetTop - 100);
+ contentWrapper.scrollLeft(targetDiv.offsetLeft - contentWrapper.width() + 100);
+ }
+ },
+ /* 38 */ /*OWN Module! To show questions of one PDF-Page on the right side*/
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.renderQuestions = renderQuestions;
+ exports.renderAllQuestions = renderAllQuestions;
+ var _event = __webpack_require__(4);
+ var _shortText = __webpack_require__(39);
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+
+ /**
+ * This function renders on the right side the questions of all annotations of a specific page.
+ *
+ * @param {type} documentId the Id of the pdf
+ * @param {type} pageNumber the requested pagenumber
+ * @param {type} activeCall specifies that the function was called by click on button with id='questionsOnThisPage'
+ * @return {undefined}
+ */
+ function renderQuestions(documentId, pageNumber, activeCall = null) {
+ let pattern = $('#searchPattern').val();
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .getQuestions(documentId, pageNumber, pattern)
+ .then(
+ function (questions) {
+ const showAllQuestions = document.querySelector('#showAllComments').getAttribute('data-active');
+ if(showAllQuestions === 'false'){
+ let visibility;
+ const showPrivate = document.querySelector('#showPrivateComments').getAttribute('data-active');
+
+ if(showPrivate === 'true') {
+ visibility = ['private', 'protected'];
+ } else {
+ visibility = ['anonymous', 'public'];
+ }
+ questions = questions.filter(e => visibility.includes(e.visibility));
+ }
+
+ let container = document.querySelector('.comment-list-container');
+ let title = $('#comment-wrapper > h4')[0];
+ if (pattern === '') {
+ title.innerHTML =
+ M.util.get_string('questionstitle', 'pdfannotator') +
+ ' ' +
+ pageNumber;
+ } else {
+ title.innerHTML = M.util.get_string(
+ 'searchresults',
+ 'pdfannotator'
+ );
+ }
+ var button1 = document.getElementById('allQuestions'); // to be found in index template
+ button1.style.display = 'inline';
+ var button2 = document.getElementById('questionsOnThisPage'); // to be found in index template
+ button2.style.display = 'none';
+ let visibilityButtons = document.querySelector('.comment-visibility');
+ visibilityButtons.style.display = 'inline';
+
+ //only if form is not shown, otherwise the questions should not be rendered
+ if (
+ document.querySelector('.comment-list-form').style.display ===
+ 'none' ||
+ activeCall
+ ) {
+ if (activeCall) {
+ document.querySelector('.comment-list-form').style.display =
+ 'none';
+ }
+ container.innerHTML = '';
+
+ if (questions.length < 1) {
+ if (pattern === '') {
+ container.innerHTML = M.util.get_string(
+ 'noquestions',
+ 'pdfannotator'
+ );
+ } else {
+ container.innerHTML = M.util.get_string(
+ 'nosearchresults',
+ 'pdfannotator'
+ );
+ }
+ } else {
+ for (let id in questions) {
+ let question = questions[id];
+ let questionWrapper = document.createElement('div');
+ questionWrapper.className =
+ 'chat-message comment-list-item questions';
+ // Add different background colors (orange/blue) and icons to distinguish private from public
+ let questionVisibility = document.createElement('img');
+ if (question.visibility === 'private' || question.visibility === 'protected') {
+ questionWrapper.className =
+ 'chat-message comment-list-item questions questions-private';
+ questionVisibility.src = M.util.image_url('comments_private_indicator','pdfannotator');
+ questionVisibility.alt = M.util.get_string('comments_icon_private','pdfannotator');
+ questionVisibility.title = M.util.get_string('comments_icon_private','pdfannotator');
+ questionVisibility.className = 'question-private-icon';
+ } else if (question.visibility === 'anonymous' || question.visibility === 'public'){
+ questionVisibility.src = M.util.image_url('comments_public_indicator','pdfannotator');
+ questionVisibility.alt = M.util.get_string('comments_icon_public','pdfannotator');
+ questionVisibility.title = M.util.get_string('comments_icon_public','pdfannotator');
+ questionVisibility.className = 'question-public-icon';
+ }
+
+ let questionText = document.createElement('span');
+ questionText.className = 'more';
+ questionText.innerHTML = question.content;
+ let questionAnswercount = document.createElement('span');
+ questionAnswercount.innerHTML = question.answercount;
+ questionAnswercount.className = 'questionanswercount';
+
+ let questionPix = document.createElement('i');
+ questionPix.classList =
+ 'icon fa fa-comment fa-fw questionanswercount';
+ questionPix.title = M.util.get_string(
+ 'answers',
+ 'pdfannotator'
+ );
+
+ let iconWrapper = document.createElement('div');
+ iconWrapper.className = 'icon-wrapper';
+
+ if (question.solved != 0) {
+ let solvedPix = document.createElement('i');
+ solvedPix.classList =
+ 'icon fa fa-lock fa-fw solvedicon';
+ solvedPix.title = M.util.get_string(
+ 'questionSolved',
+ 'pdfannotator'
+ );
+ iconWrapper.appendChild(solvedPix);
+ }
+
+ iconWrapper.appendChild(questionPix);
+ iconWrapper.appendChild(questionAnswercount);
+
+ questionWrapper.style.position = 'relative';
+ questionWrapper.appendChild(questionVisibility);
+ questionWrapper.appendChild(questionText);
+ questionWrapper.appendChild(iconWrapper);
+
+ container.appendChild(questionWrapper);
+ (function (questionObj, questionDOM) {
+ questionDOM.onclick = function (e) {
+ if (
+ questionObj.page !== undefined &&
+ questionObj.page !== $('#currentPage').val()
+ ) {
+ $('#content-wrapper').scrollTop(
+ document.getElementById(
+ 'pageContainer' + questionObj.page
+ ).offsetTop
+ );
+ }
+ (function scrollToAnnotation(
+ annotationid,
+ pageNumber
+ ) {
+ let target = $(
+ '[data-pdf-annotate-id=' +
+ annotationid +
+ ']'
+ )[0];
+ // if scrolled to a different page (see a few lines above) and page isn't loaded yet; wait and try again
+ if (target === undefined) {
+ setTimeout(function () {
+ scrollToAnnotation(
+ annotationid,
+ pageNumber
+ );
+ }, 200);
+ } else {
+ _event.fireEvent(
+ 'annotation:click',
+ target
+ );
+ var targetDiv = $(
+ '[data-target-id=' + annotationid + ']'
+ )[0];
+ var contentWrapper = $('#content-wrapper');
+ if (pageNumber === undefined) {
+ pageNumber = $('#currentPage').val();
+ }
+ var pageOffset = document.getElementById(
+ 'pageContainer' + pageNumber
+ ).offsetTop;
+ contentWrapper.scrollTop(
+ pageOffset + targetDiv.offsetTop - 100
+ );
+ contentWrapper.scrollLeft(
+ targetDiv.offsetLeft -
+ contentWrapper.width() +
+ 100
+ );
+ }
+ })(questionObj.annotationid, questionObj.page);
+ };
+ })(question, questionWrapper);
+ }
+ // comment overview column
+ //_shortText.mathJaxAndShortenText('.more', 4);
+ _shortText.shortenTextDynamic(null, '.more', 4);
+ }
+ }
+ },
+ function (err) {
+ notification.addNotification({
+ message: M.util.get_string('error:getQuestions', 'pdfannotator'),
+ type: 'error',
+ });
+ }
+ );
+ }
+
+ /**
+ * Function renders overview column for all questions in this document
+ *
+ * @param {type} documentId
+ * @return {undefined}
+ */
+ function renderAllQuestions(documentId) {
+ _PDFJSAnnotate2.default
+ .getStoreAdapter()
+ .getQuestions(documentId)
+ .then(
+ function (questions) {
+ let container = document.querySelector('.comment-list-container');
+ let title = $('#comment-wrapper > h4')[0];
+ title.innerHTML =
+ M.util.get_string('allquestionstitle', 'pdfannotator') +
+ ' ' +
+ questions.pdfannotatorname;
+
+ container.innerHTML = '';
+
+ questions = questions.questions;
+
+ var button1 = document.getElementById('allQuestions'); // to be found in index.mustache template
+ button1.style.display = 'none';
+ var button2 = document.getElementById('questionsOnThisPage'); // to be found in index.mustache template
+ button2.style.display = 'inline';
+ let visibilityButtons = document.querySelector('.comment-visibility');
+ visibilityButtons.style.display = 'none';
+
+ if (
+ document.querySelector('.comment-list-form').style.display !==
+ 'none'
+ ) {
+ document.querySelector('.comment-list-form').style.display = 'none';
+ }
+
+ if (questions.length < 1) {
+ container.innerHTML = M.util.get_string(
+ 'noquestions_view',
+ 'pdfannotator'
+ );
+ } else {
+ for (var page in questions) {
+ let questionWrapper = document.createElement('div');
+ questionWrapper.className =
+ 'chat-message comment-list-item questions page';
+ let questionText = document.createElement('span');
+ questionText.innerHTML =
+ M.util.get_string('page', 'pdfannotator') + ' ' + page;
+ let questionAnswercount = document.createElement('span');
+ questionAnswercount.innerHTML = questions[page].length;
+ questionAnswercount.className = 'questionanswercount';
+
+ let questionPix = document.createElement('i');
+ questionPix.classList =
+ 'icon fa fa-comments fa-fw questionanswercount';
+ questionPix.title = M.util.get_string(
+ 'questionsimgtitle',
+ 'pdfannotator'
+ );
+ let iconWrapper = document.createElement('div');
+ iconWrapper.classList = 'icon-wrapper';
+ iconWrapper.appendChild(questionAnswercount);
+ iconWrapper.appendChild(questionPix);
+ questionWrapper.appendChild(questionText);
+ questionWrapper.appendChild(iconWrapper);
+ container.appendChild(questionWrapper);
+ (function (page, questionDOM) {
+ questionDOM.onclick = function (e) {
+ $('#content-wrapper').scrollTop(
+ document.getElementById('pageContainer' + page)
+ .offsetTop
+ );
+ var pageinputfield =
+ document.getElementById('currentPage');
+ if (pageinputfield.value === page) {
+ renderQuestions(documentId, page, 1);
+ }
+ };
+ })(page, questionWrapper);
+ }
+ }
+ },
+ function (err) {
+ notification.addNotification({
+ message: M.util.get_string('error:getAllQuestions', 'pdfannotator'),
+ type: 'error',
+ });
+ }
+ );
+ }
+ },
+ /* 39 */ /*OWN Module! To shorten a specific text*/
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.shortenText = shortenText;
+ exports.shortenTextDynamic = shortenTextDynamic;
+ exports.mathJaxAndShortenText = mathJaxAndShortenText;
+
+ /**
+ * Shorten display of any report or question to a maximum of 80 characters and display
+ * a 'view more'/'view less' link
+ *
+ * Copyright 2013 Viral Patel and other contributors
+ * http://viralpatel.net
+ *
+ * slightly modified by RWTH Aachen in 2018
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * @param {type} selector
+ * @param {type} maxLength
+ * @param {type} ellipsesText
+ * @returns {undefined}
+ */
+ function shortenText(selector, maxLength = 80, ellipsesText = '...') {
+ var showChar = maxLength;
+ var moretext = M.util.get_string('showmore', 'pdfannotator');
+ var lesstext = M.util.get_string('showless', 'pdfannotator');
+ $(selector).each(function () {
+ if ($(this).children().first().attr('id') === 'content') {
+ return;
+ }
+ var content = $(this).html();
+ //determine if the message should be shortend, here only the characters without the html should be considered
+ var contentWithoudTags = this.innerText;
+ if (contentWithoudTags.length > showChar + ellipsesText.length) {
+ //for the clip-function you should import textclipper.js
+ var c = clip(unescape(content), showChar, {
+ html: true,
+ indicator: '',
+ }); //clipped content, the indicator is nothing, because we add the ellipsesText manually in the html
+ var h = content; // complete content
+ var html =
+ '' +
+ c +
+ '' +
+ ellipsesText +
+ ' ' +
+ h +
+ '' +
+ c +
+ ' ' +
+ moretext +
+ '';
+ $(this).html(html);
+ }
+ });
+
+ $(selector + ' .morelink').click(function () {
+ if ($(this).hasClass('less')) {
+ $(this).removeClass('less');
+ $(this).html(moretext); // entspricht innerHTML
+ $(this).parent().prev().prev().html($(this).prev().html());
+ // $(selector+" #content").html($(selector+" .morecontent .clippedContent").html());
+ } else {
+ $(this).addClass('less');
+ $(this).html(lesstext);
+ $(this).parent().prev().prev().html($(this).prev().prev().html());
+ // $(selector+" #content").html($(selector+" .morecontent .completeContent").html());
+ }
+ $(this).parent().prev().toggle(); //span .moreellipses
+ return false;
+ });
+ }
+
+ /**
+ * This function shortens the text. The length of the string is determined by the size of the parent and the given divisor.
+ * @param {type} parentselector The selector of which the size should be referenced
+ * @param {type} selector The selector where the text should be shortened
+ * @param {type} divisor The textlength is the size / divisior
+ * @param {type} ellipsesText text which should be displayed to point out that the text was shortened
+ * @returns {undefined}
+ */
+ function shortenTextDynamic(parentselector, selector, divisor) {
+ if (parentselector === null) {
+ let elem = document.querySelector(selector);
+ if (elem !== null) {
+ var parent = elem.parentElement;
+ } else {
+ return;
+ }
+ } else {
+ var parent = document.querySelector(parentselector);
+ }
+ if (parent !== null) {
+ let minCharacters = 80;
+ let maxCharacters = 120;
+ let nCharactersToDisplay = parent.offsetWidth / divisor;
+
+ if (nCharactersToDisplay < minCharacters) {
+ shortenText(selector);
+ } else if (nCharactersToDisplay > maxCharacters) {
+ nCharactersToDisplay = maxCharacters;
+ shortenText(selector, nCharactersToDisplay);
+ } else {
+ shortenText(selector, nCharactersToDisplay);
+ }
+ } else {
+ shortenText(selector); // Default: 80 characters
+ }
+ }
+
+ /**
+ * Renders MathJax and calls shortenText() afterwards.
+ * @param {type} selector
+ * @param {type} divisor
+ * @param {type} click
+ * @returns {undefined}
+ */
+ function mathJaxAndShortenText(selector, divisor, click = false) {
+ /*
+ if (typeof MathJax !== 'undefined') {
+ // Add the Mathjax-function and the shortenText function to the queue.
+ if (MathJax.Hub !== 'undefined') {
+ MathJax.Hub.Queue(
+ ['Typeset', MathJax.Hub],
+ [
+ function () {
+ shortenTextDynamic(null, selector, divisor);
+ if (click) {
+ $(selector + ' .morelink').click();
+ }
+ },
+ null,
+ ]
+ );
+ }
+ } else {
+ shortenTextDynamic(null, selector, divisor);
+ if (click) {
+ $(selector + ' .morelink').click();
+ }
+ }*/
+ }
+ },
+ /* 40 */ /*OWN Module! To load new annotations (Synchronisation between sessions)*/
+ function (module, exports, __webpack_require__) {
+ 'use strict';
+ Object.defineProperty(exports, '__esModule', { value: true });
+ exports.load = loadNewAnnotations;
+ var _event = __webpack_require__(4);
+ var _shortText = __webpack_require__(39);
+ var _PDFJSAnnotate = __webpack_require__(1);
+ var _PDFJSAnnotate2 = _interopRequireDefault(_PDFJSAnnotate);
+ var _appendChild = __webpack_require__(11);
+ var _appendChild2 = _interopRequireDefault(_appendChild);
+ function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : { default: obj };
+ }
+ var _utils = __webpack_require__(6);
+ var SIZE = 20;
+ /**
+ * This functions checks, if two annotations are at the same position an looks the same.
+ * @return boolean, true if same and false if not
+ */
+ function isAnnotationsPosEqual(annotationA, annotationB) {
+ switch (annotationA.type) {
+ case 'area':
+ return (
+ parseInt(annotationA.x) === parseInt(annotationB.x) &&
+ parseInt(annotationA.y) === parseInt(annotationB.y) &&
+ parseInt(annotationA.width) === parseInt(annotationB.width) &&
+ parseInt(annotationA.height) === parseInt(annotationB.height)
+ );
+ case 'drawing':
+ return (
+ annotationA.color === annotationB.color &&
+ JSON.stringify(annotationA.lines) ===
+ JSON.stringify(annotationB.lines) &&
+ parseInt(annotationA.width) === parseInt(annotationB.width)
+ );
+ case 'highlight':
+ case 'strikeout':
+ //strikeout and highlight cannot be shifted, so they are the same
+ return true;
+ case 'point':
+ return (
+ parseInt(annotationA.x) === parseInt(annotationB.x) &&
+ parseInt(annotationA.y) === parseInt(annotationB.y)
+ );
+ case 'textbox':
+ return (
+ parseInt(annotationA.x) === parseInt(annotationB.x) &&
+ parseInt(annotationA.y) === parseInt(annotationB.y) &&
+ parseInt(annotationA.width) === parseInt(annotationB.width) &&
+ parseInt(annotationA.height) === parseInt(annotationB.height) &&
+ annotationA.content === annotationB.content &&
+ annotationA.color === annotationB.color &&
+ parseInt(annotationA.size) === parseInt(annotationB.size)
+ );
+ default:
+ return false;
+ }
+ }
+ /**
+ * This function edits the SVG-Object of the annotation in the DOM
+ * @param {type} type type of annotation
+ * @param {type} node the annotation node
+ * @param {type} svg the outer svg
+ * @param {type} annotation the annotation object
+ * @returns {void}
+ */
+ function editAnnotationSVG(type, node, svg, annotation) {
+ if (['area', /*'highlight',*/ 'point', 'textbox'].indexOf(type) > -1) {
+ (function () {
+ var x = annotation.x;
+ var y = annotation.y;
+ if (type === 'point') {
+ x = annotation.x - SIZE / 4;
+ y = annotation.y - SIZE;
+ }
+
+ node.setAttribute('y', y);
+ node.setAttribute('x', x);
+ })();
+ } else if (type === 'drawing') {
+ (function () {
+ node.parentNode.removeChild(node);
+ (0, _appendChild2.default)(svg, annotation);
+ })();
+ }
+ }
+ /**
+ * This function synchronizes the annotations
+ * It calls itself 5 secs after the function finishes. So every 5+ seconds the annotations are updated.
+ * It loads only the annotations of the current shown page.
+ */
+ function loadNewAnnotations() {
+ //determine which page is shown, to only load these annotations.
+ var pageNumber = document.getElementById('currentPage').value;
+ var page = document.getElementById('pageContainer' + pageNumber);
+ if (page === null) {
+ setTimeout(loadNewAnnotations, 5000);
+ return;
+ }
+ var svg = page.querySelector('.annotationLayer');
+ var metadata = _utils.getMetadata(svg);
+ var viewport = metadata.viewport;
+ var documentId = metadata.documentId;
+ //Sometimes the page is not loaded yet, than try again in 5secs
+ if (isNaN(documentId) || documentId === null) {
+ setTimeout(loadNewAnnotations, 5000);
+ return;
+ }
+ //Get annotations from database to get the newest.
+ _PDFJSAnnotate2.default.getAnnotations(documentId, pageNumber).then(
+ function (data) {
+ var newAnnotations = [];
+ newAnnotations[pageNumber] = data.annotations;
+ var oldAnnotations = currentAnnotations.slice();
+ currentAnnotations[pageNumber] = newAnnotations[pageNumber];
+ var exists = false;
+ for (var annotationID in newAnnotations[pageNumber]) {
+ var annotation = newAnnotations[pageNumber][annotationID];
+ for (var oldAnnoid in oldAnnotations[pageNumber]) {
+ var oldAnno = oldAnnotations[pageNumber][oldAnnoid];
+ annotation.uuid = parseInt(annotation.uuid);
+ oldAnno.uuid = parseInt(oldAnno.uuid);
+ if (oldAnno !== undefined && annotation.uuid === oldAnno.uuid) {
+ if (!isAnnotationsPosEqual(annotation, oldAnno)) {
+ var node = document.querySelector(
+ '[data-pdf-annotate-id="' + oldAnno.uuid + '"]'
+ );
+ if (node !== null) {
+ editAnnotationSVG(
+ annotation.type,
+ node,
+ svg,
+ annotation
+ );
+ }
+ }
+ exists = true;
+ break;
+ } else if (
+ oldAnno.newAnno &&
+ isAnnotationsPosEqual(annotation, oldAnno)
+ ) {
+ //Annotation was just added and is the same in newAnnotations
+ //do Nothing
+ delete oldAnno.newAnno;
+ break;
+ }
+ }
+ if (!exists) {
+ //append annotation to svg
+ (0, _appendChild2.default)(svg, annotation, viewport);
+ }
+ exists = false;
+ }
+ var exists = false;
+ for (var oldAnnoid in oldAnnotations[pageNumber]) {
+ var oldAnno = oldAnnotations[pageNumber][oldAnnoid];
+ for (var annotationID in newAnnotations[pageNumber]) {
+ var annotation = newAnnotations[pageNumber][annotationID];
+ if (oldAnno.uuid == annotation.uuid) {
+ exists = true;
+ break;
+ }
+ }
+ if (!exists && !oldAnno.newAnno) {
+ var node = document.querySelector(
+ '[data-pdf-annotate-id="' + oldAnno.uuid + '"]'
+ );
+ if (node !== null) {
+ node.parentNode.removeChild(node);
+ }
+ }
+ exists = false;
+ }
+ //call this function to repeat in 5 secs
+ // setTimeout(loadNewAnnotations, 5000);
+ },
+ function (err) {
+ notification.addNotification({
+ message: M.util.get_string('error:getAnnotations', 'pdfannotator'),
+ type: 'error',
+ });
+ }
+ );
+ }
+ },
+ /*end of submodules of Module 2*/
+ ]);
+ }); //# sourceMappingURL=pdf-annotate.js.map
+ /* WEBPACK VAR INJECTION */
+ }).call(exports, __webpack_require__(3)(module));
+ },
+ /* 3 */
+ function (module, exports) {
+ module.exports = function (module) {
+ if (!module.webpackPolyfill) {
+ module.deprecate = function () {};
+ module.paths = [];
+ // module.parent = undefined by default
+ module.children = [];
+ module.webpackPolyfill = 1;
+ }
+ return module;
+ };
+ },
+ /* 4 */
+ function (module, exports) {
+ 'use strict';
+
+ Object.defineProperty(exports, '__esModule', {
+ value: true,
+ });
+ exports.default = initColorPicker;
+ // Color picker component
+ var COLORS = [
+ { hex: '#000000', name: 'Black' },
+ { hex: '#EF4437', name: 'Red' },
+ { hex: '#E71F63', name: 'Pink' },
+ { hex: '#8F3E97', name: 'Purple' },
+ { hex: '#65499D', name: 'Deep Purple' },
+ { hex: '#4554A4', name: 'Indigo' },
+ { hex: '#2083C5', name: 'Blue' },
+ { hex: '#35A4DC', name: 'Light Blue' },
+ { hex: '#09BCD3', name: 'Cyan' },
+ { hex: '#009688', name: 'Teal' },
+ { hex: '#43A047', name: 'Green' },
+ { hex: '#8BC34A', name: 'Light Green' },
+ { hex: '#FDC010', name: 'Yellow' },
+ { hex: '#F8971C', name: 'Orange' },
+ { hex: '#F0592B', name: 'Deep Orange' },
+ { hex: '#F06291', name: 'Light Pink' },
+ ];
+
+ function initColorPicker(el, value, onChange) {
+ function setColor(value) {
+ var fireOnChange = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
+
+ currentValue = value;
+ a.setAttribute('data-color', value);
+ a.style.background = value;
+ if (fireOnChange && typeof onChange === 'function') {
+ onChange(value);
+ }
+ closePicker();
+ }
+
+ function togglePicker() {
+ if (isPickerOpen) {
+ closePicker();
+ } else {
+ openPicker();
+ }
+ }
+
+ function closePicker() {
+ document.removeEventListener('keyup', handleDocumentKeyup);
+ if (picker && picker.parentNode) {
+ picker.parentNode.removeChild(picker);
+ }
+ isPickerOpen = false;
+ a.focus();
+ }
+
+ function openPicker() {
+ if (!picker) {
+ picker = document.createElement('div');
+ picker.style.background = '#fff';
+ picker.style.border = '1px solid #ccc';
+ picker.style.padding = '2px';
+ picker.style.position = 'absolute';
+ picker.style.width = '122px';
+ el.style.position = 'relative';
+
+ COLORS.map(createColorOption).forEach(function (c) {
+ c.style.margin = '2px';
+ c.onclick = function () {
+ // Select text/pen instead of cursor.
+ if (c.parentNode.parentNode.className === 'text-color') {
+ document.querySelector('#pdftoolbar button.text').click();
+ } else if (c.parentNode.parentNode.className === 'pen-color') {
+ document.querySelector('#pdftoolbar button.pen').click();
+ }
+ setColor(c.getAttribute('data-color'));
+ };
+ picker.appendChild(c);
+ });
+ }
+
+ document.addEventListener('keyup', handleDocumentKeyup);
+ el.appendChild(picker);
+ isPickerOpen = true;
+ }
+
+ function createColorOption(color) {
+ var e = document.createElement('a');
+ e.className = 'color';
+ e.setAttribute('href', 'javascript://');
+ e.setAttribute('title', color.name);
+ e.setAttribute('data-color', color.hex);
+ e.style.background = color.hex;
+ return e;
+ }
+
+ function handleDocumentKeyup(e) {
+ if (e.keyCode === 27) {
+ closePicker();
+ }
+ }
+
+ var picker = void 0;
+ var isPickerOpen = false;
+ var currentValue = void 0;
+ var a = createColorOption({ hex: value });
+ a.title = M.util.get_string('colorPicker', 'pdfannotator');
+ a.onclick = togglePicker;
+ el.appendChild(a);
+ setColor(value, false);
+ }
+ },
+ ]);
+ }); //require JQuery closed
+}
+
+function read_visibility_of_checkbox() {
+ var commentVisibility = 'public';
+ if (document.querySelector('#anonymousCheckbox').checked) {
+ commentVisibility = 'anonymous';
+ document.querySelector('#anonymousCheckbox').checked = false;
+ }
+
+ if (document.querySelector('#privateCheckbox') != null) {
+ if (document.querySelector('#privateCheckbox').checked) {
+ commentVisibility = 'private';
+ document.querySelector('#privateCheckbox').checked = false;
+ }
+ }
+
+ if (document.querySelector('#protectedCheckbox') != null) {
+ if (document.querySelector('#protectedCheckbox').checked) {
+ commentVisibility = 'protected';
+ document.querySelector('#protectedCheckbox').checked = false;
+ }
+ }
+ return commentVisibility;
}
/**
diff --git a/shared/locallib.js b/shared/locallib.js
index e260d8f..c27d2e3 100644
--- a/shared/locallib.js
+++ b/shared/locallib.js
@@ -82,12 +82,14 @@ function addDropdownNavigation(Y, __capabilities, __cmid) {
};
}
-
-function renderMathJax(node) {
+/***** Removing this function for Moodle 5 ****/
+/*function renderMathJax(node) {
var counter = 0;
let mathjax = function (node) {
if (typeof (MathJax) !== "undefined") {
- MathJax.Hub.Queue(['Typeset', MathJax.Hub, node]);
+ if (MathJax.Hub !== 'undefined') {
+ MathJax.Hub.Queue(['Typeset', MathJax.Hub, node]);
+ }
} else if (counter < 30) {
counter++;
setTimeout(mathjax, 100);
@@ -95,7 +97,7 @@ function renderMathJax(node) {
}
};
mathjax(node);
-}
+}*/
function fixCommentForm() {
if ($('#comment-list-form').hasClass('fixtool')) {
diff --git a/shared/overview.js b/shared/overview.js
index 80b3d15..275ea13 100644
--- a/shared/overview.js
+++ b/shared/overview.js
@@ -36,7 +36,7 @@ function startOverview(Y, __annotatorid, __cmid, __capabilities, __action) { //
}
shortenTextOverview();
- renderMathJax();
+ //renderMathJax();
/************************** 2. Function definitions **************************/
@@ -477,12 +477,14 @@ function startOverview(Y, __annotatorid, __cmid, __capabilities, __action) { //
});
});
}
-
- function renderMathJax() {
+/***** Removing this function for Moodle 5 ****/
+ /*function renderMathJax() {
var counter = 0;
let mathjax = function () {
if (typeof (MathJax) !== "undefined") {
- MathJax.Hub.Queue(['Typeset', MathJax.Hub]);
+ if (MathJax.Hub !== 'undefined') {
+ MathJax.Hub.Queue(['Typeset', MathJax.Hub]);
+ }
} else if (counter < 10) {
counter++;
setTimeout(mathjax, 200);
@@ -490,6 +492,6 @@ function startOverview(Y, __annotatorid, __cmid, __capabilities, __action) { //
}
};
mathjax();
- }
+ }*/
}
\ No newline at end of file
diff --git a/styles.css b/styles.css
index abd299b..051b629 100644
--- a/styles.css
+++ b/styles.css
@@ -261,17 +261,17 @@
.path-mod-pdfannotator .annotationLayer .choiceWidgetAnnotation select option {
padding: 0;
}
-
+
.path-mod-pdfannotator .annotationLayer .buttonWidgetAnnotation.radioButton input {
border-radius: 50%;
}
-
+
.path-mod-pdfannotator .annotationLayer .textWidgetAnnotation textarea {
font: message-box;
font-size: 9px;
resize: none;
}
-
+
.path-mod-pdfannotator .annotationLayer .textWidgetAnnotation input[disabled],
.path-mod-pdfannotator .annotationLayer .textWidgetAnnotation textarea[disabled],
.path-mod-pdfannotator .annotationLayer .choiceWidgetAnnotation select[disabled],
@@ -281,7 +281,7 @@
border: 1px solid transparent;
cursor: not-allowed;
}
-
+
.path-mod-pdfannotator .annotationLayer .textWidgetAnnotation input:hover,
.path-mod-pdfannotator .annotationLayer .textWidgetAnnotation textarea:hover,
.path-mod-pdfannotator .annotationLayer .choiceWidgetAnnotation select:hover,
@@ -338,13 +338,13 @@
top: 20%;
width: 50%;
}
-
+
.path-mod-pdfannotator .annotationLayer .textWidgetAnnotation input.comb {
font-family: monospace;
padding-left: 2px;
padding-right: 0;
}
-
+
.path-mod-pdfannotator .annotationLayer .textWidgetAnnotation input.comb:focus {
/*
* Letter spacing is placed on the right side of each character. Hence, the
@@ -400,7 +400,7 @@
margin-top: 2px;
padding-top: 2px;
}
-
+
.path-mod-pdfannotator .annotationLayer .richText > * {
white-space: pre-wrap;
}
@@ -476,7 +476,7 @@
.path-mod-pdfannotator .pdfViewer.singlePageView {
display: inline-block;
}
-
+
.path-mod-pdfannotator .pdfViewer.singlePageView .page {
margin: 0;
border: none;
@@ -534,7 +534,7 @@
.path-mod-pdfannotator .pdfViewer .page canvas[hidden] {
display: none;
}
-
+
.path-mod-pdfannotator .pdfViewer .page .loadingIcon {
position: absolute;
@@ -624,6 +624,11 @@ body {
margin: 0;
}
+.path-mod-pdfannotator #comment-wrapper button .icon {
+ color: #999;
+ margin-right: 0;
+}
+
@media only screen and (max-width: 991px) {
.path-mod-pdfannotator #content-wrapper,
.path-mod-pdfannotator #comment-wrapper {
@@ -791,6 +796,13 @@ body {
background-color: transparent;
}
+.path-mod-pdfannotator #comment-nav .spacer {
+ display: inline-block;
+ border-left: 1px solid #c1c1c1;
+ height: 34px;
+ margin: 0 5px -11px;
+}
+
.path-mod-pdfannotator .chat-message.questioncomment {
margin: 0 0 10px 0;
background-color: #c7ddf2;
@@ -801,6 +813,16 @@ body {
color: rgb(0, 84, 159);
}
+.path-mod-pdfannotator .chat-message.questions.questions-private:not(.page) {
+ background-color: #FDEFDF;
+ color: #e48312;
+}
+
+.path-mod-pdfannotator .chat-message.questioncomment.questions-private:not(.page) {
+ background-color: #FDEFDF;
+ color: #e48312;
+}
+
.path-mod-pdfannotator .chat-message.questions.page {
background-color: #dff0d8 !important;
border-color: #d0e9c6;
@@ -1278,4 +1300,88 @@ header, section, footer, aside, nav, main, article, figure {
.path-mod-pdfannotator #id_pdfannotator_content {
display: none !important;
+}
+
+.path-mod-pdfannotator .comment-visibility-button[data-active="true"]{
+ border-bottom: 2px solid #0f6cbf !important;
+}
+
+.path-mod-pdfannotator .comment-all[data-active="true"] {
+ border-bottom: 2px solid rgb(153,153,153) !important;
+}
+
+.path-mod-pdfannotator .comment-private[data-active="true"] {
+ border-bottom: 2px solid #e48312 !important;
+}
+
+.path-mod-pdfannotator .question-private-icon {
+ position: absolute;
+ top: 12px;
+ right: 16px;
+ width: 16px;
+ height: 16px;
+}
+
+.path-mod-pdfannotator .question-public-icon {
+ position: absolute;
+ top: 12px;
+ right: 16px;
+ width: 16px;
+ height: 16px;
+}
+
+.path-mod-pdfannotator .printannotations-dropdown-container {
+ position: relative;
+ display: inline-block;
+}
+
+.path-mod-pdfannotator .pdfannotator_print_dropdown {
+ position: relative;
+ display: inline-block;
+}
+
+.path-mod-pdfannotator .printAnnotationsOptionsContent {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ background-color: #eaeaea;
+ border: 1px solid #ccc;
+ min-width: 120px;
+ box-shadow: 0px 8px 16px rgba(0,0,0,0.2);
+ z-index: 1000;
+ display: flex;
+ flex-direction: column;
+}
+
+.path-mod-pdfannotator .toolbar button.pdfannotator_print {
+ background: none;
+ border: none;
+ text-align: left;
+ cursor: pointer;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.path-mod-pdfannotator .pdfannotator_print#pdfannotator_printannotations_button,
+.path-mod-pdfannotator .pdfannotator_print#pdfannotator_printannotations_buttonCSV {
+ padding: 8px;
+}
+
+.path-mod-pdfannotator .pdfannotator_print#pdfannotator_printannotations_button:hover,
+.path-mod-pdfannotator .pdfannotator_print#pdfannotator_printannotations_buttonCSV:hover {
+ background-color: lightgray;
+}
+
+.path-mod-pdfannotator .pdfannotator_print#pdfannotator_printannotations_button img,
+.path-mod-pdfannotator .pdfannotator_print#pdfannotator_printannotations_buttonCSV img {
+ margin-right: 8px;
+ margin-bottom: 2px;
+ vertical-align: middle;
+ width: 20px;
+ height: auto;
+}
+
+.path-mod-pdfannotator .printAnnotationsOptionsContent.hidden {
+ display: none;
}
\ No newline at end of file
diff --git a/templates/index.mustache b/templates/index.mustache
index 5f8bda3..d44c16a 100644
--- a/templates/index.mustache
+++ b/templates/index.mustache
@@ -80,9 +80,19 @@
{{/useprint}}
{{#useprintcomments}}
-
+
+
+
+
+
+
+
{{/useprintcomments}}