Can't target multiple iframes by width in Watir - iframe

require 'watir'
#browser = Watir::Browser.new #:phantomjs (same for firefox)
#browser.window.maximize
#browser.goto 'http://www.romnation.net/'
a = #browser.iframes(width: '160')
puts a[0].width
Which returns 728. Even though I explicitly stated that I only want iframes of width 160.
a = #browser.iframe(width: '160')
puts a.width
This returns 160, as expected.
Why is that, how do I target multiple iframes of certain width? (except for checking every iframe for its width)

This looks like a bug in IFrameCollection#to_a
IFrameCollection#elements is collecting the proper subset of iframes, but using the index number of the subset on the overall list of iframes it finds on the page. I'll spend some time on it this weekend. When I make a pull request I'll link it here.
In the meantime, this "works" but isn't ideal because it gives you an Element and not an IFrame:
iframes = browser.elements(css: "iframe[width='160']")
iframes.first.attribute_value('width') => 160

Related

Read pdf page size on .NET Core

I have only one requirement. I need to read PDF page size and determine if page is not bigger then 17x17 inches to not send it to some external service which rejects such pdfs.
Is there any free library working on .NET Core? I wasn't able to find it. Or maybe anyone implemented this by reading binary file?
A pdf does not HAVE TO declare page size externally since every page can be a different size thus 100 pages may be 100 different page sizes.
However many PDF will contain a text entry for one or more pages so you can (depending on construction) parse as text for /MediaBox and or potentially /CropBox dimensions.
So the first PDF example I pick on and open to search for /MediaBox in WordPad tells me its 210 mm x 297 mm (i.e my local A4) /MediaBox [0 0 594.95996 841.91998] and for a 3 page file all 3 entries are the same.
you can try that using command line as
type "filename.pdf" | find /i "/media"
but may not work in all cases so a bigger chance of result (but more chaff) is
type "filename.pdf" | findstr /i "^/media ^/crop"
The value is based on the default number of point size units per inch (so can be divided by 72 as a rough guide), however, thats not your aim since you know you dont want more that 17x72=1224.
So in simple terms, if either value was over 1224 then I could reject as "TOO BIG".
HOWEVER I need to also consider those two 0 values, thus if one was +100 then the limit becomes 100 more and more importantly, if one was -100 then your desired 17" restriction will fail at 1124.
So you can write in any method or language (even CMD) a simple test, however, that will require too much expanding to cover all cases, SO:-
Seriously I would use / shell a one line command tool like xpdf/poppler pdfinfo to parse all different types of PDF and then grep that output.
The output is similar for both with many lines but for your need
xpdf\pdfinfo -box filename
gives Page size: 594.96 x 841.92 pts (A4) (rotated 0 degrees)
and
poppler\pdfinfo -box filename
gives Page size: 594.96 x 841.92 pts (A4)
Thus to check the file does not exceed 17" (in either direction) it should be easy to set a comparison testing that both values are under 1224.01

Explanation of "hardcoded" font on a piece of text, and how to remove it via CSS etc

