Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Clear the cache in Tools → Preferences

For details and instructions about other browsers, see Wikipedia:Bypass your cache.

 /*global webkitSpeechRecognition */
(function() {
	'use strict';
	if(mw.config.values.wgAction!="edit"){return;}

var body = document.getElementById('wpTextbox1');
body.classList.add('speech-input');

	// check for support (webkit only)
	if (!('webkitSpeechRecognition' in window)) return;

	var talkMsg = 'ਪੰਜਾਬੀ ਵਿੱਚ ਬੋਲੋ';
	// seconds to wait for more input after last
  	var defaultPatienceThreshold = 6;

	function capitalize(str) {
		return str.charAt(0).toUpperCase() + str.slice(1);
	}

	var inputEls = document.getElementsByClassName('speech-input');

	[].forEach.call(inputEls, function(inputEl) {
		var patience = parseInt(inputEl.dataset.patience, 10) || defaultPatienceThreshold;
		var micBtn, micIcon, holderIcon, newWrapper, temptext;
		var shouldCapitalize = true;

		// gather inputEl data
		var nextNode = inputEl.nextSibling;
		var parent = inputEl.parentNode;
		var inputRightBorder = parseInt(getComputedStyle(inputEl).borderRightWidth, 10);
		var buttonSize = 0.8 * (inputEl.dataset.buttonsize || inputEl.offsetHeight);

		// default max size for textareas
		if (!inputEl.dataset.buttonsize && inputEl.tagName === 'TEXTAREA' && buttonSize > 26) {
			buttonSize = 26;
		}

		// create wrapper if not present
		var wrapper = inputEl.parentNode;
		if (!wrapper.classList.contains('si-wrapper')) {
			wrapper = document.createElement('div');
			wrapper.classList.add('si-wrapper');
			wrapper.appendChild(parent.removeChild(inputEl));
			newWrapper = true;
		}

		// create mic button if not present
		micBtn = wrapper.querySelector('.si-btn');
		if (!micBtn) {
			micBtn = document.createElement('button');
			micBtn.type = 'button';
			micBtn.classList.add('si-btn');
			micBtn.textContent = 'speech input';
			micIcon = document.createElement('span');
			holderIcon = document.createElement('span');
			micIcon.classList.add('si-mic');
			holderIcon.classList.add('si-holder');
			micBtn.appendChild(micIcon);
			micBtn.appendChild(holderIcon);
			wrapper.appendChild(micBtn);

			// size and position mic and input
			micBtn.style.cursor = 'pointer';
			micBtn.style.top = 0.125 * buttonSize + 'px';
			micBtn.style.height = micBtn.style.width = buttonSize + 'px';
			inputEl.style.paddingRight = buttonSize - inputRightBorder + 'px';
		}
	   //create temp text, if not created	
	   temptext = wrapper.querySelector('.si-txt');
       if(!temptext){temptext = document.createElement('div');
			temptext.id="tscript";
			temptext.classList.add('si-txt');
			wrapper.appendChild(temptext);
	     }
			
		// append wrapper where input was
		if (newWrapper) parent.insertBefore(wrapper, nextNode);

		// setup recognition
		var prefix = '';
		var isSentence;
		var recognizing = false;
		var timeout;
		var oldPlaceholder = null;
		var recognition = new webkitSpeechRecognition();
		recognition.continuous = true;
		recognition.interimResults = true;

		// if lang attribute is set on field use that
		// (defaults to use the lang of the root element)
		if (inputEl.lang) recognition.lang = inputEl.lang;

		function restartTimer() {
			timeout = setTimeout(function() {
				recognition.stop();
			}, patience * 1000);
		}

		recognition.onstart = function() {
			oldPlaceholder = inputEl.placeholder;
			inputEl.placeholder = inputEl.dataset.ready || talkMsg;
			recognizing = true;
			micBtn.classList.add('listening');
			restartTimer();
		};

		recognition.onend = function() {
			recognizing = false;
			clearTimeout(timeout);
      var textcontent=inputEl.value;
			micBtn.classList.remove('listening');
			if (oldPlaceholder !== null) inputEl.placeholder = oldPlaceholder;

			// If the <input> has data-instant-submit and a value,
			if (inputEl.dataset.instantSubmit !== undefined && textcontent) {
				// submit the form it's in (if it is in one).
				if (inputEl.form) inputEl.form.submit();
			}
		};

		recognition.onresult = function(event) {
			clearTimeout(timeout);
//console.log(event);
			// get SpeechRecognitionResultList object
			var resultList = event.results;
      
			// go through each SpeechRecognitionResult object in the list
			var finalTranscript = '';
			var interimTranscript = '';
			for (var i = event.resultIndex; i < resultList.length; ++i) {
				var result = resultList[i];
//([{confidence: 0.009999999776482582, transcript: " சென்ற"},isFinal: false, length: 1]}


				// get this result's first SpeechRecognitionAlternative object
				var firstAlternative = result[0];

				if (result.isFinal) {
					finalTranscript = firstAlternative.transcript;          
				} else {
					interimTranscript += firstAlternative.transcript;
				}
			}

			// capitalize transcript if start of new sentence
			var transcript = finalTranscript || interimTranscript;
			transcript = !prefix || isSentence ? capitalize(transcript) : transcript;
      
      //when prefix is empty, pick the realtime prefix
      if (prefix==undefined) {prefix= getpre_fix(inputEl).trim();}
      
      if(inputEl.constructor.name =="HTMLDivElement")
        {inputEl.innerText=prefix + transcript ;
        setEndOfContenteditable(inputEl);}
			// append transcript to cached input value     
			else{//inputEl.value= prefix + transcript;
		var curPos = inputEl.selectionStart; 
//		console.log(curPos);
// setting the updated value in the text area


			}
      
      
     
			// set cursur and scroll to end
			//inputEl.focus();
		/*	if(prefix.length>curPos)
			if (inputEl.tagName === 'INPUT') {
				inputEl.scrollLeft = inputEl.scrollWidth;
			} else {
				inputEl.scrollTop = inputEl.scrollHeight;
			}
 */
      
      //To append the sentence. when it is final. clear the prefix cache
      if (result.isFinal) {transcript=" "+transcript;
      inputEl.value=prefix.slice(0,curPos)+transcript+prefix.slice(curPos);
 var caretPos = curPos + transcript.length;
    inputEl.setSelectionRange(caretPos, caretPos);     
                           prefix= undefined;
      	document.getElementById("tscript").textContent="";
      }
      else{document.getElementById("tscript").textContent=transcript;}
     
			restartTimer();
		}
		

		micBtn.addEventListener('click', function(event) {
			event.preventDefault();

			// stop and exit if already going
			if (recognizing) {
				recognition.stop();
				return;
			}
      
      
          prefix= getpre_fix(inputEl);
      /*
      var textcontent = "";
      if(inputEl.constructor.name =="HTMLDivElement")
      {textcontent=inputEl.innerText;} else{textcontent=inputEl.value;}
      //console.log(textcontent);
			// Cache current input value which the new transcript will be appended to
			var endsWithWhitespace = textcontent.slice(-1).match(/\s/);
			prefix = !textcontent || endsWithWhitespace ? textcontent : textcontent + ' ';*/

			// check if value ends with a sentence
			isSentence = prefix.trim().slice(-1).match(/[\.\?\!]/);

			// restart recognition
			recognition.start();
		}, false);
	});
})();
  
function getpre_fix(inputEl)
  {
      var textcontent = "";
      if(inputEl.constructor.name =="HTMLDivElement")
      {textcontent=inputEl.innerText;} else{textcontent=inputEl.value;}
      //console.log(textcontent);
			// Cache current input value which the new transcript will be appended to
			var endsWithWhitespace = textcontent.slice(-1).match(/\s/);
			pre_fix = !textcontent || endsWithWhitespace ? textcontent : textcontent + ' ';
    return pre_fix;
}
  
  function setEndOfContenteditable(contentEditableElement)
{
    var range,selection;
    if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
    {
        range = document.createRange();//Create a range (a range is a like the selection but invisible)
        range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
        selection = window.getSelection();//get the selection object (allows you to change selection)
        selection.removeAllRanges();//remove any selections already made
        selection.addRange(range);//make the range you have just created the visible selection
    }
    else if(document.selection)//IE 8 and lower
    { 
        range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
        range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
        range.select();//Select the range (make it the visible selection
    }
}