4

I've been trying to check if some attributes are not part of DOM HTML5 attributes. The code traverses the html markup and save on a Set. My idea is to identify in this example the attributes ng-controller, ng-repeat, ng-bind because the other attributes (id and class) are part of DOM HTML5 attributes.

HTML

<div id="html-markup">
        <div class="class-1" ng-controller="myController">
            <table id="the-table">
                <thead class="table-header" >
                        <th ng-repeat="(key, val) in myList[0] track by key">
                            {{ key }}
                        </th>
                </thead>
                <tbody class="table-body">
                    <tr ng-repeat="item in myList track by item.id">
                        <td ng-repeat="(key, value) in item">
                            <span ng-bind="value"></span>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>

Javascript

const element = document.getElementById("html-markup");
const allChildrensNodes = element.childNodes;
const allChildrensElements = element.getElementsByTagName("*");
const attributesArray = Array.from(allChildrensElements)
        .reduce((set, child) => {
            Array.from(child.attributes).forEach((attr) => {
                //if(ATTRIBUTE IS NOT PART OF DOM HTML5 ATTRIBUTES)
                set.add(attr.name)
            });
            return set;
        }, new Set())

console.log(attributesArray);//Set(5) {"class", "ng-controller", "id", "ng-repeat", "ng-bind"}

Is there some hack or trick to check this?

a codepen for play with this: https://codepen.io/gpincheiraa/pen/veWKOj?editors=1010

Jon Goodwin
  • 9,053
  • 5
  • 35
  • 54
  • 3
    can you precise what is the final goal for this? As it would be much easier to do the contrary and check for definite attributes (or prefixes like "ng-") instead of filtering out the "regular" ones. There are JSON lists on the web for regular ones, but i don't think that guarantees to be browser-variations proof.. – Kaddath Oct 04 '17 at 14:17
  • 2
    Since HTML5 is a “living thing”, and doesn’t have versions any more, such a list would not be static to begin with, but change over time ... – CBroe Oct 04 '17 at 14:21
  • @Kaddath my idea it is identify the non standard attributes for replace his value for a placeholder. the idea for this will be do snapshot testing (https://facebook.github.io/jest/docs/en/snapshot-testing.html). the problem for check "ng-" by example it's that exists another prefixes like "ui-" or "md-" or whatever you want if you create custom directives. – Gonzalo Pincheira Arancibia Oct 04 '17 at 14:27
  • You can use a xpath query – José Castro Oct 04 '17 at 17:18

2 Answers2

2

I don't believe there's any short-cut here. You'll have to build a list of the valid attributes per tag type (and note some are only valid when others have a particular value) based on the spec. While many attributes have reflected properties you could check for, A) Not all do, B) the names of the reflected properties are not always the same as the attributes they reflect; C) some properties have the same name as attributes but aren't directly reflected (though they're usually related in some way, even if loosely; value isn't a reflected property for the value attribute, for instance; the property is defaultValue).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    That link is great -- you could grab the page via AJAX, build your list, then run through it for each element. – freginold Oct 04 '17 at 15:08
  • 1
    @freginold: Wow -- I was going to say "Probably not, cross-origin call" but the W3C supports CORS for that page! (Glad I checked...) Worked from jsfiddle and from localhost, so I figure they have it wide open. – T.J. Crowder Oct 04 '17 at 15:12
1

Hi If you want to collect start with "ng-" you can add below code insted`

if(attr.name.startsWith('ng-'))
  set.add(attr.name)

Or you can make your own array with full attribute list in in this link (HTML attribute reference)

    const fullAttributeList = ['class','name','id',.....];
   ..
   ..
   ..
    if(fullAttributeList.indexOf(attr.name) ===-1)
      set.add(attr.name)
Ferhat BAŞ
  • 797
  • 7
  • 12
  • Thanks, i use your link from mdn and the list of attributes was enough for me. Simply use `Array.from(document.querySelectorAll(".standard-table tbody tr td:nth-child(1)")).map((c) => c.innerText)` in the chrome console and get the list :) – Gonzalo Pincheira Arancibia Oct 04 '17 at 20:06