I'm unable to understand how a piece of text has some kind of hardcoded font in it, that cannot be removed even after pasting into an RTE, application of CSS etc. See 2 examples below copied from various places:
Sample 1 - this font is apparently Cambria Math, and will not / cannot be overridden by CSS when displaying or removed when pasting into an RTE. Eg take this text and dump into CKEditor, QuillJS and any other, it will remain the same. In fact the same is happening right here in this editor - the font is not getting removed, and I'm unable to explain why.
𝐈𝐧𝐝𝐮𝐬𝐭𝐫𝐲 𝐚𝐧𝐚𝐥𝐲𝐬𝐢𝐬 𝐢𝐬 𝐚 𝐜𝐫𝐮𝐜𝐢𝐚𝐥 𝐬𝐭𝐞𝐩 𝐢𝐧 𝐭𝐡𝐞 𝐜𝐮𝐫𝐫𝐞𝐧𝐭 𝐜𝐨𝐦𝐩𝐞𝐭𝐢𝐭𝐢𝐯𝐞 𝐦𝐚𝐫𝐤𝐞𝐭 𝐬𝐩𝐚𝐜𝐞 𝐭𝐡𝐚𝐭 𝐡𝐞𝐥𝐩𝐬 𝐢𝐝𝐞𝐧𝐭𝐢𝐟𝐲 𝐭𝐡𝐞 𝐫𝐢𝐠𝐡𝐭 𝐭𝐚𝐫𝐠𝐞𝐭 𝐜𝐮𝐬𝐭𝐨𝐦𝐞𝐫𝐬 𝐚𝐧𝐝 𝐚𝐜𝐜𝐨𝐫𝐝𝐢𝐧𝐠𝐥𝐲 𝐩𝐫𝐨𝐯𝐢𝐝𝐞 𝐭𝐚𝐢𝐥𝐨𝐫𝐞𝐝 𝐬𝐨𝐥𝐮𝐭𝐢𝐨𝐧𝐬 𝐟𝐨𝐫 𝐭𝐡𝐞𝐢𝐫 𝐛𝐮𝐬𝐢𝐧𝐞𝐬𝐬 𝐧𝐞𝐞𝐝𝐬. 𝐄𝐯𝐞𝐫𝐲 𝐚𝐬𝐩𝐞𝐜𝐭 𝐚𝐧𝐝 𝐮𝐧𝐢𝐪𝐮𝐞 𝐜𝐡𝐚𝐥𝐥𝐞𝐧𝐠𝐞𝐬 𝐩𝐮𝐭 𝐮𝐩 𝐛𝐲 𝐭𝐡𝐞 𝐩𝐚𝐫𝐭𝐢𝐜𝐮𝐥𝐚𝐫 𝐢𝐧𝐝𝐮𝐬𝐭𝐫𝐲 𝐚𝐫𝐞 𝐜𝐚𝐫𝐞𝐟𝐮𝐥𝐥𝐲 𝐭𝐚𝐤𝐞𝐧 𝐢𝐧𝐭𝐨 𝐜𝐨𝐧𝐬𝐢𝐝𝐞𝐫𝐚𝐭𝐢𝐨𝐧 𝐰𝐡𝐢𝐥𝐞 𝐟𝐨𝐫𝐦𝐮𝐥𝐚𝐭𝐢𝐧𝐠 𝐭𝐡𝐞𝐬𝐞 𝐬𝐨𝐥𝐮𝐭𝐢𝐨𝐧𝐬. 𝐈𝐭 𝐚𝐥𝐬𝐨 𝐭𝐚𝐤𝐞𝐬 𝐢𝐧𝐭𝐨 𝐜𝐨𝐧𝐬𝐢𝐝𝐞𝐫𝐚𝐭𝐢𝐨𝐧 𝐯𝐚𝐫𝐢𝐨𝐮𝐬 𝐠𝐨𝐯𝐞𝐫𝐧𝐦𝐞𝐧𝐭 𝐫𝐞𝐟𝐨𝐫𝐦𝐬, 𝐜𝐨𝐦𝐩𝐞𝐭𝐢𝐭𝐢𝐯𝐞 𝐞𝐧𝐯𝐢𝐫𝐨𝐧𝐦𝐞𝐧𝐭, 𝐜𝐮𝐬𝐭𝐨𝐦𝐞𝐫 𝐛𝐞𝐡𝐚𝐯𝐢𝐨𝐫, 𝐞𝐱𝐢𝐬𝐭𝐢𝐧𝐠 𝐚𝐧𝐝 𝐮𝐩𝐜𝐨𝐦𝐢𝐧𝐠 𝐛𝐮𝐬𝐢𝐧𝐞𝐬𝐬 𝐦𝐨𝐝𝐞𝐥𝐬, 𝐚𝐧𝐝 𝐞𝐯𝐞𝐫-𝐞𝐯𝐨𝐥𝐯𝐢𝐧𝐠 𝐭𝐞𝐜𝐡𝐧𝐨𝐥𝐨𝐠𝐢𝐜𝐚𝐥 𝐝𝐞𝐯𝐞𝐥𝐨𝐩𝐦𝐞𝐧𝐭𝐬. 𝐈𝐧𝐝𝐮𝐬𝐭𝐫𝐲 𝐚𝐧𝐚𝐥𝐲𝐬𝐢𝐬 𝐡𝐞𝐥𝐩𝐬 𝐚𝐧 𝐨𝐫𝐠𝐚𝐧𝐢𝐳𝐚𝐭𝐢𝐨𝐧 𝐟𝐨𝐫𝐦𝐮𝐥𝐚𝐭𝐞 𝐬𝐭𝐫𝐚𝐭𝐞𝐠𝐢𝐞𝐬 𝐚𝐧𝐝 𝐩𝐨𝐥𝐢𝐜𝐢𝐞𝐬 𝐨𝐟 𝐚 𝐛𝐮𝐬𝐢𝐧𝐞𝐬𝐬.
Sample 2 - this is how it should be. When rendered the target CSS font is used.
Allowing PUT as create operations is problematic, as it necessarily exposes information about the existence or non-existence of objects. It's also not obvious that transparently allowing re-creating of previously deleted instances is necessarily a better default behavior than simply returning 404 responses.
More info if needed:
I saw this occur here https://www.althealth.me/topics/792/article/2888/rigid-knee-braces-market-is-expected-to-. This is an instance on the MainCross platform which is created by me.

