What is a DOM path? - dom

Searching the web for DOM path returns results that lack a consensus, are about XPath, or altogether have nothing to do with technology. There are questions on Stack Overflow that ask about DOM paths, but there is no indication of a "DOM path" being the same thing to different people (in the same way things like HTMLor integers are conceived of the same way).
What is a DOM path? What makes for a valid DOM path? What are they used with?

A so called DOM Path is not definied by the DOM specification itself. The closest thing you can find there, are event paths.
An event path is definied as follows:
An event has an associated path. A path is a list of structs. Each
struct consists of an item (an EventTarget object), an
item-in-shadow-tree (a boolean), a target (a potential event target),
a relatedTarget (a potential event target), a touch target list (a
list of potential event targets), a root-of-closed-tree (a boolean),
and a slot-in-closed-tree (a boolean). A path is initially the empty
list.

Related

What is an ‘`is` value’ of a DOM element node?

While idly browsing the DOM specification, I came upon this passage:
Elements have an associated namespace, namespace prefix, local name, custom element state, custom element definition, is value. When an element is created, all of these values are initialized.
Looking at other parts of the specification, I learned that it is apparently supposed to be a string value or null. However, I have not been able to find out what is it actually supposed to be used for.
Of what use is this concept?

Eclipse CDT plugin - action restricted to function name

