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