From 62581d506c4de1ad2ba365f55a503eff1dfd86d7 Mon Sep 17 00:00:00 2001 From: vondrp <vondrovic@centrum.cz> Date: Tue, 22 Oct 2024 23:55:13 +0200 Subject: [PATCH 1/3] =?UTF-8?q?Re=20#11638=20-=20logika=20u=C5=BE=C3=ADv?= =?UTF-8?q?=C3=A1n=C3=AD=20recommended=20atribut=C5=AF=20a=20styl=C5=AF=20?= =?UTF-8?q?s=20pou=C5=BEit=C3=ADm=20json=20souboru,=20json=20zat=C3=ADm=20?= =?UTF-8?q?nedoko=C4=8Den,=20otestov=C3=A1na=20funk=C4=8Dnost=20logiky?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.module.ts | 3 +- src/app/model/attribute-config.interface.ts | 19 ++++ src/app/model/element-config.interface.ts | 17 +++ src/app/model/style-config.interface.ts | 14 +++ .../final-stage/final-stage.component.ts | 107 ++++++++++++++++-- src/assets/json/recommended-elements.json | 105 +++++++++++++++++ 6 files changed, 255 insertions(+), 10 deletions(-) create mode 100644 src/app/model/attribute-config.interface.ts create mode 100644 src/app/model/element-config.interface.ts create mode 100644 src/app/model/style-config.interface.ts create mode 100644 src/assets/json/recommended-elements.json diff --git a/src/app/app.module.ts b/src/app/app.module.ts index e196f15..0c9103f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,6 +1,7 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; +import { HttpClientModule } from '@angular/common/http'; import { AppComponent } from './app.component'; import { OverviewComponent } from './view/pages/overview/overview.component'; @@ -38,7 +39,7 @@ import { CustomRadiobuttonComponent } from './view/components/custom-radiobutton CustomCheckboxComponent, CustomRadiobuttonComponent, ], - imports: [BrowserModule, FormsModule], + imports: [BrowserModule, FormsModule, HttpClientModule], providers: [], bootstrap: [AppComponent], }) diff --git a/src/app/model/attribute-config.interface.ts b/src/app/model/attribute-config.interface.ts new file mode 100644 index 0000000..c0ce1da --- /dev/null +++ b/src/app/model/attribute-config.interface.ts @@ -0,0 +1,19 @@ +/** + * Interface representing the configuration for an HTML attribute. + */ +export interface AttributeConfig { + /** + * The name of the attribute (e.g., 'href', 'target'). + */ + name: string; + + /** + * Indicates whether the attribute is required (optional). + */ + required?: boolean; + + /** + * The default value of the attribute, if applicable (optional). + */ + defaultValue?: string; +} diff --git a/src/app/model/element-config.interface.ts b/src/app/model/element-config.interface.ts new file mode 100644 index 0000000..743b391 --- /dev/null +++ b/src/app/model/element-config.interface.ts @@ -0,0 +1,17 @@ +import { AttributeConfig } from './attribute-config.interface'; +import { StyleConfig } from './style-config.interface'; + +/** + * Interface representing the configuration of an HTML element. + */ +export interface ElementConfig { + /** + * An array of recommended attributes for the element. + */ + atr: AttributeConfig[]; + + /** + * An array of recommended styles for the element. + */ + style: StyleConfig[]; +} diff --git a/src/app/model/style-config.interface.ts b/src/app/model/style-config.interface.ts new file mode 100644 index 0000000..7398c6b --- /dev/null +++ b/src/app/model/style-config.interface.ts @@ -0,0 +1,14 @@ +/** + * Interface representing the configuration for a CSS style. + */ +export interface StyleConfig { + /** + * The name of the style property (e.g., 'color', 'font-size'). + */ + name: string; + + /** + * The default value of the style property, if applicable (optional). + */ + defaultValue?: string; +} diff --git a/src/app/view/pages/final-stage/final-stage.component.ts b/src/app/view/pages/final-stage/final-stage.component.ts index ed18ea8..dd75118 100644 --- a/src/app/view/pages/final-stage/final-stage.component.ts +++ b/src/app/view/pages/final-stage/final-stage.component.ts @@ -7,6 +7,11 @@ import { HtmlElement } from 'src/app/model/html-element.interface'; import { Message } from 'src/app/model/message.interface'; +import { ElementConfig } from 'src/app/model/element-config.interface'; +import { AttributeConfig } from 'src/app/model/attribute-config.interface'; +import { StyleConfig } from 'src/app/model/style-config.interface'; +import { HttpClient } from '@angular/common/http'; + import { saveFinalStates, getMarkFinalState, @@ -48,6 +53,7 @@ export class FinalStageComponent implements OnInit { valueTypes: { [key: string]: 'custom' | 'default' } = {}; // recomended attributes + RecommendedElements: { [key: string]: ElementConfig } = {}; recommendedStyles: string[] = []; recommendedAttributes: string[] = []; @@ -63,7 +69,10 @@ export class FinalStageComponent implements OnInit { filteredRecommendedAttributes: string[] = []; filteredOthersAttributes: string[] = []; - constructor(private ref: ChangeDetectorRef) {} + constructor( + private ref: ChangeDetectorRef, + private http: HttpClient + ) {} // Readonly properties protected readonly Object = Object; // just for the template @@ -73,16 +82,48 @@ export class FinalStageComponent implements OnInit { * Initializes the FinalStageComponent. */ ngOnInit(): void { + this.http + .get<{ + [key: string]: ElementConfig; + }>('/assets/json/recommended-elements.json') + .subscribe((data: { [key: string]: ElementConfig }) => { + this.RecommendedElements = data; + console.log(this.RecommendedElements); + + // Check if finalStateTarget is available and call loadRecommended + if (this.finalStateTarget) { + console.log( + 'Final state target tag name:', + this.finalStateTarget.tagName + ); + this.loadRecommended(this.finalStateTarget.tagName); + } else { + this.recommendedAttributes = []; + this.recommendedStyles = []; + } + }); + chrome.runtime.onMessage.addListener((message: Message) => { if (message.finalStateClickTarget) { this.isMarkFinalState = true; - this.filterData(''); // by using dictionary of recommended attributes and styles use tagname to assign recommended attributes and styles // this.finalStateTarget?.tagName - this.recommendedAttributes = ['type', 'placeholder']; - this.recommendedStyles = ['backgroundColor', 'fontSize']; + if (this.finalStateTarget) { + this.loadRecommended(this.finalStateTarget.tagName); + } else { + this.recommendedAttributes = []; + this.recommendedStyles = []; + } + // filter must be called after setting recommended + this.filterData(''); } else { + if (this.finalStateTarget) { + this.loadRecommended(this.finalStateTarget.tagName); + } else { + this.recommendedAttributes = []; + this.recommendedStyles = []; + } // Otherwise, check getMarkFinalState getMarkFinalState().then(markFinalState => { this.isMarkFinalState = markFinalState; @@ -97,11 +138,40 @@ export class FinalStageComponent implements OnInit { this.customValues = {}; this.valueTypes = {}; this.ref.detectChanges(); // chrome.runtime.onMessage is outside of Angular scope, so we need to detect changes manually + if (this.finalStateTarget) { + this.loadRecommended(this.finalStateTarget.tagName); + } else { + this.recommendedAttributes = []; + this.recommendedStyles = []; + } + // filter must be called after setting recommended this.filterData(''); } }); } + loadRecommended(tagname: string) { + // Normalize to small letters + const normalizedTagname = tagname.toLowerCase(); + + // Look for tag (case-insensitive) + const foundElement = Object.keys(this.RecommendedElements).find( + key => key.toLowerCase() === normalizedTagname + ); + + if (foundElement) { + this.recommendedAttributes = this.RecommendedElements[ + foundElement + ].atr.map((attr: AttributeConfig) => attr.name); + this.recommendedStyles = this.RecommendedElements[foundElement].style.map( + (style: StyleConfig) => style.name + ); + } else { + this.recommendedAttributes = []; + this.recommendedStyles = []; + } + } + // Handlers for custom value changes /** @@ -351,8 +421,13 @@ export class FinalStageComponent implements OnInit { // Split filteredStyles into filteredRecommendedStyles and filteredOthersStyles this.filteredStyles.forEach(key => { if (!savedAttributeKeys.includes('style.' + key)) { + const normalizedKey = key.toLowerCase(); // Check if style belongs into recommendedStyles or othersStyles - if (this.recommendedStyles.includes(key)) { + if ( + this.recommendedStyles.some( + style => style.toLowerCase() === normalizedKey + ) + ) { this.filteredRecommendedStyles.push(key); } else { this.filteredOthersStyles.push(key); @@ -375,13 +450,22 @@ export class FinalStageComponent implements OnInit { this.filteredComputedStyles.forEach(key => { if (!savedAttributeKeys.includes('style.' + key)) { + const normalizedKey = key.toLowerCase(); // Check if style belongs into recommendedStyles or othersStyles and is not already included if ( - this.recommendedStyles.includes(key) && - !this.filteredRecommendedStyles.includes(key) + this.recommendedStyles.some( + style => style.toLowerCase() === normalizedKey + ) && + !this.filteredRecommendedStyles.some( + style => style.toLowerCase() === normalizedKey + ) ) { this.filteredRecommendedStyles.push(key); - } else if (!this.filteredOthersStyles.includes(key)) { + } else if ( + !this.filteredOthersStyles.some( + style => style.toLowerCase() === normalizedKey + ) + ) { this.filteredOthersStyles.push(key); } } @@ -423,8 +507,13 @@ export class FinalStageComponent implements OnInit { // Split filteredAttributes into filteredRecommendedAttributes and filteredOthersAttributes this.filteredAttributes.forEach(key => { if (!savedAttributeKeys.includes(key)) { + const normalizedKey = key.toLowerCase(); // check if attribute belongs to recommended or others - if (this.recommendedAttributes.includes(key)) { + if ( + this.recommendedAttributes.some( + attr => attr.toLowerCase() === normalizedKey + ) + ) { this.filteredRecommendedAttributes.push(key); } else { this.filteredOthersAttributes.push(key); diff --git a/src/assets/json/recommended-elements.json b/src/assets/json/recommended-elements.json new file mode 100644 index 0000000..531a750 --- /dev/null +++ b/src/assets/json/recommended-elements.json @@ -0,0 +1,105 @@ +{ + "a": { + "atr": [ + { + "name": "href", + "required": true + }, + { + "name": "target", + "defaultValue": "_blank" + }, + { + "name": "rel" + } + ], + "style": [ + { + "name": "color", + "defaultValue": "#0000FF" + }, + { + "name": "textdecoration", + "defaultValue": "underline" + } + ] + }, + "div": { + "atr": [ + { + "name": "Id", + "required": true + }, + { + "name": "class" + }, + { + "name": "datacustom" + } + ], + "style": [ + { + "name": "color" + }, + { + "name": "backgroundcolor" + }, + { + "name": "margin" + }, + { + "name": "padding" + } + ] + }, + "p": { + "atr": [ + { + "name": "class" + }, + { + "name": "data-paragraph" + } + ], + "style": [ + { + "name": "fontsize" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + } + ] + }, + "img": { + "atr": [ + { + "name": "src", + "required": true + }, + { + "name": "alt", + "required": true + }, + { + "name": "width", + "defaultValue": "auto" + }, + { + "name": "height", + "defaultValue": "auto" + } + ], + "style": [ + { + "name": "borderradius" + }, + { + "name": "boxshadow" + } + ] + } +} + \ No newline at end of file -- GitLab From 4660d11208db2b0e1942546e52f9b0bb1790b56c Mon Sep 17 00:00:00 2001 From: vondrp <vondrovic@centrum.cz> Date: Wed, 23 Oct 2024 20:30:55 +0200 Subject: [PATCH 2/3] =?UTF-8?q?Re=20#11638=20-=20naps=C3=A1n=C3=AD=20json?= =?UTF-8?q?=20recommended=20atribut=C5=AF=20a=20styl=C5=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/json/recommended-elements.json | 940 +++++++++++++++++++++- 1 file changed, 925 insertions(+), 15 deletions(-) diff --git a/src/assets/json/recommended-elements.json b/src/assets/json/recommended-elements.json index 531a750..ec23aac 100644 --- a/src/assets/json/recommended-elements.json +++ b/src/assets/json/recommended-elements.json @@ -11,12 +11,17 @@ }, { "name": "rel" + }, + { + "name": "download" + }, + { + "name": "charset" } ], "style": [ { - "name": "color", - "defaultValue": "#0000FF" + "name": "color" }, { "name": "textdecoration", @@ -24,52 +29,198 @@ } ] }, - "div": { + "area": { "atr": [ { - "name": "Id", - "required": true + "name": "href" + }, + { + "name": "download" + } + ], + "style": [ + { + "name": "cursor" + } + ] + }, + "audio": { + "atr": [ + { + "name": "src" }, { - "name": "class" + "name": "controls" }, { - "name": "datacustom" + "name": "controlslist" } ], "style": [ { - "name": "color" + "name": "width" + }, + { + "name": "height" + } + ] + }, + "base": { + "atr": [ + { + "name": "href" + }, + { + "name": "target" + } + ], + "style": [ + ] + }, + "button": { + "atr": [ + { + "name": "value" + }, + { + "name": "download" + }, + { + "name": "form" }, + { + "name": "formtarget" + } + ], + "style": [ { "name": "backgroundcolor" }, + { + "name": "color" + }, + { + "name": "border" + }, + { + "name": "cursor" + }, + { + "name": "boxshadow" + }, + { + "name": "padding" + } + ] + }, + "data": { + "atr": [ + { + "name": "value" + } + ], + "style": [ + { + "name": "fontfamily" + }, + { + "name": "fontstyle" + } + ] + }, + "embed": { + "atr": [ + { + "name": "src" + } + ], + "style": [ + { + "name": "width" + }, + { + "name": "height" + } + ] + }, + "fieldset": { + "atr": [ + { + "name": "form" + } + ], + "style": [ + { + "name": "border" + }, + { + "name": "padding" + } + ] + }, + "form": { + "atr": [ + { + "name": "href" + }, + { + "name": "target" + }, + { + "name": "autocomplete" + }, + { + "name": "acceptcharset" + }, + { + "name": "action" + }, + { + "name": "method" + }, + { + "name": "target" + }, + { + "name": "enctype" + } + ], + "style": [ { "name": "margin" }, { "name": "padding" + }, + { + "name": "alignitems" + }, + { + "name": "justifycontent" } ] }, - "p": { + "iframe": { "atr": [ { - "name": "class" + "name": "src" }, { - "name": "data-paragraph" + "name": "srcdoc" } ], "style": [ { - "name": "fontsize" + "name": "border" }, { - "name": "lineheight" + "name": "overflow" }, { - "name": "textalign" + "name": "width" + }, + { + "name": "height" } ] }, @@ -83,6 +234,12 @@ "name": "alt", "required": true }, + { + "name": "decoding" + }, + { + "name": "loading" + }, { "name": "width", "defaultValue": "auto" @@ -98,8 +255,761 @@ }, { "name": "boxshadow" + }, + { + "name": "width" + }, + { + "name": "height" + }, + { + "name": "maxwidth" + } + ] + }, + "input": { + "atr": [ + { + "name": "value" + }, + { + "name": "readonly" + }, + { + "name": "checked" + }, + { + "name": "formtarget" + }, + { + "name": "placeholder" + }, + { + "name": "pattent" + }, + { + "name": "step" + }, + { + "name": "accept" + }, + { + "name": "type" + } + ], + "style": [ + { + "name": "border" + }, + { + "name": "padding" + }, + { + "name": "fontsize" + }, + { + "name": "width" + }, + { + "name": "backgroundcolor" + } + ] + }, + "label": { + "atr": [ + { + "name": "for" + } + ], + "style": [ + { + "name": "fontweight" + }, + { + "name": "display" + } + ] + }, + "li": { + "atr": [ + { + "name": "value" + } + ], + "style": [ + { + "name": "liststyletype" + }, + { + "name": "margin" + }, + { + "name": "padding" + } + ] + }, + "link": { + "atr": [ + { + "name": "href" + }, + { + "name": "media" + } + ], + "style":[] + }, + "map": { + "atr":[], + "style":[] + }, + "meta": { + "atr": [ + { + "name": "charset" + } + ], + "style": [] + }, + "meter": { + "atr": [ + { + "name": "value" + }, + { + "name": "min" + }, + { + "name": "max" + } + ], + "style": [ + { + "name": "width" + }, + { + "name": "height" + }, + { + "name": "backgroundcolor" + } + ] + }, + "object": { + "atr": [ + { + "name": "data" + } + ], + "style": [ + { + "name": "width" + }, + { + "name": "height" + } + ] + }, + "optgroup": { + "atr": [ + { + "name": "label" + } + ], + "style": [] + }, + "option": { + "atr": [ + { + "name": "value" + }, + { + "name": "selected" + } + ], + "style": [] + }, + "output": { + "atr": [ + { + "name": "for" + } + ], + "style": [ + { + "name": "fontfamily" + }, + { + "name": "fontweight" + }, + { + "name": "color" + } + ] + }, + "progress": { + "atr": [ + { + "name": "value" + }, + { + "name": "max" + } + ], + "style": [ + { + "name": "width" + }, + { + "name": "height" + } + ] + }, + "select": { + "atr": [ + { + "name": "multiple" + }, + { + "name": "size" + } + ], + "style": [ + { + "name": "border" + }, + { + "name": "padding" + }, + { + "name": "fontsize" + } + ] + }, + "slot": { + "atr": [], + "style": [] + }, + "textarea": { + "atr": [ + { + "name": "placeholder" + }, + { + "name": "maxlength" + }, + { + "name": "minlength" + } + ], + "style": [ + { + "name": "border" + }, + { + "name": "backgroundcolor" + }, + { + "name": "padding" + }, + { + "name": "fontsize" + } + ] + }, + "track": { + "atr": [ + { + "name": "src" + }, + { + "name": "kind" + } + ], + "style": [] + }, + "video": { + "atr": [ + { + "name": "src" + }, + { + "name": "controls" + }, + { + "name": "controlslist" + }, + { + "name": "autoplay" + }, + { + "name": "poster" + }, + { + "name": "preload" + } + ], + "style": [ + { + "name": "width" + }, + { + "name": "height" + }, + { + "name": "objectfit" + } + ] + }, + "body": { + "atr": [], + "style": [ + { + "name": "backgroundcolor" + }, + { + "name": "fontfamily" + }, + { + "name": "margin" + }, + { + "name": "padding" + }, + { + "name": "lineheight" + }, + { + "name": "overflow" + } + ] + }, + "div": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "display" + }, + { + "name": "alignitems" + }, + { + "name": "justifycontent" + }, + { + "name": "backgroundcolor" + }, + { + "name": "margin" + }, + { + "name": "padding" + }, + { + "name": "lineheight" + }, + { + "name": "border" + } + ] + }, + "section": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "display" + }, + { + "name": "alignitems" + }, + { + "name": "justifycontent" + }, + { + "name": "backgroundcolor" + }, + { + "name": "margin" + }, + { + "name": "padding" + }, + { + "name": "lineheight" + }, + { + "name": "border" + } + ] + }, + "article": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "display" + }, + { + "name": "alignitems" + }, + { + "name": "justifycontent" + }, + { + "name": "backgroundcolor" + }, + { + "name": "margin" + }, + { + "name": "padding" + }, + { + "name": "lineheight" + }, + { + "name": "border" + } + ] + }, + "aside": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "display" + }, + { + "name": "alignitems" + }, + { + "name": "justifycontent" + }, + { + "name": "backgroundcolor" + }, + { + "name": "margin" + }, + { + "name": "padding" + }, + { + "name": "lineheight" + }, + { + "name": "border" + } + ] + }, + "nav": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "display" + }, + { + "name": "alignitems" + }, + { + "name": "justifycontent" + }, + { + "name": "backgroundcolor" + }, + { + "name": "margin" + }, + { + "name": "padding" + }, + { + "name": "lineheight" + }, + { + "name": "border" + } + ] + }, + "p": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "fontweight" + }, + { + "name": "fontstyle" + }, + { + "name": "textransform" + } + ] + }, + "span": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "fontweight" + }, + { + "name": "fontstyle" + }, + { + "name": "textransform" + } + ] + }, + "h1": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "fontweight" + }, + { + "name": "fontstyle" + }, + { + "name": "textransform" + } + ] + }, + "h2": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "fontweight" + }, + { + "name": "fontstyle" + }, + { + "name": "textransform" + } + ] + }, + "h3": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "fontweight" + }, + { + "name": "fontstyle" + }, + { + "name": "textransform" + } + ] + }, + "h4": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "fontweight" + }, + { + "name": "fontstyle" + }, + { + "name": "textransform" + } + ] + }, + "h5": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "fontweight" + }, + { + "name": "fontstyle" + }, + { + "name": "textransform" + } + ] + }, + "h6": { + "atr": [], + "style": [ + { + "name": "fontsize" + }, + { + "name": "color" + }, + { + "name": "lineheight" + }, + { + "name": "textalign" + }, + { + "name": "fontweight" + }, + { + "name": "fontstyle" + }, + { + "name": "textransform" + } + ] + }, + "default": { + "atr": [], + "style": [ + { + "name": "display" + }, + { + "name": "margin" + }, + { + "name": "padding" } ] } } - \ No newline at end of file + \ No newline at end of file -- GitLab From 73059e17b73fa43de6a9ab4ec03c1ceb6470c36e Mon Sep 17 00:00:00 2001 From: vondrp <vondrovic@centrum.cz> Date: Wed, 23 Oct 2024 21:04:36 +0200 Subject: [PATCH 3/3] =?UTF-8?q?Re=20#11638=20-=20pou=C5=BEit=C3=AD=20defau?= =?UTF-8?q?lt=20elementu,=20nen=C3=AD-li=20jin=C3=BD=20nalezen,=20roz?= =?UTF-8?q?=C5=A1=C3=AD=C5=99en=C3=AD=20atribut=C5=AF,=20kter=C3=A9=20sb?= =?UTF-8?q?=C3=ADr=C3=A1me?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/utils/attribute-grabber.util.ts | 8 ++++++++ src/app/view/pages/final-stage/final-stage.component.ts | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/app/utils/attribute-grabber.util.ts b/src/app/utils/attribute-grabber.util.ts index 968f07e..55b9d78 100644 --- a/src/app/utils/attribute-grabber.util.ts +++ b/src/app/utils/attribute-grabber.util.ts @@ -202,6 +202,10 @@ const extractFromForm = (element: HTMLFormElement): NonNullable<unknown> => { autocomplete: element.autocomplete, acceptCharset: element.acceptCharset, accept: element.getAttribute('accept'), + action: element.action, + method: element.method, + enctype: element.enctype, + novalidate: element.noValidate, }; }; @@ -363,6 +367,7 @@ const extractFromSelect = ( autocomplete: element.autocomplete, required: element.required, value: element.value, + size: element.size, }; }; @@ -409,6 +414,9 @@ const extractFromVideo = (element: HTMLVideoElement): NonNullable<unknown> => { src: element.src, controls: element.controls, controlsList: element.getAttribute('controlslist'), + autoplay: element.autoplay, + poster: element.poster, + preload: element.preload, }; }; diff --git a/src/app/view/pages/final-stage/final-stage.component.ts b/src/app/view/pages/final-stage/final-stage.component.ts index dd75118..74e9e18 100644 --- a/src/app/view/pages/final-stage/final-stage.component.ts +++ b/src/app/view/pages/final-stage/final-stage.component.ts @@ -155,10 +155,17 @@ export class FinalStageComponent implements OnInit { const normalizedTagname = tagname.toLowerCase(); // Look for tag (case-insensitive) - const foundElement = Object.keys(this.RecommendedElements).find( + let foundElement = Object.keys(this.RecommendedElements).find( key => key.toLowerCase() === normalizedTagname ); + // If not found, try to use "default" + if (!foundElement) { + foundElement = Object.keys(this.RecommendedElements).find( + key => key.toLowerCase() === 'default' + ); + } + if (foundElement) { this.recommendedAttributes = this.RecommendedElements[ foundElement -- GitLab