Updating gWidgets elements in R

I'm having trouble updating graphical elements in R and I can't figure it out. I'd appreciate a little push.
I'm trying to make a simple GUI which is prepopulated with some options, but when a button is pressed the database is queried (the query is modified by the GUI), and the result needs to change what's available in the gcomboboxes and gtables. I'm frankly amazed at how simple it is to create such an excellent environment in R.
I don't believe I can modify the body of gcomboboxes or gtables once they're on screen (if I can, that's probably my preferred solution). I also don't believe I can destroy individual elements of a glayout, only the entire glayout. But how do I get it back in the right order?
# Small example for GUI element creation and destruction
if(!require("RGtk2")) {library("RGtk2")}
if(!require("digest")) {library("digest")}
if(!require("cairoDevice")) {library("cairoDevice")}
if(!require("gWidgets")) {library("gWidgets")}
if(!require("gWidgetsRGtk2")) {library("gWidgetsRGtk2")}
nw<-gwindow("Test",toolkit=guiToolkit("RGtk2"))
g<-ggroup(horizontal=FALSE,cont=nw)
t1<-glayout(container=g) # Header
t2<-glayout(container=g) # Dynamic middle
t3<-glayout(container=g) # Footer
t1[1,1]<-gcombobox(c("foo","bar"))
t1[1,2]<-gbutton("Update")
t2[1,1]<-gframe("",container=t2)
t2[2,1]<-gcombobox(c("violin","metal"))
t2[3,1]<-gtable(c("YoYoMa","Metallica"))
t3[1,1]<-glabel("Filler text",container=t3)
delete(g,t2) # Unable to delete t2[2,1] and t2[3,1]
t2<-glayout(container=g)
#t2[2,1]<-gcombobox(c("violin","metal","pop")) ### Nope...
#t2[3,1]<-gtable(c("YoYoMa","Metallica","UB40"))
#add(t2,gcombobox(c("violin","metal","pop"))) ### Nope...
#add(t2,gtable(c("YoYoMa","Metallica","UB40")))
All my added elements go below my footer text. How do I straighten it out so they go between the header and footer?
If I don't delete the glayout, it looks like I can modify the contents of the gcombobox, but the UI doesn't really reflect it. I can see new text when I click the arrow, but the selection no longer appears to change.
...
t2[2,1]<-gcombobox(c("text to remove","violin","metal"))
t2[3,1]<-gtable(c("YoYoMa","Metallica"))
t3[1,1]<-glabel("Filler text",container=t3)
t2[2,1]<-gcombobox(c("violin","metal","pop")) # "text to remove" remains selected regardless of user input
t2[3,1]<-gtable(c("YoYoMa","Metallica","UB40"))
It was a little frustrating, but this is working well for me. I'll leave this solution here in case anybody else has trouble.
# Small example for GUI element creation and destruction
if(!require("RGtk2")) {library("RGtk2")}
if(!require("digest")) {library("digest")}
if(!require("cairoDevice")) {library("cairoDevice")}
if(!require("gWidgets")) {library("gWidgets")}
if(!require("gWidgetsRGtk2")) {library("gWidgetsRGtk2")}
nw<-gwindow("Test",toolkit=guiToolkit("RGtk2"))
g<-ggroup(horizontal=FALSE,cont=nw)
t1<-glayout(container=g) # Header
t2<-glayout(container=g) # Dynamic middle
t3<-glayout(container=g) # Footer
t1[1,1]<-gcombobox(c("foo","bar"))
t1[1,2]<-gbutton("Update")
t2[1,1]<-gframe("",container=t2)
t2[2,1]<-gcombobox(c("text to remove","violin","metal"))
t2[3,1]<-gtable(c("YoYoMa","Metallica"))
t2[3,1]<-gtable(BandList)
t3[1,1]<-glabel("Filler text",container=t3)
t2[2,1][]<-c("violin","metal","pop")
svalue(t2[2,1])<-"pop" #otherwise it's confused about defaults
t2[3,1][]<-c("YoYoMa","Metallica","UB40")
I found a way to edit the contents already on screen without needing to delete the screen elements.
# Small example for GUI element creation and destruction
if(!require("RGtk2")) {library("RGtk2")}
if(!require("digest")) {library("digest")}
if(!require("cairoDevice")) {library("cairoDevice")}
if(!require("gWidgets")) {library("gWidgets")}
if(!require("gWidgetsRGtk2")) {library("gWidgetsRGtk2")}
nw<-gwindow("Test",toolkit=guiToolkit("RGtk2"))
g<-ggroup(horizontal=FALSE,cont=nw)
t1<-glayout(container=g) # Header
t2<-glayout(container=g) # Dynamic middle
t3<-glayout(container=g) # Footer
t1[1,1]<-gcombobox(c("foo","bar"))
t1[1,2]<-gbutton("Update")
t2[1,1]<-gframe("",container=t2)
t2[2,1]<-gcombobox(c("text to remove","violin","metal"))
t2[3,1]<-gtable(c("YoYoMa","Metallica"))
t2[3,1]<-gtable(BandList)
t3[1,1]<-glabel("Filler text",container=t3)
t2[2,1][]<-c("violin","metal","pop")
svalue(t2[2,1])<-"pop" #otherwise it's confused about defaults
t2[3,1][]<-c("YoYoMa","Metallica","UB40")

Manipulating X11 window menu in a WM-agnostic way

Motif-based window managers (Mwm, Dtwm, 4Dwm, 5Dwm) allow custom menu items (with the corresponding callbacks) to be added to the application's window menu (see the screenshot, gist available here). The application itself is also required to link with -lXm (at least for XmAddProtocols() and XmAddProtocolCallback() to be available).
From the X Window perspective, this is achieved via a couple of extra Atoms set by the client:
_MOTIF_WM_MESSAGES(ATOM) = _MOTIF_WM_OFFSET, CUSTOM_MENU_ACTION_A, CUSTOM_MENU_ACTION_B
WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, _MOTIF_WM_MESSAGES
_MOTIF_WM_MENU(STRING) = "no-label f.separator\n
Custom\ Menu\ Title f.title\n
XTerm f.exec \"xterm &\"\n
Custom\ Menu\ Action\ A Shift Alt<Key>F1 f.send_msg 393\n
Custom\ Menu\ Action\ B Shift Alt<Key>F2 f.send_msg 394\n"
Apparently, this behavior is not supported by any of the modern EWMH-compliant window managers. Additionally, EWMH specification doesn't seem to provide any alternative.
Is there any non-Motif cross-WM way to manipulate the window menu (GTK, Qt or Xlib)?

JSNewtworkX stop layout

i'm using JSNetworkX for graph exploration and rendering.
JSNetworkX is using D3.js for graph render. However, as I work with large graph (json file about 5Mb), I would like to render this graph directly without any animations (so, in placing each node directly without force attraction).
I try to use D3.layout.force().stop() after rendering, but it's without effects.
Because of that, I'm thinking that it has to be done in jsnx.draw, see my code below.
jsnx.draw(G, {
element: 'body',
d3: d3,
layout_attr: {
charge: -1500,
linkDistance: 1,
gravity: 1,
friction: 0.4,
alpha: -100
},
});
force = d3.layout.force();
Unfortunately, you can't do that with the current version. Do you need a force layout at all or do you already have positions for each node? FWIW, if you really have a large graph, even a static layout would be slow, because you'd still have too many SVG elements. The next version will include a WebGL rendered for large graphs.
So, we can't for the moment.
As of v0.3.4, jsnx.draw returns the force layout object so you can do var force = jsnx.draw{/*...*/} then force.stop().

Resources