[whatwg/dom] Suggestion: new method - getNodesByType (#992)

# getNodesByType
This is a suggestion for a new method to return a node list of descendant nodes of a matching node type.

## Purpose
More directly access any part of a document.  I have used this method in my own code for many years and it has allowed me to perform actions quickly with minimal code.

### Examples
* I can embed state data from the server into an HTML comment and deliver this directly with the HTML without using any external artifact.  I can then access the comment directly from a node list using `document.getNodesByType(8);`

* I can access all text in a document immediately and the evaluate the relationships of those text node values against their parent elements for accessibility concerns: https://github.com/prettydiff/semanticText

## Background
In the DOM specification nodes are of a type.  The standard types are (including deprecated legacy types):

1. 1 - ELEMENT_NODE
2. 2 - ATTRIBUTE_NODE
3. 3 - TEXT_NODE
4. 4 - CDATA_SECTION_NODE
5. 5 - ENTITY_REFERENCE_NODE
6. 6 - ENTITY_NODE
7. 7 - PROCESSING_INSTRUCTION_NODE
8. 8 - COMMENT_NODE
9. 9 - DOCUMENT_NODE
10. 10 - DOCUMENT_TYPE_NODE
11. 11 - DOCUMENT_FRAGMENT_NODE
12. 12 - NOTATION_NODE

The numbers were intentionally specified because that is the value returned by accessing the nodeType property of a node object, which returns a number corresponding to the definitions listed above.

The below suggestion criteria will also mention a value for 0: **0 - ALL** where in a 0 value returns a node list of all descendant nodes.

## Availability
This method should be available on the document object and elements.

## Input
A node type value.  This value can be of two types:

* number, 0-12 - The node type value.
* string, type name - The node type name.

### Unsupported Input
If input is provided that does not conform the accepted criteria the default value of 0 will be applied.

## Output
A node list

## Working Demonstration (TypeScript)
```typescript
function browser_dom_getNodesByType(typeValue:number|string):Node[] {
    const valueString:string = (typeof typeValue === "string") ? typeValue.toLowerCase() : "",
        // eslint-disable-next-line
        root:Element = (this === document) ? document.documentElement : this,
        numb:number = (isNaN(Number(typeValue)) === false)
            ? Number(typeValue)
            : 0;
    let types:number = (numb > 12 || numb < 0)
        ? 0
        : Math.round(numb);

    // If input is a string and supported standard value
    // associate to the standard numeric type
    if (valueString === "all" || typeValue === "") {
        types = 0;
    } else if (valueString === "element_node") {
        types = 1;
    } else if (valueString === "attribute_node") {
        types = 2;
    } else if (valueString === "text_node") {
        types = 3;
    } else if (valueString === "cdata_section_node") {
        types = 4;
    } else if (valueString === "entity_reference_node") {
        types = 5;
    } else if (valueString === "entity_node") {
        types = 6;
    } else if (valueString === "processing_instruction_node") {
        types = 7;
    } else if (valueString === "comment_node") {
        types = 8;
    } else if (valueString === "document_node") {
        types = 9;
    } else if (valueString === "document_type_node") {
        types = 10;
    } else if (valueString === "document_fragment_node") {
        types = 11;
    } else if (valueString === "notation_node") {
        types = 12;
    }

    // A handy dandy function to trap all the DOM walking
    return (function browser_dom_getNodesByType_walking():Node[] {
        const output:Node[] = [],
            child  = function browser_dom_getNodesByType_walking_child(x:Element):void {
                const children:NodeListOf<ChildNode> = x.childNodes;
                let a:NamedNodeMap    = x.attributes,
                    b:number    = a.length,
                    c:number    = 0;
                // Special functionality for attribute types.
                if (b > 0 && (types === 2 || types === 0)) {
                    do {
                        output.push(a[c]);
                        c = c + 1;
                    } while (c < b);
                }
                b = children.length;
                c = 0;
                if (b > 0) {
                    do {
                        if (children[c].nodeType === types || types === 0) {
                            output.push(children[c] as Element);
                        }
                        if (children[c].nodeType === 1) {
                            //recursion magic
                            browser_dom_getNodesByType_walking_child(children[c] as Element);
                        }
                        c = c + 1;
                    } while (c < b);
                }
            };
        child(root);
        return output;
    }());
}
```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/992

Received on Monday, 21 June 2021 03:59:50 UTC