How to detect that a TVML lockup loses focus? - tvos

Is there a way to detect that a lockup loses focus when using TVML and TVMLKit JS on tvOS 12?
I know there's a highlight event when something receives focus using the following:
lockupElement.addEventListener("highlight", this.handleHighlight);
I want to handle when the lockup is no longer highlighted. The closest I've found to a solution is to add highlight-events to absolutely every other element and then reset any previously highlighted elements. This seems like a hack and it is also tedious and bug-prone adding it to every other element.
Anyone know of a better method?

If your lockup element is a custom element created through the extended interface creator you can override the didUpdateFocus(context, coordinator) function in your Swift class.
If it's just a default lockup I think you're out of luck.

Related

Programmatic focus of web components

What's the proper way to handle programmatic focus of web components?
Calling focus() on a web component should focus the appropriate element in the shadow DOM. This means overwriting the focus method.
This is not enough though, because the web browser is not aware that the component is interactive. One consequence it that clicking an anchor pointing to the element will not focus it as it would a native interactive html element like <button>. There may be other implications that I'm not aware of.
The only way I know to make an element interactive is to give it a tabindex value. But tabindex="0" will create an extra tab stop, while tabindex="-1" will remove all tab stops inside the component. So neither works. My next step is to set tabindex="0", then switch the value on focus() and blur(). It seems crazy to me that I have to do all this hacky work for such a basic requirement (making a web component properly interactive and accessible). Am I missing something? Is there a better solution?
I was missing something indeed. Web components have a specific API for this: delegatesFocus. MDN docs.
When set to true:
calling focus() on the host element brings the first focusable element within the shadow DOM into focus.
so does clicking inside the component on any non focusable element
the tab sequence is unchanged
:focus styles on the host are applied
It's part of the web components specs so no worries about support.

Moving components with bindings outside of their parent

