github.com/MontFerret/ferret@v0.18.0/pkg/drivers/cdp/templates/xpath.go (about)

     1  package templates
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/mafredri/cdp/protocol/runtime"
     7  
     8  	"github.com/MontFerret/ferret/pkg/drivers/cdp/eval"
     9  	"github.com/MontFerret/ferret/pkg/runtime/values"
    10  )
    11  
    12  const xpath = `(el, expression, resType) => {
    13  	const unwrap = (item) => {
    14  		return item.nodeType != 2 ? item : item.nodeValue;
    15  	};
    16  	const out = document.evaluate(
    17  		expression,
    18  		el,
    19  		null,
    20  		resType == null ? XPathResult.ANY_TYPE : resType
    21  	);
    22  	let result;
    23  
    24  	switch (out.resultType) {
    25  		case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
    26  		case XPathResult.ORDERED_NODE_ITERATOR_TYPE: {
    27  			result = [];
    28  			let item;
    29  
    30  			while ((item = out.iterateNext())) {
    31  				result.push(unwrap(item));
    32  			}
    33  
    34  			break;
    35  		}
    36  		case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
    37  		case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE: {
    38  			result = [];
    39  
    40  			for (let i = 0; i < out.snapshotLength; i++) {
    41  				const item = out.snapshotItem(i);
    42  
    43  				if (item != null) {
    44  					result.push(unwrap(item));
    45  				}
    46  			}
    47  			break;
    48  		}
    49  		case XPathResult.NUMBER_TYPE: {
    50  			result = out.numberValue;
    51  			break;
    52  		}
    53  		case XPathResult.STRING_TYPE: {
    54  			result = out.stringValue;
    55  			break;
    56  		}
    57  		case XPathResult.BOOLEAN_TYPE: {
    58  			result = out.booleanValue;
    59  			break;
    60  		}
    61  		case XPathResult.ANY_UNORDERED_NODE_TYPE:
    62  		case XPathResult.FIRST_ORDERED_NODE_TYPE: {
    63  			const node = out.singleNodeValue;
    64  			
    65  			if (node != null) {
    66  				result = unwrap(node);
    67  			}
    68  			
    69  			break;
    70  		}
    71  		default: {
    72  			break;
    73  		}
    74  	}
    75  
    76  	return result;
    77  }
    78  `
    79  
    80  var (
    81  	xpathAsElementFragment = fmt.Sprintf(`
    82  const xpath = %s;
    83  const found = xpath(el, selector, XPathResult.FIRST_ORDERED_NODE_TYPE);
    84  `, xpath)
    85  
    86  	xpathAsElementArrayFragment = fmt.Sprintf(`
    87  const xpath = %s;
    88  const found = xpath(el, selector, XPathResult.ORDERED_NODE_ITERATOR_TYPE);
    89  `, xpath)
    90  )
    91  
    92  func XPath(id runtime.RemoteObjectID, expression values.String) *eval.Function {
    93  	return eval.F(xpath).WithArgRef(id).WithArgValue(expression)
    94  }