Following the question I would like to ask about the appropriate way to check the initial render status of a component (not the update status) in shadow DOM. Is there any similar to document.readyState or a promise?
I have also tried to do:
getItems() {
this.updateComplete
.then(() => {
this.nodesLists = this.shadowRoot.querySelectorAll(".name");
})
.then(...)
}
which also failed.
Tia
await this.updateComplete (or this.updateComplete.then(...)) is the correct way to wait until the element has no pending render work before e.g. querying the state of the element's rendering, so your code should generally work as long as the element is connected to the document before running getItems.
Example: https://jsbin.com/jiquhez/edit?html,console,output
Note however, that if you await updateComplete before the element is connected and the element has no properties set that would trigger a render, then updateComplete currently resolves before the first render. This may be considered an unintended bug, filed at lit-element/#594.
Note you may also want to look into using the firstUpdated lifecycle method, depending on your use case. This is a method you can implement on your class to perform one-time work following the first update/render cycle for the element (useful for e.g. selecting static nodes that won't change based on rendering).
Example: https://jsbin.com/limikas/edit?html,console,output
Surprisingly can't find this on google...
Can the name of a custom element (a la the Web Components set of W3C specs) contain unicode?
This HTML 5 Custom element names? says that a custom element name must begin with an ASCII character, contain a hyphen, and ANY OTHER characters. Does that mean unicode?
TL;DR This great article explains what characters are permitted in javascript. Unfortunately, those won’t work as expected with elements. At least, at the moment.
The reason is that document.registerElement which is being called on newly created custom elements, will fail:
var a = document.registerElement('a-ℵ');
//⇒ Uncaught SyntaxError: Failed to execute
// 'registerElement' on 'Document':
// Registration failed for type 'a-ℵ'.
// The type name is invalid.
That’s because registerElement tries to create internal constructor, different from generic function HTMLElement()/function HTMLUnknownElement() for registered elements:
console.log(document.registerElement('a-b'));
//⇒ function a-b() { [native code] }
I would suggest the internals of browsers are not yet ready for:
//⇒ function a-ℵ() { [native code] }
though you might easily specify:
var ℵ = function() { console.log('IT WORKS') };
ℵ();
//⇒ IT WORKS
I understand this is not exactly an answer you expected, but I hope it sheds some light.
I read the answer to Why am I getting an error when assigning tokens to a channel?.
The answer is that this is not an error, but a warning.
Well that's all very well, but the Eclipse IDE, https://github.com/jknack/antlr4ide, will not generate code when this warning is present.
Is there a way to not get a warning, when using a COMMENT channel?
You could trick the compiler by defining COMMENT in a tokens{} block instead of in the #members{} block. This would result in a constant value getting automatically assigned to it.
If you are also using the HIDDEN channel, I would include something like this to be safe:
#members {
{
if (HIDDEN == COMMENT) {
throw new IllegalStateException(
"Expected the HIDDEN and COMMENT constants to have different values.");
}
}
}
I am currently in the process of turning a sudoku solving program into a GUI with scala.swing and running into some trouble with the use of different functions. That is to say, I have a function for completely solving the puzzle, another for offering a hint entry, and another that will reset the grid. The interface consists of 81 individual ComboBox'es (see: http://i.imgur.com/45vzpei.png) and three buttons that perform said functions. My problem is that, while the separate reactions/cases involved reference specifically which buttons/functions to listen to, any button will incite all of the functions. My code for each of the listeners/buttons looks something like the following
listenTo(solve,comb11,comb12,comb13,comb14,comb15,comb16,comb17,comb18,comb19,comb21,comb22,comb23,comb24,comb25,comb26,comb27,comb28,comb29,comb31,comb32,comb33,comb34,comb35,comb36,comb37,comb38,comb39,comb41,comb42,comb43,comb44,comb45,comb46,comb47,comb48,comb49,comb51,comb52,comb53,comb54,comb55,comb56,comb57,comb58,comb59,comb61,comb62,comb63,comb64,comb65,comb66,comb67,comb68,comb69,comb71,comb72,comb73,comb74,comb75,comb76,comb77,comb78,comb79,comb81,comb82,comb83,comb84,comb85,comb86,comb87,comb88,comb89,comb91,comb92,comb93,comb94,comb95,comb96,comb97,comb98,comb99)
reactions += {
case ButtonClicked(solve) =>
...[working code for solve function]...
}
(The 'comb##'s are the exhaustive 81 ComboBoxes and the 'solve' is the button that solves the whole puzzle.) If I get rid of all but one of the listener/reaction blocks of code, clicking the remaining button works perfectly. If I try to include two or all of the listener/reaction code blocks, then every button causes ALL functions to be performed, which is clearly confusing and undesirable.
Not sure I understand your problem. But if you use lower case names in pattern matching extraction, these are fresh variables, and have nothing to do with values of the same name defined elsewhere. So to react to the solve button, you need to match against the value solve which you can do by putting it in back ticks:
listenTo(allMyButtons: _*)
reactions += {
case ButtonClicked(`solve`) => // note the back ticks!
...[working code for solve function]...
}
Otherwise, why don't you just keep each reaction with each combo box?
val combos = Vector.tabulate(81) { i =>
new ComboBox(1 to 9) {
listenTo(this)
reactions += {
case ButtonClicked(_) =>
... // not important to check the button - we only listen to one!
}
}
}
There is also a shorter way of defining the reaction to a pressed button.
import swing.{MainFrame, FlowPanel, Button}
val frame = new MainFrame {
contents = new FlowPanel {
contents += Button("solve")(println("solve"))
}
visible = true
}
I have a GUI, in it I have a properties window that opens in a new window. In some of the times, (randomly and not deterministicly reproducible) when I open the window it gives the fallowing error:
grab failed: window not viewable
It doesn't interfere with the normal function of the program nor doesn't seem to have any affect on anything besides printing that message.
The code for creating the new window is:
proc _prop_menu_make_top {{elem {}}} {
toplevel .prop_menu
#...initialize some variables...
wm title .prop_menu "Properties for $_prop_attr(name)"
#...create and display the window widgets...
bind .prop_menu <Key-KP_Enter> {_prop_menu_ok_button}
bind .prop_menu <Return> {_prop_menu_ok_button}
bind .prop_menu <Escape> {_prop_menu_cancel_button}
# catch presses on the window's `x` button
wm protocol .prop_menu WM_DELETE_WINDOW {
_prop_menu_cancel_button
}
# make the top window unusable
center_the_toplevel .prop_menu
focus .prop_menu.main_frame.model_name.entry
grab release .
grab set .prop_menu
}
proc center_the_toplevel { window } {
if { [string equal $window [winfo toplevel $window]] } {
set width [winfo reqwidth $window]
set height [winfo reqheight $window]
set x [expr {([winfo vrootwidth $window] - $width) / 2}]
set y [expr {([winfo vrootheight $window] - $height) / 2 }]
wm geometry $window +${x}+${y}
}
return
}
proc _prop_menu_ok_button {} {
#....saving the needed data...
_prop_menu_cancel_button
}
proc _prop_menu_cancel_button {} {
destroy .prop_menu
# make the top window usable again
grab set .
# redraw the canvas
nlv_draw
}
Does anyone has any idea as to what may be causing this problem?
Does anyone has any advice as to how make the bug easier to reproduse?
EDIT:
running Tcl version 8.4.6 for 64bit, don't know which tk version.
Explanation
For various reasons (some technical, some design principles), Tk only permits grabs to be set on windows that are mapped onto the screen. This is almost certainly what you want; mouse clicks should be going to a window you can see after all.
The problem you've got is that you're trying to do the grab too early. In particular, Tk postpones the creation of the underlying X11/OS window (depending on platform) for each widget until it has finished deciding what the configuration of that widget will be, which is taken to be when Tk becomes “idle”. Idle is defined to be when the event loop is entered and there are no pending events to be serviced. At that point, Tk tells the basic system graphics engine to allocate a rectangular chunk of screen estate (the window) and to put it on the screen. That in turn triggers a whole cascade of events and processing (there's a lot going on at that point) that ends up with the window being shown to you; it's only once the window is shown that you can set a grab on it.
So how do you know when you can set a grab? Well, you've got to wait for the window to turn up. That means waiting for an event: the key ones that you might care about for this task are <Map>, <Visibility> and <Expose>. They indicate respectively when the window is logically present within the root window, when there is a change in what is actually viewable, and when there is something to redraw. (There are equivalents on Windows to the first and last, which Tk remaps internally, but Windows doesn't tell you about actual visibility changes at all. Ever.)
Solution
The simplest way to wait for a widget to become grabbable (and then do the grabbing) is to use:
tkwait visibility $theWidget
grab set $theWidget
That just waits in the event loop for a <Visibility> event to turn up on that window. (It doesn't work on Windows though because of the absence of the event type on that platform.) You could rewrite the above as this:
bind $theWidget <Visibility> [list set waiting($theWidget) gotit]
vwait waiting($theWidget)
bind $theWidget <Visibility> {} ;# remove the binding again!
grab set $theWidget
If you're on Windows[*], you'll have to use that second technique, but replacing <Visibility> with <Map>.
bind $theWidget <Map> [list set waiting($theWidget) gotit]
vwait waiting($theWidget)
bind $theWidget <Map> {} ;# remove the binding again!
grab set $theWidget
I can't remember if <Expose> is available to scripts in Tk 8.4; that's an event that Tk handles for you normally. In any case, <Map> works and <Visibility> is perfect on X11.
You should also be aware that both tkwait and vwait can cause problems with reentrant event handling — you don't want it if you can help it! — so take care. You can deal with the problems by rewriting it all into continuation-passing style, which happens to be fairly easy in this case:
bind $theWidget <Map> {
bind %W <Map> {}
grab set %W
}
But if you're doing anything more than setting a grab, it can become really complex. (Tcl 8.6's coroutines can help untangle this mess, but they're definitely not portable to 8.4.)
[*] I forget whether there are issues round here with OSX with a non-X11 build of Tk. Check for yourself if you care.