ASTContext::getParents is supposed to return the parents of a given node. My question is how can one AST node have more than one parent??
I suspected that the doc might mean the member function returns the ancestors of a given node, not just the parents and i tested it. sizereturns a size of1` and all the nodes i tested only have one parent.
It's been a couple of years but anyways.
I did ask the question on the clang mailing list but the archive link doesn't seem to exist anymore.
The parents member function could be parent when it comes to C since in C, AST nodes can't have more than one parent. parents makes sense in C++ where nodes can have more than one parent in the AST. This happens for example with template instantiations and lambdas where a node can end up with more than one parent.
Related
I'm using Stencil to build web components and recently had a little talk with a colleague about shadowRoot and implications. Suppose I have the following simple component with a a tag which has the id of link-button. What happens in the parent HTML page if there are several components of the same kind? Is it semantically wrong to have several components with the same ID on the same HTML page, or is it alright since each shadowRoot is a microcosm of its own and the containing HTML page is not aware of this so called, hidden, content?
#Component({
tag: 'link-button',
styleUrl: 'button.scss',
shadow: true,
})
export class LinkButton {
render() {
return <a id='link-button'></a>;
}
}
This is how this component looks during inspection. Imagine 10 of these.
Different shadow trees may contain elements with the same id since, as you said, shadow trees are essentially "microcosms".
Using the HTML Living Standard to prove this:
The id Attribute
When specified on HTML elements, the id attribute value must be unique amongst all the IDs in the element's tree and must contain at least one character. The value must not contain any ASCII whitespace.
To understand how the standard defines "tree", we turn to the DOM standard.
Trees
An object that participates in a tree has a parent, which is either null or an object, and has children...
The root of an object is itself, if its parent is null, or else it is the root of its parent. The root of a tree is any object participating in that tree whose parent is null.
The "tree" of an element consists of all its parents until it hits a "root" (and their children), and the element's children.
The standard makes a distinction between document trees and shadow trees because they have different roots:
A document tree is a node tree whose root is a document.
A shadow tree is a node tree whose root is a shadow root.
In other words, the root of a shadow tree is not the same as the root of the document, and hence they are in different trees for the sake of defining an id.
But to be thorough, we have to consider whether a document's children includes the shadow trees of its children. For that we turn to the definition of Node Tree.
It's harder to quote directly, but essentially a tree can either be a Document which contains Elements, or a DocumentFragment. Elements, meanwhile, are defined to contain either other Elements or CharacterData nodes, notably not DocumentFragments.
The final piece of the puzzle is that shadow roots are DocumentFragments, which are therefore not considered children of Documents for the sake of defining a tree.
Or to summarize:
An id must be unique within a tree.
A tree is all the elements between a root and its last children.
Document Trees and Shadow Trees have different roots.
Document Trees do not contain Shadow Trees as children.
Therefore, different Shadow Trees may contain the same id.
🙂
A similar answer on Stack Overflow.
Great example where "normal" Browser behavior is not what the written standard says.
This goes back 25+ years, when (duplicate) IDs had a meaning in Internet Explorer
which all later browsers copied.
Browser behavior for the past 20 years:
global IDs create a Global Variable with the same name
Only in Global Scope! Not in shadowRoots!
duplicate IDs create a Global Variable containing an HTMLCollection,
but the Mozilla team "fixed" this some years ago, FireFox now behaves like getElementById and returns the first element in the DOM
.querySelectorAll("#MYID") returns a valid NodeList with multiple elements.
All because the Web is backwards compatible, a website from 1996 should run fine today.
So the correct answer is:
Yes, you can have duplicate ID values, should you depends on your needs.
If I see a junior use getElementID in (their own) experimental code, I educate them they are wasting keystrokes.
If I see this Browser magic in production code, I fire them.
If I see them using this knowledge in a shadowRoot, I promote them to senior, because they understand the platform.
<div id="MYID"></div>
<div id="MYID"></div>
<my-el id=MYID></my-el>
<my-el id=MYID></my-el>
<script>
customElements.define(`my-el`, class extends HTMLElement {
connectedCallback() {
this.attachShadow({
mode: "open"
}).innerHTML = (`<p id="MYID"></p>`).repeat(3);
console.log("NodeList",this.shadowRoot.querySelectorAll("#MYID"));
}
});
console.log("global variable MYID:",MYID); // global IDs create a global Variable
</script>
I'm trying to find an element from a location I got before.
In easy words I use PHPUnit with Selenium/Mink/Behat and first did this
$products = $this->getPage()->findAll('css', 'ul.list li.item .price');
Now I have a list with all items that have a price.
From this position I have to go one node up and find the previous DIV-element.
/preceding-sibling::div[#class='product-box']/descendant-or-self::*/figure/descendant-or-self::*/a/#href
This all works with one XPATH call, but I can't do that in one call, because I have a condition that is checking my first call for a specific needle.
So in real I'm now at a price element and need to know how I can travel up to my previous DIV-element.
This question already has answers here:
What is the difference between id and class in CSS, and when should I use them? [duplicate]
(15 answers)
Closed 8 years ago.
It looks like ids and classes are the exact same thing and have the same functionality, however ids are used just to show the coder/designer that they are only changing one item in those other similar items... Is that true?
I watched this helpful video http://www.youtube.com/watch?v=UZ4s1AvIDPM and that's the only difference I could tell.
It looks like ids and classes are the exact same thing and have the same functionality
Look again.
id specifically identifies an element. Each element can have no more than one id and each id must be unique throughout the DOM.
class describes an element in a more generic way, associating it logically with other elements of the same class. An element can have many classes, and the same class can be used many times throughout the DOM.
ids are used just to show the coder/designer that they are only changing one item in those other similar items... Is that true?
No, that's not true at all. ids uniquely identify (hence "id") elements. They can be used by a developer or a designer to target a specific element for some purpose (altering it, styling it, observing it, and so on).
The fact that the person is selecting an id does guarantee that they are targeting only one element (assuming that element exists, otherwise zero elements) as long as the document is well-formed (doesn't break the rule of not re-using id values, in which case the code is incorrect and behavior is undefined).
Conversely, when selecting based on a class value, any number of elements may be selected. So any developer and/or designer (or any other role) would bear that in mind and not assume that there's only one element.
I have a MySQL table that represents an element which is a node of a tree. The element has an ID, and a parent_id element, which refers to another element in the same table (can be null for top level elements). I wish to be able to sort these elements, both locally (elements which have the same parent), and globally (I want to flatten the tree and present it as a list). I have given each element a local_sorting_key, which can sort the elements within a parent node, but I want the ability to recursively sort the whole tree.
What I've done is add a new field, global_sorting_key, which is a concatenation of the global_sorting_key of the parent (if the element has a parent), and the local_sorting_key. This allows me to recursively set a sorting key for each element, and easily get the whole table and use SQL to sort it. However, this solution is not normalized, as changes to the local_sorting_key do not produce changes in the global_sorting_key, leading to internal inconsistencies.
How do I solve my problem in a simple way, while also maintaining 3NF?
I want to access an element using a DOM hierarchy Node structure, through its parent nodes.I am trying to find the DOM hierarchy through firebug; want something like, <parent_node1>.<child_node1>.<child_node2> (not by document.getElementByID, getElementbyname) to access an element.
I want to automate a scenario like, I have column headers and corresponding values. Want to test, whether the values present under each column header, is correct...
I am thinking of using DOM as a method of automating this case...But, how can I find the DOM hierarchy...?
What I see through Inspect Element in Firebug is something like, list of events, elements and is not looking like a hierarchy node structure...Can somebody help in this regard please?
As discussed, you probably mean the DOM Element properties like element.childNodes, element.firstChild or similar.
Have a look at the DOM Element property reference over at JavaScriptKit, you'll get a good overview there how to access the hierarchy.
var currentTD = document.getElementsByTagName("td")[0];
var currentTable = document.getElementsByTagName("table")[0];
currentTD.parentNode // contains the TR element the TD resides in.
currentTable.childNodes // contains THEAD TBODY and TFOOT if present.
DOM Tables even have more properties like a rows collection and a cells collection.
A reminder of caution: Beware that these collections are live collections, so iterating over them and accessing collection.length in each iteration can be really slow because to get the length, the DOM has to be queried each time.
document.getElementById and document.getElementByTagname are using the DOM. They take an object within the DOM (specifically the document object, though you can also call both of those on elements) and return an object which is a single element or a collection of zero or more elements, respectively. That's a DOM operation. From there you can do other DOM operations on the results like getting children, parents or siblings, changing values etc.
All DOM operations come down to:
Take a starting point. This is often document though it's so often that the first thing we do is call document.getElementById or document.getElementByTagname and then work from the result that we could really consider that the starting point.
Find the element or elements we are interested in, relative to the starting point whether through startingPoint.getElementById* or startingPoing.getElementByTagname perhaps combined with some test (e.g. only working on those with a particular classname, if they have children of particular types, etc.
Read and/or change certain values, add new child nodes and/or delete nodes.
In a case like yours the starting point will be one or more tables found by document.getElementById(someID), document.getElementById(someID).getElementsByTagname('table')[0], or similar. From that table, myTable.getElementsByTagname('th') will get you the column headings. Depending on the structure, and what you are doing with it, you could just select corresponding elements from myTable.getElementsByTagname('td') or go through each row and then work on curRow.getElementsByTagname('td').
You could also just use firstChild, childNodes etc. though it's normally more convenient to have elements you don't care about filtered out by tagname.
*Since there can only be one element with a given id in a document, this will return the same if called on any element higher in the document hierarchy, so we normally just call this on document. It can be useful to call it on an element if we want to do something if the element is a descendant of our current element, and not otherwise.