annotate_node-1.0.1-alpha1/js/annotate_node_annotator.js

js/annotate_node_annotator.js
/**
 * We add the buttons to each sentence/paragraph here as well as comparing
 * the annotation/comment with the original text and highlighting changes
 * with color.
 */

(function (Drupal, $, drupalSettings) {
    var asian_characters;
    var correction_mode;

    Drupal.behaviors.AnnotateNodeBehavior = {
    attach: function (context, settings) {
      asian_characters = drupalSettings.annotate_node.asian_characters;
      correction_mode = drupalSettings.annotate_node.correction_mode;
      // When the document loads see if the #pop div exists.  If so on an annotation template.
      // Create Poppers add color coded difference changes if config enabled them.
      // Start observer looking for new comments via Ajax CommentForm.
      $(context).find("#popup").once("onInitialLoadBehavior").each(function () {
          ('input.myCustom', context)
          createPopperAndSentenceIDs();
          if (correction_mode == "On"){
            stringDifference();
          }
          observer.observe(targetNode, config);
      });
    }
  };
    // Our buttons will open the CommentForm
    var buttonPopper = $('.popper-button');
    var popup = $('#popup');
    //Our popup  is the CommentForm to add annotations.  Should start hidden before button click.  Note we're using jQuery to show/hide/toggle.
    popup.hide();

/**
 * This will be called below if config is set to be Length Dependent and
 * when we need a string of the content of the node in order to get a word count
 * and thereby decide if should be broken up by paragraphs or sentences.
 */
/*
function get_text(el) {
    ret = "";
    var length = el.childNodes.length;
    for(var i = 0; i < length; i++) {
        var node = el.childNodes[i];
        if(node.nodeType != 8) {
            ret += node.nodeType != 1 ? node.nodeValue : get_text(node);
        }
    }
	console.log('ret is ' + ret);
    return ret;
}
*/

/**
 * When clicking each annotation/comment button, first capture it's ID number.  This is the ID of
 * the paragraph/sentence and we'll add this into a column in the database via a hidden field in CommentForm
 * to keep track of which paragraph/sentence each comment belongs to.
 */
    buttonPopper.click(function () {
      var buttonPopper = document.querySelector('#popper-' + this.id);
      var tooltipPopper = document.querySelector('#popup');
      var popperInstance = Popper.createPopper(buttonPopper, tooltipPopper,{
  placement: 'right',
    modifiers: [
    {
      name: 'offset',
      options: {
        offset: [110, 0],
      },
    },
  ],
                });
        //There is a field in the comment form hidden via css to hold the paragraph number this is attached to, populate it here.
        $('#edit-paragraph-number').val(this.id);

        // Prepopulate the text area of cke editor with the matching id from button if correction_mode is on.
        // note, cke has it's own method for this, can't just use jquery
        // https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editable.html#method-setData
        if (correction_mode == "On"){
            var txt = $('#sentence-' + this.id).text();
            CKEDITOR.instances['edit-comment-value'].setData(txt);
        }
        popup.toggle();
    });

/**
 * We're going to listen to the main div.  If it's altered, that means the Ajax CommentForm
 * added a appended a comment to a div.  That will trigger our function to compare comment/annotation
 * with original text and highlight changes if corrections is true in config.
 * Look at the html of the node to see there is a sentence div then a comments div below
 * with each comment being a child div of the latter with it's own ID.
 */
const targetNode = document.getElementById('content');

// Options for the observer (which mutations to observe)
const config = { attributes: false, childList: true, subtree: true };

// Callback function to execute when mutations are observed


const callback = function (mutationsList, observer) {
    //check if browser supports MutationObserver, if not, corrected version won't show until reloads the page.
    if (window.MutationObserver) {

    for(const mutation of mutationsList) {
        //This is triggered when CommentForm appends a new comment/annotation
        var migrationID = mutation.target.id;
        //Make sure the mutation happening is one of our comments being added.
        if (mutation.type === 'childList'  && migrationID.indexOf('comments-') != -1){
            popup.hide();

            //get # of children for this sentence/paragraph, divide by two because date is also a child
            var numberChildren = document.getElementById(migrationID).childElementCount / 2;

            // Find our new element entered by AJAX form
            // mutation.target.id will have the number of the sentence/paragraph we're on
            // and we attached '-temp' to the ID in the CommentForm, so piecing those together
            // can find and assign correct ID. This is where we're changing the comment ID we
            // had given via the append command in comment form. ID of comment is one greater
            // than number of children.
            var commentID = numberChildren - 1;
            document.getElementById('comment-' + migrationID.split('-')[1] + '-temp').id = 'comment-' + migrationID.split('-')[1] + '-' + commentID;

            // Add the correction color coded line if needed.

            //First get the new comment ID
            var targetComment = 'comment-' + migrationID.split('-')[1] + '-' + commentID;

            //Send the ID of the sentence and the targetComment to stringDifference to  show colored coded difference.
            var id = 'sentence-' + migrationID.split('-')[1];
            stringDifference(id, targetComment);

        }
      }
   }
 }

 // Create an observer instance linked to the callback function.
 // We're listening for changes to can trigger stringDifference if comment is added via Ajax form.
 // We strt this will the onInitialLoadBehavior
const observer = new MutationObserver(callback);

//Hide form if click anywhere outside of Popper (commment form) and not clicking the buttons.
$('body').on('click', function (e) {
    var buttonClicked = $(e.target).parents(".popper").length;
    var buttonImageClicked = $(e.target).parents(".annotate_submit_icon").length;
    var annotateNodeCommentFormClicked = $(e.target).parents("#popup").length;

    //if they're outside the comment form and not opening via the button, close the form.
    if ( !(buttonClicked > 0 ) && !(buttonImageClicked > 0) && !(annotateNodeCommentFormClicked > 0) ){
        popup.hide();
    }
});

/**
 * We are using the Popper js library, to place comment form within screen
 * relative to the button.  Here we create the unique IDs for those buttons.
 * We also add unique IDs to each sentence/paragraph.
 */

    function createPopperAndSentenceIDs() {
        var i = 1;
        $('.sentence').each(function () {

            var customID = 'sentence-' + String(i);
            try {

                $(this).attr('id', customID);
                //var reference = $('#sentence-' + String(i));
                var customPopperId = 'popper-' + String(i);
                $(this).find('.popper').attr('id', customPopperId);
                i++;

            } catch (e) {
                console.log('In createPopper' + e);
            }
        });
        return this;

    }

    /**
     * This places the corrected or annotated text (comment for drupal) below each sentence
     * or paragraph and highlight changes made in green or red for non-asian text.  Our
     * Javascript doesn't handle characters if more than one byte.
     *
     * If parameters were passed in, this function is being called upon closing the AJAX comment form,
     * otherwise it's being run via document.ready.
     */

    function stringDifference(id = null, targetComment = null) {

     //We've detected the change, don't want to trigger again when start corrections
      observer.disconnect();

      if (id == null) {
        $('.sentence').each(function () {
            var id = $(this).attr('id').replace(/sentence-/, '');
            var one = $('#sentence-' + id).text();
            $('#comments-' + id + ' p').each(function (i, obj) {
                var other = $('#comment-' + id + '-' + i).text();
                $('#comment-' + id + '-' + i).append('</br>');
                var color = '';
                if (other.trim()) {
                    var diff = Diff.diffWords(one, other);
                if (asian_characters == true || correction_mode == "Off"){
                    diff.forEach(function (part) {
                    });
                  } else{
                        diff.forEach(function (part) {
                        // green for additions, red for deletions
                        // grey for common parts
                        color = part.added ? 'green' :
                                part.removed ? 'red' : 'grey';
                        var span = $('<span />').addClass('corrected');
                        if (part.removed && part.value !== " ") {
                            var tempSpan = span;
                            span = $('<s/>').append(tempSpan);

                        }

                        span.css("color", color);
                        span.append(document
                                .createTextNode(part.value));

                        $('#comment-' + id + '-' + i).append(span);

                    });

                  }

                }
            });
        });
        $('<span>&nbsp;</span>').insertAfter('s');

      //start If statement if coming via AJAX submit, only adding one stringDifference if needed at all
      }else if (id != null && asian_characters == false && correction_mode == "On") {
        var one = $('#' + id).text();
        var other = $('#' + targetComment).text();

        $('#' + targetComment).append('</br>');
        var color = '';
        if (other.trim()) {
          var diff = Diff.diffWords(one, other);
                          diff.forEach(function (part) {
                        // green for additions, red for deletions
                        // grey for common parts
                        color = part.added ? 'green' :
                                part.removed ? 'red' : 'grey';
                        var span = $('<span />').addClass('corrected');
                        if (part.removed && part.value !== " ") {
                            var tempSpan = span;
                            span = $('<s/>').append(tempSpan);

                        }

                        span.css("color", color);
                        span.append(document
                                .createTextNode(part.value));

                        $('#' + targetComment).append(span);

                    });
        }

      }

      //Finished attaching the color coded correction.  Start listening again for new comments coming in via AJAX
      observer.observe(targetNode, config);
    }
})(Drupal, jQuery, drupalSettings);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc