<commit_before>/// <reference path="../data/Dictionary.ts"/>
/// <reference path="InputTag.ts"/>
/// <reference path="ButtonTag.ts"/>
/// <reference path="SelectTag.ts"/>
/// <reference path="OptionTag.ts"/>
/// <reference path="../ConversationalForm.ts"/>

// basic tag from form logic
// types:
// radio
// text
// email
// tel
// password
// checkbox
// radio
// select
// button


// namespace
namespace cf {
	// interface
	export interface ITag{
		domElement?: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement,
		type: string,
		name: string,
		title: string,
		question: string,
		errorMessage:string,
		setTagValueAndIsValid(value: FlowDTO):boolean;

		value:string;
	}

	export interface ITagOptions{
		domElement?: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement,
		questions?: Array<string>,
		label?: string,
		validationCallback?: (value: string) => boolean,// can also be set through cf-validation attribute
	}

	// class
	export class Tag implements ITag {
		public domElement: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement;
		
		protected defaultValue: string | number;

		private errorMessages: Array<string>;
		private pattern: RegExp;
		private _title: string;

		private validationCallback?: (value: string) => boolean; // can also be set through cf-validation attribute.
		private questions: Array<string>; // can also be set through cf-questions attribute.

		public get type (): string{
			return this.domElement.getAttribute("type");
		}

		public get name (): string{
			return this.domElement.getAttribute("name");
		}
		
		public get title (): string{
			if(!this._title){
				this._title = this.domElement.getAttribute("title");
			}

			return this._title;
		}

		public get value (): string{
			return this.domElement.value;
		}

		public get question():string{
			if(!this.questions){
				this.findLabelAndSetQuestions();
			}

			return this.questions[Math.floor(Math.random() * this.questions.length)];
		}

		public get errorMessage():string{
			if(!this.errorMessages){
				// custom tag error messages
				if(this.domElement.getAttribute("cf-error")){
					this.errorMessages = this.domElement.getAttribute("cf-error").split("|");
				}else{
					this.errorMessages = [Dictionary.get("input-placeholder-error")];
				}
			}
			return this.errorMessages[Math.floor(Math.random() * this.errorMessages.length)];
		}

		constructor(options: ITagOptions){
			if(!Tag.isTagValid(options.domElement)){
				return;
			}

			this.domElement = options.domElement;

			// questions array
			if(options.questions)
				this.questions = options.questions;

			
			// custom tag validation
			if(this.validationCallback){
				this.validationCallback = options.validationCallback;
			}else if(this.domElement.getAttribute("cf-validation")){
				// set it through an attribute, danger land with eval
				this.validationCallback = eval(this.domElement.getAttribute("cf-validation"));
			}

			// reg ex pattern is set on the Tag, so use it in our validation
			if(this.domElement.getAttribute("pattern"))
				this.pattern = new RegExp(this.domElement.getAttribute("pattern"));

			// default value of Tag
			this.defaultValue = this.domElement.value;

			if(this.type != "group"){
				console.log('Tag registered:', this.type);
			}
		}

		public static isTagValid(element: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement):boolean{
			if(element.getAttribute("type") === "hidden")
				return false;

			if(element.style.display === "none")
				return false;
			
			if(element.style.visibility === "hidden")
				return false;

			if(element.tagName.toLowerCase() == "option" && element.innerText.length > 1){
				return true;
			}
		
			if(element.tagName.toLowerCase() == "select")
				return true
			else
				return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
		}

