Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
How to use ui.Webview.evaluate_javascript()?
-
Hey everyone I made a ui application that opens uses a custom view with a webview with a few other textviews ,buttons, and etc to run js on the webpage presented on the webview and display the results on a textview.
In the docs it doesn’t explain how the js should be structured in order to get the results from the snippets used. So I was wondering if anyone can tell me how to correctly use the method?
I’m gonna include code from my application (excluding animation functions I use for each separate view) and I’ll wait for responses. I appreciate any help I can get, and thanks in advance!!!
class browser(ui.View): def did_load(self): self.html = 0 html_view = ui.load_view('html_view') self.add_subview(html_view) self['html_view'].x = 400 def go(self): v = self.superview url_bar = v['url input'] webview = v['webview1'] webview.load_url('http://'+url_bar.text) # this is located on a custom view that #is a subview to the view containing the webview class html_view(ui.View): #this is a button located on the subview #that initiates the "webview.evaluate_javascript()" method def runjs(self): #this is the subview v = self.superview #this is the main view bv = v.superview #the textview that the script is entered in script = v['js field'].text #the variable that contains the result of #the method result = bv['webview1'].evaluate_javascript(script) #Printing result for testing purposes print(result) #setting a textview to the result'' v['result'].text = result
-
@AceNinjaFire try this, then see the script, only as a small sample. Hoping it will help
Run it, wait some seconds and watch the topic scrolling and the avatars images# webview and its scrollview, download image, javascript import clipboard import console from objc_util import * import requests import ui class MyView(ui.View): def __init__(self,w,h): self.width = w self.height = h webview = ui.WebView() webview.frame = self.frame webview.delegate = self self.add_subview(webview) t = 'https://forum.omz-software.com/topic/' url = clipboard.get() if not url.startswith(t): url = t + '3317/introduction' webview.load_url(url) # get scrollview of webview via its ObjectiveC object self.scrollview = ObjCInstance(webview).subviews()[0].scrollView() # print html source file during tests #r = requests.get(url) #source =r.text #print(source) c = ui.Button(name='close') c.frame = (10,20,32,32) c.background_image = ui.Image.named('iob:ios7_close_outline_32') c.tint_color = 'red' c.action = self.close_button self.add_subview(c) b = ui.Button(name='avatar') d = 64 b.frame = (10,10,d,d) b.font =('Menlo',d/2) b.background_color = 'cyan' b.corner_radius = d/2 b.border_color ='blue' b.border_width = 1 b.hidden = True self.add_subview(b) self.top = 0 def close_button(self,sender): self.close() def webview_did_finish_load(self, webview): # search posts, users, profile images """ <div class="clearfix"> <div class="icon pull-left"> <a href="/user/xxxxxx"> <img src="yyyyyyyyyyyyy align="left" itemprop="image" /> </a> """ t_img = '<img src="' t_usr = '<a href="/user/' self.users = {} self.posts = {} # number of elements of class "icon pull-left" n_posts = int(webview.evaluate_javascript('document.getElementsByClassName("icon pull-left").length')) for i in range(0,n_posts): webview.evaluate_javascript('ele=document.getElementsByClassName("icon pull-left")['+str(i)+'];') html = webview.evaluate_javascript('ele.innerHTML') #print(html) i = html.find(t_usr) j = html.find('"',i+len(t_usr)) usr = html[i+len(t_usr):j] #print(usr) if usr not in self.users: i = html.find(t_img) j = html.find('"',i+len(t_img)) url = html[i+len(t_img):j] #print(url) if url[0] == '/': url = 'https://forum.omz-software.com' + url r = requests.get(url) image_data = r.content self.users[usr] = image_data o = int(webview.evaluate_javascript('ele.getBoundingClientRect().top')) self.posts[o] = usr self.update_interval = 1/60 def update(self): self.top = self.top + 1 self.scrollview.setContentOffset_(CGPoint(0,self.top)) if self.top in self.posts: usr = self.posts[self.top] #print(self.top,usr) if self.users[usr]: self['avatar'].title = '' self['avatar'].background_image = ui.Image.from_data(self.users[usr]) else: self['avatar'].title = usr siz = self['avatar'].width/2 while True: w,h = ui.measure_string(usr,font=('Menlo',siz)) #print(usr,siz,w,self['avatar'].width) if w < self['avatar'].width: self['avatar'].font = ('Menlo',siz) break siz = siz - 1 self['avatar'].background_image = None self['avatar'].hidden = False self['avatar'].y = 100 def main(): console.clear() w, h = ui.get_screen_size() disp = 'full_screen' back = MyView(w,h) back.background_color='white' back.present(disp, hide_title_bar=True) if __name__ == '__main__': main()
-
@AceNinjaFire Or it is better to try @mikael 's WKWebView
-
Damn!!!
Thank you!! I have no experience with using the objc_util module at all😅, but I’ll have to look at it now. You helped me solve a problem I was having lol, I appreciate it.
Would you know of a good tutorial for using the module? I’ve looked at the doc before but it’s not an easy read.
-
@AceNinjaFire said:
it’s not an easy read.
That's sure, at least 😀
I don't know any other doc but we learn by practicing or by finding some examples in this marvelous forum -
@AceNinjaFire I just wanted to delete my post because I told myself that it probably did not respond to your request ...Perhpas, it was a little bit too complex to start. Sorry for that.
-
You’re good lol. Complex or not I appreciate it, since the only way I’ll learn is by example or experimentation. I’m using the example you gave to reference to the objc_util module and what it does. I’m still far from understanding it but it’ll definitely be useful if it works the way I think it does.
EDIT: also you introduced a few ui functions I was unaware of which helped me solve another problem I was having lol. I really need to read the docs more completely going forward.
-
Was the original request how to get data back from a JavaScript script? Or how to execute any JavaScript at all? Are you still looking for an answer there?
-
@JonB You are right to ask it. That's the reason why I sincerely wanted to remove my post because I answered too quickly, but he seemed to be happy with my answer 😢 thus I could not remove it.
-
Yea that was my original question, but after looking at @cvp ‘s code I realized you had to structure it in a way to get the value normally (document.location.href) without assigning it to a value like (var url = document.location.href).
cvp answered my original question and answered a question I didn’t even have yet. So yea I was happy with it lol.
-
This post is deleted! -
By the way, if you ever need to communicate from JavaScript to python (for instance, if you are using JavaScript UI elements) you can implement a custom webview delegate. Also, if you are doing much js coding you may want to implement on_error logging... See
https://forum.omz-software.com/topic/1804/debugging-in-javascript-in-pythonista
-
Dang thanks man, and that’s definitely something I’ll look into. I’ve been looking for a reason to delve into js again after my initial dive into it. What types of projects have you done bridging the two together?