In my project I'm working on styling some overlays. Because of the nested component structure I'm running into some problems here. The intended solution is to move the overlay somewhere closer to the app root while preserving data bindings, making the css styling less restricted.
I've managed to set up a prototype using Renderer2.appendChild(...). When the overlay is shown, the ngOnInit of the overlay appends the overlay to another DOM element.
With my current code I can either get the input or output binding to work (but not both), based on moving an empty comment <!----> found directly in front of the overlay.
From my understanding (Empty comments in Angular application) Angular needs this comment, but Renderer2.appendChild does not account for it (maybe it's not meant to be used for components, only for 'raw' html?).
Demo:
Here's the prototype presenting both issues I am stuck on: https://stackblitz.com/edit/angular-pg24om
Visibility of the overlays (shown below the labels) can be toggled with a button. The submit buttons inside the overlay logs the input to the console using an #Output event emitter. Pressing change text changes an #Input property.
Without moving the overlay, input and output binding works like expected.
Incorrect input binding: If I choose to move the empty <!----> comment together with the overlay, my input binding seems to stop working. Pressing Change text does not change the random number I pass to the component. Output binding still works fine in this scenario.
Incorrect destruction: If I don't move the empty comment, Angular fails to clean up the component when the visibility is hidden using the Toggle visiblity button. That said, while the component is alive both input and output binding remains functional.
If anyone knows how to get this to work, I'd greatly appreciate some help. I did see other methods of creating overlays using factory resolvers and detaching views, but being able to move the component while preserve bindings in the HTML template will save us a lot of time otherwise spent on changing a lot of components.
Edit: I forgot to mention that the error Error: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node. occurs when attempting to remove the overlay without the moved comment. Angular is attempting to delete a #comment element from the overlay, but it fails to do so because the comment is still in the div where the overlay template resides. That's the reason I tried to move the comment together with the overlay.

Emulate JavaScript events with developer tools?

Chrome (and Firefox) both have really awesome tools for changing the current state of an element, e.g. setting it to a hover state so you can examine/modify css:
The problem is that this doesn't seem to set off any JavaScript events.
I'm currently trying to style a tooltip, which is shown on hover. It's difficult to hover over the element manually as the tooltip dissapears when I take the mouse off of said element, and setting the state to hover in the developer tools doesn't seem to set off the jQuery events.
I'm having to resort to adding an ID on the element in the developer tools inspector, then doing the following in the console:
$("#custom-element-hover").mouseover();
Which feels wrong (and is a little cumbersome).
Is there a better way to do this that I don't know about?
In a simple situation I think it is often easier to use the console as you are doing. But within developer tools, you can also find the event listener code and set a breakpoint on it:
You then right click on this handler and do view source, unminimize the source with the {} button and set a breakpoint in this handler function.
If this handler function triggers on unrelated events then you may need to right click on it and make the breakpoint conditional or add Watch Expressions to see when you are at the correct event.
You could also use the same method of breakpoint setting to instead skip over a particular mouseout event.
I can share with what I do in this kind of situations. I open elements tab in chrome debugger and right click on target element. Then I choose "Copy CSS path"
If you do this you will get something like this
#mdhelp-tabs > li:nth-child(1)
And this string can actually be used as legimit selector for jQuery. So this
$("#mdhelp-tabs > li:nth-child(1)")
will give jquery object with target element of dom in it.
So you would not have to assign an ID to every single element you want to deal with.
I am not sure but you can use console to handle tooltip

Opting out of `dragenter` and `dragover` events (html5)

I have a collection of draggable "content" elements, and a root-level "feedback" UI element which is displayed above them to provide feedback during drag and drop.
The problem is, during the drag operation, hovering over the "feedback" element causes the dragenter and dragover events to be fired on that element, rather than the underlying content element. It effectively "blocks" the dragenter event from firing on the correct element.
Is there a way for an element to cancel, or "opt out" of a dragenter/dragover event? I could display the feedback element underneath the content, but I'd rather not do that.
jsFiddle: http://jsfiddle.net/jact8/1/
I'm using the HTML drag/drop API, not jQuery or anything like that.
I've created a new fiddle. I think you want to use currentTarget instead of target in your handler on the columns to ensure that the event you receive is from the element you added the listener to (column) rather than the element it originated from (italicised text). See explanation here (it's for ActionScript but I believe it's valid for JavaScript also).
I'm assuming the listener on the insertionCaret element is for debug purposes only and have removed it (let me know if I'm mistaken here). You won't receive the event if you don't listen for it so won't need to opt out of it!

What is the best approach to building a popup inside of Flash AS3

I am trying to accomplish an "imagemap" in flash where you click on different areas in the image and when you click on it, a popup (within flash) comes up showing more information about the object that was clicked on. The popup has a close button that can will then close the popup.
My biggest trouble is the way I have my code right now is when you click on a region of the map, it creates a popup on the fly, and then I use addChild(_myPopup) to add it to the display list. The problem with this approach for me, is that the Popup is now a Child of the button I just pressed, but this object organization doesn't really make sense to me. I'd like to have the popup not be a child of the button and it be on it's own layer or a child of the stage directly.
What is a good approach and code architecture for building such an organization of objects? I'm fairly new to AS3 and I've built some small applications but my knowledge is limited.
Thanks
UPDATE
ok looks like calling stage.addChild(myPopup) from inside the button works pretty well. Is this good practice?
Assuming you have a hierarchy that looks something like this:
stage
Main class
Image class
Button
It's good practice to never call upwards in the displaylist, every object only deals with it's children. Events however, are a nice way of communicating upwards. Have the Button dispatch an event, preferrably a custom one, then handle that using a listener in the main class that then deals with creating a popup on top of everything.
An often encountered practise to organize the layers of the visible application is:
stage
main class with all children
popup container
tooltip container
mouse cursor container (apparently not longer necessary since player 10 supports custom cursors)
So you create your popups always in the popup container above the main class. If you would have tooltips, they should go into the tooltip container. This approach guarantees that popups are always visible above the main app and tooltips are always visible on top of everything.