Currently I am developing a plugin for Eclipse CDT. I have successfully made an action declaration in my plugin.xml file.
<extension
point="org.eclipse.ui.popupMenus">
<objectContribution
id="MyOwnPlugin.contribution1"
nameFilter="*.c"
objectClass="org.eclipse.ui.IEditorInput">
<action
class="myownplugin.popup.actions.DoTestsAction"
enablesFor="1"
id="myownplugin.doTests"
label="Do Tests"
menubarPath="additions">
</action>
</objectContribution>
</extension>
This successfully declares a popup action when I right-click on the editor and I can select the action.
However, what I would like to achieve is that the action would only appear when I right-click on a function name/function declaration. Is there a way how to achieve this? I have been trying the filter XML tag in the plugin.xml, but with no success.
Thanks.
I haven't tried this myself, but I believe what you want is doable (modulo the click position vs. caret position issue described in the comments). You are on the right track with using the <filter> element, but there are some other pieces required to get this to work.
The first thing to realize is that a context menu pertains to an object, and in the case of the editor's context menu, that object is the IEditorInput representing the contents of the editor tab.
Any mechanism to make the presence of a context menu action dependent on some condition, will only have that object available as input. It follows that the condition must be based on the state of the object (only). This is why we can base it on caret position but not on the location of the click itself: "the current caret position in the editor" is part of the state of the IEditorInput, but "the location of the current click within the editor" is not (that I know of).
The documentation of the <filter> element says:
This element is used to evaluate the attribute state of each object
in the current selection. A match only if each object in the selection
has the specified attribute state. Each object in the selection must
implement, or adapt to, org.eclipse.ui.IActionFilter.
The reason this talks about a "selection" is that in some views a context menu can be invoked with multiple objects selected (e.g. in the Project Explorer view, with multiple files / folders selected). In an editor context that doesn't apply; there will only be one object in the "selection", of type IEditorInput.
Unfortunately, IEditorInput does not implement IActionFilter. However, it does implement IAdaptable, so we can use the adapter mechanism to have our plugin support adapting it to IActionFilter.
That will involve adding something like this to your plugin.xml:
<extension point="org.eclipse.core.runtime.adapters">
<factory
class="your.plugin.EditorInputAdapterFactory"
adaptableType="org.eclipse.ui.IEditorInput">
<adapter type="org.eclipse.ui.IActionFilter"/>
</factory>
</extension>
where your.plugin.EditorInputAdapterFactory is a type you'll write in your plugin. Its implementation will look something like this:
public class EditorInputAdapterFactory implements IAdapterFactory {
#Override
public <T> T getAdapter(Object adaptable, Class<T> adapterType) {
if (adaptable instanceof IEditorInput && adapterType.equals(IActionFilter.class)) {
return new EditorInputActionFilter((IEditorInput) adaptable);
}
return null;
}
}
where EditorInputActionFilter is, again, a type we'll write.
Ok, now we have an action filter that works with IEditorInput objects, enabling us to use the <filter> element.
The <filter> element uses an "attribute name" and an "attribute value", which will be passed it to the IActionFilter. As the author of the action filter, we get to invent these. For example, we can invent an attribute name called selectedElementType (where by "selected element" I mean the type of C++ element the caret is currently over), and a value named function.
Then our filter declaration will look like this:
<filter name="selectedElementType" value="function" />
Finally, we need to implement our action filter so it evaluates the property we defined for an IEditorInput object. I won't write up the complete implementation here, but in broad strokes:
Use CDTUITools.getWorkingCopyManager() to map the IEditorInput to an IWorkingCopy, which implements ITranslationUnit.
Get the editor's current caret position, using something like CUIPlugin.getActivePage().findEditor(editorInput).getEditorSite().getSelectionProvider().getSelection() (with appropriate null checks in between). There may be an easier way to do this, but that's what comes to mind. Since you're in an editor, the returned selection should have type ITextSelection.
Use SharedASTJob to get access to the editor's shared AST (IASTTranslationUnit). Note that you'll need to block on the job, and the action filter will (I assume) be invoked on the UI thread, which is not ideal. (More on that below.)
Use IASTTranslationUnit.getNodeSelector(null).findEnclosingName(offset, length), with the offset and length from the ITextSelection, to get an IASTName representing the name under the caret (if any).
Use IASTName.resolveBinding() to get the binding (C++ semantic model object) that the name refers to.
Check if the binding implements IFunction.
All of this will go in your implementation of IActionFilter.testAttribute(). The target parameter to that function will be the IEditorInput. For good measure, you should check that the name and value parameters correspond to the attribute names you invented (selectedElementType and function) before doing any of this (initially, your action filter will only be invoked by your <filter> element, so they'll always match, but you can imagine extending this mechanism in the future to e.g. support other selected element types.)
Finally, a note on performance: what you're doing here is conditioning the responsiveness of a UI element (the appearance of a popup) on a property of C++ code, which can be slow to parse and analyze. This necessarily means your popup may take longer to appear as a result (which is reflected in your action filter needing to block on the SharedASTJob). By using SharedASTJob, you are minimizing this effect by re-using an already-parsed AST if there is one, but e.g. if you've just opened an editor and you right-click, and the initial AST takes several seconds to build, your popup will take several seconds to show up. Caveat emptor.

How are regular DOM Elements mutable?

In the react docs, they claim:
ReactElements are not to be confused with DOM Elements. A ReactElement
is a light, stateless, immutable, virtual representation of a DOM
Element.
Does this imply that a regular DOM element can be mutated? And if so, can you give an example of how you can mutate a DOM element, but the same code applied to a ReactElement would not mutate it?
I think you may be reading too deep into that statement. I believe by the word immutable, the ReactJS documentation is saying that "this will not change between the moment we define to the moment that we use it".
I believe this comes from other frameworks such as old version of ASP.NET that changed the DOM object ID and changed other aspects of the DOM element created between the moment of creation and the moment of usage in the DOM.
However, this element can still be modified once it is actually rendered onto the DOM as a regular HTML element by jQuery. The beauty and downside to the DOM is that once anything is placed into the DOM, the validity of that data cannot be trusted. At the end of the day, it's just a document. Hopefully, that helps.
React components can be modified by props or state. State is internal to the component. Props are passed from the parent component. Any mutations on DOM should be made via props or state changes. Though some jQuery code works with React, it is highly discouraged.
After more research, I think this has to do with the virtual DOM.
The virtual DOM is all about "diffing" to find the differences (if any) among its ReactElements. If ReactElements could be mutated, then the virtual DOM wouldn't need to diff, as the element would just mutate itself and that would be the current state of the virtual DOM. But the virtual DOM wants to diff, so rather than updating the existing ReactElement, what happens is you pass the virtual DOM a new version of that ReactElement. And updating itself to the most recent version (sort of like git I guess), the virtual DOM then updates the real DOM with the most recent version of itself.
The full flow looks something like this (I think)
React takes your stateful ReactComponent (i.e. it can be mutated), turns it into a statless ReactElement(s) (i.e. if something changes, it issues a new ReactElement rather than updating the old one), which are used to create your virtual DOM. If state changes in your ReactComponent, a new version of the corresponding ReactElements are created and sent to the virtual DOM. The virtual DOM runs the new version of the ReactElements against the old, updates itself, and then updates the real DOM.
Traditionally, with regular DOM elements and regular DOM, there is no diff occurring (and so you don't have two versions of DOM elements, new and old, you just have the one single version that you are mutating as you go). So instead of sending a new version of the DOM element to be diffed, you just update the existing DOM element.
further reading:
React Elements vs React Components vs Component Backing Instances

What underlying difference makes Node Instances appear different?

I have two similar (if not identical) node instances that are appearing differently in a deployment diagram (and anywhere else that I use them).
I may have done some odd things in the past while beating EA into submission.
But, now ... by pulling every lever I can imagine, I can't get them to appear the same (or behave the same). The one on the right is consistent with all the other nodes I have.
The colour is off and the "properties" (maybe they're tags?) showing in the body of the one on the left appear but I can't figure out where to edit / remove them.
I've tried:
Element ... Advanced ... Change type (Node --> Device and back to Node just to try and get it to 'forget' anything it's holding onto)
Remove & re-add stereotype to both the Node type (i.e. type from which instance was made) and the instance itself.
Creating a new instance from the same type, just to see what happens. It creates a node instance more like the one on the right.
Early on in developing this model, I created my own MDG technology. My guess is that the node on the left was created from a type in that MDG, which had some attributes available. It's conceivable to me that Sparx is hanging onto those attributes and not providing a way to edit because of the type was changed.
Any guidance on how to manipulate the under lying data (without creating a new node instance and replacing on all diagrams and re-configuring all relationships)?
Those are different elements. You see that the name (FQN) is different on both. Click each and issue Ctrl-G to locate them in the browser.
The green dot on top makes me think that you use your own MDG which puts the dot on <<SUSE>> stereotyped elements. So the MDG is likely what also makes them appear different depending on tagged values.
Regarding the Version and OS shown in the lower compartment of the left class: those are run states. You can edit them via Context/Features../Run State
For the colour of the element, I think what happened is this ... at some point, I selected (Element Context Menu) --> Appearance --> "Default Appearance" and clicked Reset to defaults. Even with a stereotype applied, this reverts to the "unstereotyped" appearance. I grabbed the RGB values from one the element on the right in the image and set the element on the left's values to those numbers and it's all consistent now.
The main question was the Run State variables, which #(Thomas Killian) addresses in another answer.

ExtJS: Component VS Element VS other

I've been working with ExtJS for a good few months now, but still don't have a perfectly clear map of what's going on behind the scenes there. I'm just talking about the building blocks of the framework and their most basic functionality.
Ext.Component
Ext.Element
DOM.Element
DOM.Node (?)
CompositeElement (?)
Whatever else (?)
For each of the abovementioned I would like to know:
How to select: by ID, by class, via parent, find (OR children OR query OR select? WTF), siblings, ComponentQuery, DOM-query, CSS-query, etc..
How to manipulate in the tree: create, append, prepend, insert after this sibling, move to that parent, remove, destroy, etc..
How to manipulate on the screen: show, hide, fade, slide, move up, down, change size, etc..
How to identify related to each other: find DOM.Element knowing its Ext.Component, find Ext.Component knowing its DOM.Element, etc..
What is the dependency between them: what happens to the DOM.Element if its Ext.Component is hidden / destroyed / changed / moved, what happens to the Ext.Component if its Ext.Element is hidden / destroyed / changed / moved, etc.
I'm looking for a methodical and logically clear layout of how each is supposed to be used and is expected to behave. I am also hoping that the described functionality can be grouped in corresponding categories, e.g. would be nice to see complement traversing methods .up() and .down() next to each other, rather than alphabetically pages apart. Of course links and examples (which the official documentation lacks so badly) are also welcome!
You can find out a whole lot about the building blocks of ExtJS (known as Ext Core) from the manual for this: http://docs.sencha.com/core/manual/. I will try to add some knowledge and highlight some key points, but you should definitely read through that for a very informative overview.
Ext.Component
The building block for the OOP paradigm within ExtJS. Essentially, this is an Object that contains inherited functionality to serve as the basis for a specialized component that will be transformed by the framework into DOM elements that are shown as HTML.
The Sencha documentation is excellent for this. Here are a couple good places to start:
http://docs.sencha.com/extjs/4.2.1/#!/guide/layouts_and_containers
http://docs.sencha.com/extjs/4.2.1/#!/guide/components
Ext.Element vs DOM Element
As an JavaScript develop knows, a DOM element is just a JS object that represents a tag in the document's HTML. Essentially, Ext.Element is a wrapper object for a DOM element that allows for ExtJS to manipulate the object. Any DOM element on the page can be wrapped as an Ext.Element to allow for this additional functionality.
For example, take this HTML tag:
<div id="myDiv">My content</div>
You can access this using
var el = document.getElementById('myDiv')
and use the basic, built-in JavaScript DOM functionality on el. You could also access this using
var el = Ext.get('myDiv')
and have a whole additional set of functionality available to apply to that element using the ExtJS library
The Sencha docs are also excellent for this. See all the available functionality for Ext.Element here: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.dom.Element
Misc
You can get an Ext.Element from a component using the getEl() method:
var myComponent = Ext.create('Ext.Component', { html: 'my component' });
var el = myComponent.getEl();
You would rarely need to go the other way, to determine a component from a DOM element. There isn't much of a use case there unless you are really hacking something. A major reason for using a framework like ExtJS is to prevent needing to do something like this; if should develop entirely within the JavaScript, you should be able to avoid having a reference to a DOM element where you need to get its containing ExtJS component.
Niklas answered pretty well about how to select components and elements. The only things I would really add is that you can use up() and down() to select relative to a component. In this way, you should use itemId on components rather than the global identifier id (using id can cause difficult-to-debug errors if you are reusing components with the same ID).
Also, to add to Niklas's answer about showing/hiding components, the framework does indeed add some CSS to the component's element, depending on what the hideMode for the component is. Learn more about that property here: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.AbstractComponent-cfg-hideMode
An excellent way to learn more is to look through all of the examples that come packaged with the framework. Open the examples in your browser, then look through the code to find out how things are done. You will find it way easier to learn this way, rather than reading it on paper or a website. Nothing beats experience when it comes to learning something new.
How to select: by ID, by class, via parent, find (OR children OR query OR select? WTF), siblings, ComponentQuery, DOM-query, CSS-query, etc..
Ext.ComponentQuery.query("*") // get all
Ext.ComponentQuery.query("button") // all buttons
Ext.ComponentQuery.query("#myid") // all controls / components myid
Ext.ComponentQuery.query("#myid", rootelement) // all controls / components myid with rootelement
Ext.ComponentQuery.query("#myid,button") // all buttons or controls / components myid
How to manipulate in the tree: create, append, prepend, insert after this sibling, move to that parent, remove, destroy, etc..
Adding button to a View:
Ext.ComponentQuery.query("#viewId")[0].add(new Ext.Button({ text: 'test'}));
There is also insert, remove and so on depending on the control you are querying.
How to manipulate on the screen: show, hide, fade, slide, move up, down, change size, etc..
Ext.ComponentQuery.query("button").forEach(function(button){ button.hide(); }) // hide all buttons
There is also show, disable, enable and so on depending on the control you are querying.
How to identify related to each other: find DOM.Element knowing its Ext.Component, find Ext.Component knowing its DOM.Element, etc..
Finding Ext.Component knowing its Dom.Element is pretty easy, you just take the ID from the DOM element and use Ext.ComponentQuery.query("#id").
There is also Ext.select('#id') for getting the object from an ID.
With the element property you can get the DOM:
var dom = Ext.ComponentQuery.query("button")[0].element.dom // Getting the DOM from the first button
var dom2 = component.element.dom // does also work as long as component is a valid sencha touch component
What is the dependency between them: what happens to the DOM.Element if its Ext.Component is hidden / destroyed / changed / moved, what happens to the Ext.Component if its Ext.Element is hidden / destroyed / changed / moved, etc.
I think, I'm not sure, that if you call .hide for instance there will be some CSS applied to the DOM for example: display: none. Internally they can use some framework like jQuery for that or the old school version document.getElementById('id').css and so one. If you call .show, it may change to display: block or whatever type it was before(this could be saved in the Sencha Touch class).
I don't know what happens if the DOM element gets destroyed. Probably the element too and then the garbage collector has some work to do.
If there are any more questions / something was unclear or not enough, don't hesitate to ask.
An attempt to answer the question myself.
Since there is no TABLE markup support on this website, I put my answer in this shared Spreadsheet. Note the comments on mouse rollover.
It's just a pattern for now. It needs work to get more legible and complete. Feel free to comment, or ask me if you would like to edit it.