		public static createTag(options: ITagOptions): ITag{
			const element: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement = options.domElement;
			if(Tag.isTagValid(element)){
				// ignore hidden tags
				let tag: ITag;
				if(element.tagName.toLowerCase() == "input"){
					tag = new InputTag({
						domElement: element
						// validationCallback
						// questions: Array<String>
					});
				}else if(element.tagName.toLowerCase() == "select"){
					tag = new SelectTag({
						domElement: element
						// validationCallback
						// questions: Array<String>
					});
				}else if(element.tagName.toLowerCase() == "button"){
					tag = new ButtonTag({
						domElement: element
						// validationCallback
						// questions: Array<String>
					});<commit_msg>fix: blank option tag<commit_after>/// <reference path="../data/Dictionary.ts"/>
/// <reference path="InputTag.ts"/>
/// <reference path="ButtonTag.ts"/>
/// <reference path="SelectTag.ts"/>
/// <reference path="OptionTag.ts"/>
/// <reference path="../ConversationalForm.ts"/>

// basic tag from form logic
// types:
// radio
// text
// email
// tel
// password
// checkbox
// radio
// select
// button


// namespace
namespace cf {
	// interface
	export interface ITag{
		domElement?: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement,
		type: string,
		name: string,
		title: string,
		question: string,
		errorMessage:string,
		setTagValueAndIsValid(value: FlowDTO):boolean;

		value:string;
	}

	export interface ITagOptions{
		domElement?: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement,
		questions?: Array<string>,
		label?: string,
		validationCallback?: (value: string) => boolean,// can also be set through cf-validation attribute
	}

	// class
	export class Tag implements ITag {
		public domElement: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement;
		
		protected defaultValue: string | number;

		private errorMessages: Array<string>;
		private pattern: RegExp;
		private _title: string;

		private validationCallback?: (value: string) => boolean; // can also be set through cf-validation attribute.
		private questions: Array<string>; // can also be set through cf-questions attribute.

		public get type (): string{
			return this.domElement.getAttribute("type");
		}

		public get name (): string{
			return this.domElement.getAttribute("name");
		}
		
		public get title (): string{
			if(!this._title){
				this._title = this.domElement.getAttribute("title");
			}

			return this._title;
		}

		public get value (): string{
			return this.domElement.value;
		}

		public get question():string{
			if(!this.questions){
				this.findLabelAndSetQuestions();
			}

			return this.questions[Math.floor(Math.random() * this.questions.length)];
		}

		public get errorMessage():string{
			if(!this.errorMessages){
				// custom tag error messages
				if(this.domElement.getAttribute("cf-error")){
					this.errorMessages = this.domElement.getAttribute("cf-error").split("|");
				}else{
					this.errorMessages = [Dictionary.get("input-placeholder-error")];
				}
			}
			return this.errorMessages[Math.floor(Math.random() * this.errorMessages.length)];
		}

		constructor(options: ITagOptions){
			if(!Tag.isTagValid(options.domElement)){
				return;
			}

			this.domElement = options.domElement;

			// questions array
			if(options.questions)
				this.questions = options.questions;

			
			// custom tag validation
			if(this.validationCallback){
				this.validationCallback = options.validationCallback;
			}else if(this.domElement.getAttribute("cf-validation")){
				// set it through an attribute, danger land with eval
				this.validationCallback = eval(this.domElement.getAttribute("cf-validation"));
			}

			// reg ex pattern is set on the Tag, so use it in our validation
			if(this.domElement.getAttribute("pattern"))
				this.pattern = new RegExp(this.domElement.getAttribute("pattern"));

			// default value of Tag
			this.defaultValue = this.domElement.value;

			if(this.type != "group"){
				console.log('Tag registered:', this.type);
			}
		}

		public static isTagValid(element: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement):boolean{
			if(element.getAttribute("type") === "hidden")
				return false;

			if(element.style.display === "none")
				return false;
			
			if(element.style.visibility === "hidden")
				return false;

			if(element.tagName.toLowerCase() == "option" && (element.innerText == "" || element.innerText == " ")){
				return false;
			}
		
			if(element.tagName.toLowerCase() == "select")
				return true
			else
				return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
		}

		public static createTag(options: ITagOptions): ITag{
			const element: HTMLInputElement | HTMLSelectElement | HTMLButtonElement | HTMLOptionElement = options.domElement;
			if(Tag.isTagValid(element)){
				// ignore hidden tags
				let tag: ITag;
				if(element.tagName.toLowerCase() == "input"){
					tag = new InputTag({
						domElement: element
						// validationCallback
						// questions: Array<String>
					});
				}else if(element.tagName.toLowerCase() == "select"){
					tag = new SelectTag({
						domElement: element
						// validationCallback
						// questions: Array<String>
					});
				}else if(element.tagName.toLowerCase() == "button"){
					tag = new ButtonTag({
						domElement: element
						// validationCallback
						// questions: Array<String>
					});
{'fraction_non_alphanumeric': 0.13468013468013468, 'fraction_numerical': 0.00010521885521885521, 'mean_word_length': 3.580722891566265, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 32, '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': '6864932', 'n_tokens_mistral': 3283, 'n_tokens_neox': 2679, 'n_words': 639}