<commit_before>var
	util = require('enyo/utils'),
	kind = require('enyo/kind'),
	platform = require('enyo/platform'),
	TextArea = require('moonstone/RichText');

module.exports = kind({
	name: "smarttextarea",
	kind: TextArea,
	classes: "twist-text",
	handlers: {
		onkeypress: 'keyPressed',
		onkeydown: 'keyDown',
		oninput: 'inputChange'
	},
	events: {
		onValidate: ''
	},
	published: {
		tags: []
	},

	create: function() {
		this.inherited(arguments);

		this.replaceMode = false;
		this.replaceValue = "";
	},

	rendered: function() {
		this.inherited(arguments);

		appendNode(this, "twist-in-text", "&nbsp;");
	},

	inputChange: function(ctrl, e) {
		var newSize = this.getRawtext().length;
		if (!newSize) {
			// HACK: Remove all dummy text (BR, ...) when text is empty
			this.reset();
		}
	},

	keyDown: function(ctrl, e) {
		// If TAB press in hashtag mode, replace by current selection
		if (e.keyCode == 9 && this.replaceMode) {
			this.removeSelection();
			e.preventDefault();
		}

		// ENTER key validate the twist
		else if (e.keyCode == 13) {
			this.doValidate();
			e.preventDefault();
			return;
		}
	},

	keyPressed: function(ctrl, e){
		// Ignore BACK
		if (e.charCode == 0) {
			return;
		}

		// ENTER key validate the twist
		else if (e.charCode == 13) {
			this.doValidate();
			e.preventDefault();
			return;
		}

		// In hashtag mode, wait end character
		var selection = this.getSelection();
		var hashtagMode = this.replaceMode || isInHashtag(selection);
		var char = String.fromCharCode(e.charCode);
		if (hashtagMode) {
			if (!char.match(/[a-zA-Z_]/i)) {
				// Leave hashtag mode
				if (e.charCode == 32) {
					char = "&nbsp;"
				}
				if (this.replaceMode) {
					selection.deleteFromDocument();
				}
				appendNode(this, "twist-in-text", char);
				this.replaceMode = false;
				this.replaceValue = '';
				e.preventDefault();
				return;
			} else {
				// Intellisense proposal
				var tags = this.tags;
				var current;
				if (this.replaceMode) {
					current = this.replaceValue+char.toLowerCase();
				} else {
				 	current = (getRawSelection(selection)+char).toLowerCase();
				}
				for (var i = 0 ; i < tags.length ; i++) {
					if (tags[i].indexOf(current) == 0) {
						var delta = platform.firefox ? -this.replaceValue.length : 1; // HACK: Firefox handle selection differently
						this.insertAtCursor(tags[i].substr(current.length-1));
						selection.extend(selection.anchorNode, current.length+delta);
						this.replaceMode = true;
						this.replaceValue = current;
						e.preventDefault();
						break;
					}
				}
			}
		} else {
			// # key enter in hashtag mode
			if (e.charCode == 35) {
				appendNode(this, "twist-tag-in-text", "#");
				e.preventDefault();
				return;
			}
		}
	},

	getRawtext: function() {
		var root = this.hasNode();
		if (!root) {
			return '';
		}
		var nodes = root.childNodes;
		var rawtext = '';
		for (var i = 0 ; i < nodes.length ; i++) {
			rawtext += nodes[i].innerText;
		}
		return rawtext;
	},

	reset: function() {
		var root = this.hasNode();
		if (!root) {
			return;
		}
		while (root.firstChild) {
			root.removeChild(root.firstChild);
		}
		appendNode(this, "twist-in-text", "&nbsp;");
	}
});


// Private: Detect if the current selection is in hashtag mode
function isInHashtag(selection) {
	if (!selection || !selection.anchorNode || !selection.anchorNode.parentNode) {
		return false;
	}
	if (selection.anchorNode.className == "twist-tag-in-text") {<commit_msg>Remove newline in text, trim text<commit_after>var
	util = require('enyo/utils'),
	kind = require('enyo/kind'),
	platform = require('enyo/platform'),
	TextArea = require('moonstone/RichText');

module.exports = kind({
	name: "smarttextarea",
	kind: TextArea,
	classes: "twist-text",
	handlers: {
		onkeypress: 'keyPressed',
		onkeydown: 'keyDown',
		oninput: 'inputChange'
	},
	events: {
		onValidate: ''
	},
	published: {
		tags: []
	},

	create: function() {
		this.inherited(arguments);

		this.replaceMode = false;
		this.replaceValue = "";
	},

	rendered: function() {
		this.inherited(arguments);

		appendNode(this, "twist-in-text", "&nbsp;");
	},

	inputChange: function(ctrl, e) {
		var newSize = this.getRawtext().length;
		if (!newSize) {
			// HACK: Remove all dummy text (BR, ...) when text is empty
			this.reset();
		}
	},

	keyDown: function(ctrl, e) {
		// If TAB press in hashtag mode, replace by current selection
		if (e.keyCode == 9 && this.replaceMode) {
			this.removeSelection();
			e.preventDefault();
		}

		// ENTER key validate the twist
		else if (e.keyCode == 13) {
			this.doValidate();
			e.preventDefault();
			return;
		}
	},

	keyPressed: function(ctrl, e){
		// Ignore BACK
		if (e.charCode == 0) {
			return;
		}

		// ENTER key validate the twist
		else if (e.charCode == 13) {
			this.doValidate();
			e.preventDefault();
			return;
		}

		// In hashtag mode, wait end character
		var selection = this.getSelection();
		var hashtagMode = this.replaceMode || isInHashtag(selection);
		var char = String.fromCharCode(e.charCode);
		if (hashtagMode) {
			if (!char.match(/[a-zA-Z_]/i)) {
				// Leave hashtag mode
				if (e.charCode == 32) {
					char = "&nbsp;"
				}
				if (this.replaceMode) {
					selection.deleteFromDocument();
				}
				appendNode(this, "twist-in-text", char);
				this.replaceMode = false;
				this.replaceValue = '';
				e.preventDefault();
				return;
			} else {
				// Intellisense proposal
				var tags = this.tags;
				var current;
				if (this.replaceMode) {
					current = this.replaceValue+char.toLowerCase();
				} else {
				 	current = (getRawSelection(selection)+char).toLowerCase();
				}
				for (var i = 0 ; i < tags.length ; i++) {
					if (tags[i].indexOf(current) == 0) {
						var delta = platform.firefox ? -this.replaceValue.length : 1; // HACK: Firefox handle selection differently
						this.insertAtCursor(tags[i].substr(current.length-1));
						selection.extend(selection.anchorNode, current.length+delta);
						this.replaceMode = true;
						this.replaceValue = current;
						e.preventDefault();
						break;
					}
				}
			}
		} else {
			// # key enter in hashtag mode
			if (e.charCode == 35) {
				appendNode(this, "twist-tag-in-text", "#");
				e.preventDefault();
				return;
			}
		}
	},

	getRawtext: function() {
		var root = this.hasNode();
		if (!root) {
			return '';
		}
		var nodes = root.childNodes;
		var rawtext = '';
		for (var i = 0 ; i < nodes.length ; i++) {
			rawtext += nodes[i].innerText;
		}
		rawtext = rawtext.replace('\n', ' ').trim();
		return rawtext;
	},

	reset: function() {
		var root = this.hasNode();
		if (!root) {
			return;
		}
		while (root.firstChild) {
			root.removeChild(root.firstChild);
		}
		appendNode(this, "twist-in-text", "&nbsp;");
	}
});


// Private: Detect if the current selection is in hashtag mode
function isInHashtag(selection) {
	if (!selection || !selection.anchorNode || !selection.anchorNode.parentNode) {
		return false;
	}
	if (selection.anchorNode.className == "twist-tag-in-text") {
{'fraction_non_alphanumeric': 0.1605641829320416, 'fraction_numerical': 0.004274113121527283, 'mean_word_length': 3.0114285714285716, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6569355', 'n_tokens_mistral': 2896, 'n_tokens_neox': 2421, 'n_words': 540}