It is currently Thu May 23, 2013 11:27 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Access JavaScript functions in WebGadget on Linux
PostPosted: Sat Jan 10, 2009 3:27 am 
Offline
User
User
User avatar

Joined: Sun Feb 26, 2006 3:43 am
Posts: 55
Location: Missouri, United States
After many hours digging through XPCOM, C++ function mangling and blasphemously undocumented Mozilla functions - I finally have a working ExecuteJavaScript() hack for the Linux WebGadget. Although it doesn't use XPCOM or any magic, or for that matter even play with the gtk_moz_embed_*_() API functions. In theory it could be completely cross platform, in practice the win32 IWebBrowser2 object doesn't get the change to the document title until after a return to the programs event loop. Somebody let me know if it works on Mac?
Identical interface as Freak's win32 library, except this one adds an optional timeout value in case the function never returns. This is necessary to prevent lock-ups if an unforseen error occurs and the title never changes.

Code:
; Linux PB 4.30
; Tested on Slackware 11

Prototype.s ProtoExecuteJavaScript(gadget, Function$, Arguments$, Separator$, timeout=5000)

JSMutex = CreateMutex()

Procedure.s JavaScriptQuote(code.s)
  code = ReplaceString(code, "\", "\\")
  code = ReplaceString(code, Chr(34), "\"+Chr(34))
  ProcedureReturn Chr(34)+code+Chr(34)
EndProcedure

Procedure.l JavaScriptResetTitle(gadget.l)
   Shared JSMutex
   LockMutex(JSMutex)
   SetGadgetText(gadget, "javascript:void(function(){document.title='';})();")
   UnlockMutex(JSMutex)
EndProcedure

Procedure JavaScriptExamineThread(gadget.l)
   title.s = ""
  Repeat
    title = GetGadgetItemText(gadget, #PB_Web_PageTitle)
    If title = ""
      Delay(100)
    EndIf
  Until title > ""
EndProcedure

Procedure.s ProcExecuteJavaScript(gadget, Function$, Arguments$, Separator$, timeout)
  Shared JSMutex
  If GadgetType(gadget) <> #PB_GadgetType_Web
    ProcedureReturn ""
  EndIf
  code.s = ""
  If Trim(Arguments$) = ""
    code = ""
  ElseIf Seperator$ = ""
    code = JavaScriptQuote(Arguments$)
  Else           
    Count = CountString(Arguments$, Separator$)+1
    For i = 1 To Count           
      code = code + JavaScriptQuote(StringField(Arguments$, i, Separator$))
      If i <> Count
        code = code + ","
      EndIf
    Next i
  EndIf
  code = Function$+"("+code+");"
 
  JavaScriptResetTitle(gadget)
  LockMutex(JSMutex)
  code = JavaScriptQuote(code)
  js.s = "javascript:void(function(){document.title='';try{var ret = eval("+code
  js = js + ");document.title=ret;}catch(e){document.title='exception: '+e;}})();"
  SetGadgetText(gadget, js)
   thread = CreateThread(@JavaScriptExamineThread(), gadget)
   If thread <> 0
      WaitThread(thread, timeout)
   EndIf
  UnlockMutex(JSMutex)
  title.s = GetGadgetItemText(gadget, #PB_Web_PageTitle)
  ProcedureReturn title
EndProcedure

ExecuteJavaScript.ProtoExecuteJavaScript = @ProcExecuteJavaScript()

#URL = "file:////somewhere.html"

Enumeration
  #Gadget_Web
  #Gadget_Command
  #Gadget_Args
  #Gadget_Text
  #Gadget_Button
EndEnumeration

Procedure Resize()
  Width = WindowWidth(0)
  Height = WindowHeight(0)
  ResizeGadget(#Gadget_Web, 5, 5, Width-10, Height-60)
  ResizeGadget(#Gadget_Command, 5, Height-50, (Width-105)/4, 20)
  ResizeGadget(#Gadget_Args, 10+(Width-105)/4, Height-50, ((Width-105)*3)/4, 20)
  ResizeGadget(#Gadget_Text, 5, Height-25, Width-10, 20)
  ResizeGadget(#Gadget_Button, Width-90, Height-50, 85, 20)
EndProcedure

If OpenWindow(0, 0, 0, 800, 600, "Javascript test", #PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_MaximizeGadget|#PB_Window_MinimizeGadget)
    WebGadget(#Gadget_Web, 0, 0, 0, 0, #URL)
    StringGadget(#Gadget_Command, 0, 0, 0, 0, "prompt")
    StringGadget(#Gadget_Args, 0, 0, 0, 0, "So what will it be?,2 Beers")
    TextGadget(#Gadget_Text, 0, 0, 0, 0, "Type commandname into the first, and arguments into the second box. Do not include ()", #PB_Text_Border)
    ButtonGadget(#Gadget_Button, 0, 0, 0, 0, "Execute")
    Resize()
   
    Repeat
      Event = WaitWindowEvent()
      If Event = #PB_Event_SizeWindow
        Resize()
      ElseIf Event = #PB_Event_Gadget And EventGadget() = #Gadget_Button
        Command$ = GetGadgetText(#Gadget_Command)
        Arguments$ = GetGadgetText(#Gadget_Args)
        Result$ = ExecuteJavaScript(#Gadget_Web, Command$, Arguments$, ",")           
        SetGadgetText(#Gadget_Text, "Result: "+Result$)         
      EndIf
    Until Event = #PB_Event_CloseWindow
EndIf

End


Actually, the example given is a prompt() function, which happens to be one of the only things that doesn't work well (modal dialogs.)

Cheers.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 10, 2009 3:41 am 
Offline
Addict
Addict
User avatar

Joined: Wed Feb 28, 2007 9:13 am
Posts: 923
Location: Edinburgh
Thankyou very much for this. At present I don't have a Linux computer and have never coded for Linux, but I'm sure that in the future this code will be very useful for me.

Thanks again!

Seymour.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye