Advertisement
Guest User

DashedSentenceRepeat

a guest
Mar 13th, 2021
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* This software is licensed under a BSD license; see the LICENSE file for details. */
  2.  
  3. function boolToInt(x) { if (x) return 1; else return 0; }
  4.  
  5. define_ibex_controller({
  6. name: "DashedSentenceRepeat",
  7.  
  8. jqueryWidget: {
  9.     _init: function() {
  10.         this.cssPrefix = this.options._cssPrefix;
  11.         this.utils = this.options._utils;
  12.         this.finishedCallback = this.options._finishedCallback;
  13.     if (this.utils.getValueFromPreviousElement("failed")) {
  14.         this.finishedCallback(null);
  15.     } else {
  16.         if (typeof(this.options.s) == "string") {
  17.             // replace all linebreaks (and surrounding space) with 'space-return-space'
  18.             var inputString = this.options.s.replace(/\s*[\r\n]\s*/g, " \r ");
  19.             this.words = inputString.split(/[ \t]+/);
  20.         } else {
  21.             assert_is_arraylike(this.options.s, "Bad value for 's' option of DashedSentence.");
  22.             this.words = this.options.s;
  23.         }
  24.         this.mode = dget(this.options, "mode", "self-paced reading");
  25.         assert(this.mode == "self-paced reading" || this.mode == "speeded acceptability",
  26.                "Value of 'mode' option for DashedSentence controller must be either " +
  27.                "'self-paced reading' or 'speeded acceptability'.");
  28.         this.display = dget(this.options, "display", "dashed");
  29.         this.blankText = dget(this.options, "blankText", "\u2014\u2014"/*mdash*/);
  30.         this.wordTime = dget(this.options, "wordTime", this.display == "in place" ? 400 : 300); // Only for speeded accpetability.
  31.         this.wordPauseTime = dget(this.options, "wordPauseTime", this.display == "in place" ? 0 : 100); // Ditto.
  32.         this.showAhead = dget(this.options, "showAhead", true);
  33.         this.showBehind = dget(this.options, "showBehind", true);
  34.         assert(this.display == "dashed" || this.display == "in place",
  35.                "Value of 'display' option for DashedSentence controller must be either " +
  36.                "'dashed' (default) or 'in place'.");
  37.  
  38.         this.currentWord = 0;
  39.  
  40.         // Is there a "stopping point" specified?
  41.         this.stoppingPoint = this.words.length;
  42.         for (var i = 0; i < this.words.length; ++i) {
  43.             if (stringStartsWith("@", this.words[i])) {
  44.                 this.words[i] = this.words[i].substring(1);
  45.                 this.stoppingPoint = i + 1;
  46.                 break;
  47.             }
  48.         }
  49.  
  50.         this.hideUnderscores = dget(this.options, "hideUnderscores", true);
  51.         if (this.hideUnderscores) {
  52.             this.words = $.map(this.words, function(word) { return word.replace(/_/g, ' ') });
  53.         }
  54.  
  55.         this.mainDiv = $("<div>");
  56.         this.element.append(this.mainDiv);
  57.  
  58.         this.background = this.element.css('background-color') || "white";
  59.         this.isIE7;
  60.         /*@cc_on this.isIE = true; @*/
  61.         if (this.isIE)
  62.             this.background = "white";
  63.  
  64.         // Defaults.
  65.         this.unshownBorderColor = dget(this.options, "unshownBorderColor", "#9ea4b1");
  66.         this.shownBorderColor = dget(this.options, "shownBorderColor", "black");
  67.         this.unshownWordColor = dget(this.options, "unshownWordColor", this.background);
  68.         this.shownWordColor = dget(this.options, "shownWordColor", "black");
  69.  
  70.         // Precalculate MD5 of sentence.
  71.         this.sentenceDescType = dget(this.options, "sentenceDescType", "literal");
  72.         assert(this.sentenceDescType == "md5" || this.sentenceDescType == "literal", "Bad value for 'sentenceDescType' option of DashedSentence.");
  73.         if (this.sentenceDescType == "md5") {
  74.             var canonicalSentence = this.words.join(' ');
  75.             this.sentenceDesc = hex_md5(canonicalSentence);
  76.         }
  77.         else {
  78.         if (typeof(this.options.s) == "string")
  79.         this.sentenceDesc = csv_url_encode(this.options.s);
  80.         else
  81.         this.sentenceDesc = csv_url_encode(this.options.s.join(' '));
  82.         }
  83.  
  84.         this.mainDiv.addClass(this.cssPrefix + "sentence");
  85.  
  86.         this.resultsLines = [];
  87.         if (this.mode == "self-paced reading") {
  88.             // Don't want to be allocating arrays in time-critical code.
  89.             this.sprResults = [];
  90.             for (var i = 0; i < this.words.length; ++i)
  91.                 this.sprResults[i] = new Array(2);
  92.         }
  93.         this.previousTime = null;
  94.  
  95.         if (this.display == "in place") {
  96.             this.wordSpan = $(document.createElement("span")).text(this.blankText);
  97.             if (conf_centerItems) {
  98.                 this.mainDiv.css('text-align', 'center');
  99.                 this.wordSpan.css('text-align', 'center');
  100.             }
  101.             this.mainDiv.append(this.wordSpan);
  102.  
  103.             this.blankWord = this.blankWord_inplace;
  104.             this.showWord = this.showWord_inplace;
  105.         }
  106.         else { // dashed
  107.             this.blankWord = this.blankWord_dashed;
  108.             this.showWord = this.showWord_dashed;
  109.  
  110.             this.wordISpans = []; // Inner spans.
  111.             this.wordOSpans = []; // Outer spans.
  112.             this.owsnjq = []; // 'outer word spans no jQuery'.
  113.             this.iwsnjq = []; // 'inner word spans no jQuery'.
  114.             for (var j = 0; j < this.words.length; ++j) {
  115.                 if ( this.words[j] == "\r" ) {
  116.                     this.mainDiv.append('<br/>');
  117.  
  118.                     if (j <= this.stoppingPoint)
  119.                         this.stoppingPoint--;
  120.                    
  121.                     continue;
  122.                 }
  123.  
  124.                 var ispan;
  125.                 var ospan = $(document.createElement("span"))
  126.                             .addClass(this.cssPrefix + 'ospan')
  127.                             .append(ispan = $(document.createElement("span"))
  128.                                             .addClass(this.cssPrefix + 'ispan')
  129.                                             .text(this.words[j]));
  130.                 if (! this.showAhead)
  131.                     ospan.css('border-color', this.background);
  132.                 this.mainDiv.append(ospan);
  133.                 if (j + 1 < this.words.length)
  134.                     this.mainDiv.append("&nbsp; ");
  135.                 this.wordISpans.push(ispan);
  136.                 this.wordOSpans.push(ospan);
  137.                 this.iwsnjq.push(ispan[0]);
  138.                 this.owsnjq.push(ospan[0]);
  139.             }
  140.         }
  141.  
  142.         if (this.mode == "speeded acceptability") {
  143.             this.showWord(0);
  144.             var t = this;
  145.             function wordTimeout() {
  146.                 t.blankWord(t.currentWord);
  147.                 ++(t.currentWord);
  148.                 if (t.currentWord >= t.stoppingPoint)
  149.                     t.finishedCallback([[["Sentence (or sentence MD5)", t.sentenceDesc]]]);
  150.                 else
  151.                     t.utils.setTimeout(wordPauseTimeout, t.wordPauseTime);
  152.             }
  153.             function wordPauseTimeout() {
  154.                 t.showWord(t.currentWord);
  155.                 t.utils.clearTimeout(wordPauseTimeout);
  156.                 t.utils.setTimeout(wordTimeout, t.wordTime);
  157.             }
  158.             this.utils.setTimeout(wordTimeout, this.wordTime);
  159.         }
  160.         else if (this.mode == "self-paced reading") {
  161.             var t = this;
  162.             // Inlining this to minimize function calls in code for updating screen after space is pressed.
  163. /*            function goToNext(time) {
  164.                 t.recordSprResult(time, t.currentWord);
  165.  
  166.                 if (t.currentWord - 1 >= 0)
  167.                     t.blankWord(t.currentWord - 1);
  168.                 if (t.currentWord < t.stoppingPoint)
  169.                     t.showWord(t.currentWord);
  170.                 ++(t.currentWord);
  171.                 if (t.currentWord > t.stoppingPoint) {
  172.                     t.processSprResults();
  173.                     t.finishedCallback(t.resultsLines);
  174.                 }
  175.  
  176.                 return false;
  177.             }*/
  178.  
  179.             this.safeBind($(document), 'keydown', function(e) {
  180.                 var time = new Date().getTime();
  181.                 var code = e.keyCode;
  182.  
  183.                 if (code == 32) {
  184.                     // *** goToNext() ***
  185. //                    t.recordSprResult(time, t.currentWord);
  186.                     var word = t.currentWord;
  187.                     if (word > 0 && word <= t.stoppingPoint) {
  188.                         var rs = t.sprResults[word-1];
  189.                         rs[0] = time;
  190.                         rs[1] = t.previousTime;
  191.                     }
  192.                     t.previousTime = time;
  193.  
  194.                     if (t.currentWord - 1 >= 0)
  195.                         t.blankWord(t.currentWord - 1);
  196.                     if (t.currentWord < t.stoppingPoint)
  197.                         t.showWord(t.currentWord);
  198.                     ++(t.currentWord);
  199.                     if (t.currentWord > t.stoppingPoint) {
  200.                         t.processSprResults();
  201.                         t.finishedCallback(t.resultsLines);
  202.                     }
  203.                     return false;
  204.                     // ***
  205.                 }
  206.                 else {
  207.                     return true;
  208.                 }
  209.             });
  210.  
  211.             // For iPhone/iPod touch -- add button for going to next word.
  212.             if (isIPhone) {
  213.                 var btext = dget(this.options, "iPhoneNextButtonText", "next");
  214.                 var next = $("<div>")
  215.                            .addClass(this.cssPrefix + "iphone-next")
  216.                            .text(btext);
  217.                 this.element.append(next);
  218.                 next.click(function () {
  219.                     var time = new Date().getTime();
  220.  
  221.                     // *** goToNext() ***
  222.                     //t.recordSprResult(time, t.currentWord);
  223.                     var word = t.currentWord;
  224.                     if (word > 0 && word <= t.stoppingPoint) {
  225.                         var rs = t.sprResults[word-1];
  226.                         rs[0] = time;
  227.                         rs[1] = t.previousTime;
  228.                     }
  229.                     t.previousTime = time;
  230.  
  231.                     if (t.currentWord - 1 >= 0)
  232.                         t.blankWord(t.currentWord - 1);
  233.                     if (t.currentWord < t.stoppingPoint)
  234.                         t.showWord(t.currentWord);
  235.                     ++(t.currentWord);
  236.                     if (t.currentWord > t.stoppingPoint) {
  237.                         t.processSprResults();
  238.                         t.finishedCallback(t.resultsLines);
  239.                     }
  240.  
  241.                     return false;
  242.                     // ***
  243.                 });
  244.             }
  245.     }
  246.  
  247.        
  248.         }
  249.     },
  250.  
  251.     // Not using JQuery in these two methods just in case it slows things down too much.
  252.     // NOTE: [0] subscript gets DOM object from JQuery selector.
  253.     blankWord_dashed: function(w) {
  254.         if (this.currentWord <= this.stoppingPoint) {
  255.             this.owsnjq[w].style.borderColor = this.unshownBorderColor;
  256.             this.iwsnjq[w].style.visibility = "hidden";
  257.             if (! this.showBehind)
  258.                 this.owsnjq[w].style.borderColor = this.background;
  259.         }
  260.     },
  261.     showWord_dashed: function(w) {
  262.         if (this.currentWord < this.stoppingPoint) {
  263.             if (this.showAhead || this.showBehind)
  264.                 this.owsnjq[w].style.borderColor = this.shownBorderColor;
  265.             this.iwsnjq[w].style.visibility = "visible";
  266.         }
  267.     },
  268.  
  269.     blankWord_inplace: function (w) {
  270.         if (this.wordPauseTime > 0 && this.currentWord <= this.stoppingPoint) {
  271.             this.wordSpan.empty();
  272.         }
  273.     },
  274.     showWord_inplace: function (w) {
  275.         if (this.currentWord < this.stoppingPoint) {
  276.             this.wordSpan.text(this.words[this.currentWord]);
  277.         }
  278.     },
  279.  
  280.     // Inlining this now.
  281.     /*recordSprResult: function(time, word) {
  282.         if (word > 0 && word < this.stoppingPoint) {
  283.             var rs = this.sprResults[word-1];
  284.             rs[0] = time;
  285.             rs[1] = this.previousTime;
  286.         }
  287.         this.previousTime = time;
  288.     },*/
  289.  
  290.     processSprResults: function () {
  291.         var nonSpaceWords = [];
  292.         for (var i = 0; i < this.words.length; ++i) {
  293.             if ( this.words[i] != "\r" )
  294.                 nonSpaceWords.push(this.words[i]);
  295.         }
  296.  
  297.         for (var i = 0; i < nonSpaceWords.length; ++i) {
  298.             this.resultsLines.push([
  299.                 ["Word number", i+1],
  300.                 ["Word", csv_url_encode(nonSpaceWords[i])],
  301.                 ["Reading time", this.sprResults[i][0] - this.sprResults[i][1]],
  302.                 ["Newline?", (! this.display == "in place") &&
  303.                              boolToInt(((i+1) < this.wordOSpans.length) &&
  304.                              (this.wordOSpans[i].offset().top != this.wordOSpans[i+1].offset().top))],
  305.                 ["Sentence (or sentence MD5)", this.sentenceDesc]
  306.             ]);
  307.         }
  308.     }
  309. },
  310.  
  311. properties: {
  312.     obligatory: ["s"],
  313.     htmlDescription: function (opts) {
  314.         return $(document.createElement("div")).text(opts.s);
  315.     }
  316. }
  317. });
  318.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement