/config/webview.lua

http://github.com/mason-larobina/luakit · Lua · 350 lines · 231 code · 38 blank · 81 comment · 82 complexity · 0b0efca360248874636f5e3bc560787c MD5 · raw file

  1. --------------------------
  2. -- WebKit WebView class --
  3. --------------------------
  4. -- Webview class table
  5. webview = {}
  6. -- Table of functions which are called on new webview widgets.
  7. webview.init_funcs = {
  8. -- Set useragent
  9. set_useragent = function (view, w)
  10. view.user_agent = globals.useragent
  11. end,
  12. -- Check if checking ssl certificates
  13. checking_ssl = function (view, w)
  14. local ca_file = soup.ssl_ca_file
  15. if ca_file and os.exists(ca_file) then
  16. w.checking_ssl = true
  17. end
  18. end,
  19. -- Update window and tab titles
  20. title_update = function (view, w)
  21. view:add_signal("property::title", function (v)
  22. w:update_tablist()
  23. if w.view == v then
  24. w:update_win_title()
  25. end
  26. end)
  27. end,
  28. -- Update uri label in statusbar
  29. uri_update = function (view, w)
  30. view:add_signal("property::uri", function (v)
  31. w:update_tablist()
  32. if w.view == v then
  33. w:update_uri()
  34. end
  35. end)
  36. end,
  37. -- Update history indicator
  38. hist_update = function (view, w)
  39. view:add_signal("load-status", function (v, status)
  40. if w.view == v then
  41. w:update_hist()
  42. end
  43. end)
  44. end,
  45. -- Update tab titles
  46. tablist_update = function (view, w)
  47. view:add_signal("load-status", function (v, status)
  48. if status == "provisional" or status == "finished" or status == "failed" then
  49. w:update_tablist()
  50. end
  51. end)
  52. end,
  53. -- Update scroll widget
  54. scroll_update = function (view, w)
  55. view:add_signal("expose", function (v)
  56. if w.view == v then
  57. w:update_scroll()
  58. end
  59. end)
  60. end,
  61. -- Update progress widget
  62. progress_update = function (view, w)
  63. for _, sig in ipairs({"load-status", "property::progress"}) do
  64. view:add_signal(sig, function (v)
  65. if w.view == v then
  66. w:update_progress()
  67. w:update_ssl()
  68. end
  69. end)
  70. end
  71. end,
  72. -- Display hovered link in statusbar
  73. link_hover_display = function (view, w)
  74. view:add_signal("link-hover", function (v, link)
  75. if w.view == v and link then
  76. w:update_uri(link)
  77. end
  78. end)
  79. view:add_signal("link-unhover", function (v)
  80. if w.view == v then
  81. w:update_uri()
  82. end
  83. end)
  84. end,
  85. -- Clicking a form field automatically enters insert mode.
  86. form_insert_mode = function (view, w)
  87. view:add_signal("button-press", function (v, mods, button, context)
  88. -- Clear start search marker
  89. (w.search_state or {}).marker = nil
  90. if button == 1 and context.editable then
  91. view:emit_signal("form-active")
  92. end
  93. end)
  94. -- Emit root-active event in button release to prevent "missing"
  95. -- buttons or links when the input bar hides.
  96. view:add_signal("button-release", function (v, mods, button, context)
  97. if button == 1 and not context.editable then
  98. view:emit_signal("root-active")
  99. end
  100. end)
  101. view:add_signal("form-active", function ()
  102. if not w.mode.passthrough then
  103. w:set_mode("insert")
  104. end
  105. end)
  106. view:add_signal("root-active", function ()
  107. if w.mode.reset_on_focus ~= false then
  108. w:set_mode()
  109. end
  110. end)
  111. end,
  112. -- Catch keys in non-passthrough modes
  113. mode_key_filter = function (view, w)
  114. view:add_signal("key-press", function ()
  115. if not w.mode.passthrough then
  116. return true
  117. end
  118. end)
  119. end,
  120. -- Try to match a button event to a users button binding else let the
  121. -- press hit the webview.
  122. button_bind_match = function (view, w)
  123. view:add_signal("button-release", function (v, mods, button, context)
  124. (w.search_state or {}).marker = nil
  125. if w:hit(mods, button, { context = context }) then
  126. return true
  127. end
  128. end)
  129. end,
  130. -- Reset the mode on navigation
  131. mode_reset_on_nav = function (view, w)
  132. view:add_signal("load-status", function (v, status)
  133. if status == "provisional" and w.view == v then
  134. if w.mode.reset_on_navigation ~= false then
  135. w:set_mode()
  136. end
  137. end
  138. end)
  139. end,
  140. -- Domain properties
  141. domain_properties = function (view, w)
  142. view:add_signal("load-status", function (v, status)
  143. if status ~= "committed" or v.uri == "about:blank" then return end
  144. -- Get domain
  145. local domain = lousy.uri.parse(v.uri).host
  146. -- Strip leading www.
  147. domain = string.match(domain or "", "^www%.(.+)") or domain or "all"
  148. -- Build list of domain props tables to join & load.
  149. -- I.e. for luakit.org load .luakit.org, luakit.org, .org
  150. local props = {domain_props.all or {}, domain_props[domain] or {}}
  151. repeat
  152. table.insert(props, 2, domain_props["."..domain] or {})
  153. domain = string.match(domain, "%.(.+)")
  154. until not domain
  155. -- Join all property tables
  156. for k, v in pairs(lousy.util.table.join(unpack(props))) do
  157. info("Domain prop: %s = %s (%s)", k, tostring(v), domain)
  158. view[k] = v
  159. end
  160. end)
  161. end,
  162. -- Action to take on mime type decision request.
  163. mime_decision = function (view, w)
  164. -- Return true to accept or false to reject from this signal.
  165. view:add_signal("mime-type-decision", function (v, uri, mime)
  166. info("Requested link: %s (%s)", uri, mime)
  167. -- i.e. block binary files like *.exe
  168. --if mime == "application/octet-stream" then
  169. -- return false
  170. --end
  171. end)
  172. end,
  173. -- Action to take on window open request.
  174. --window_decision = function (view, w)
  175. -- view:add_signal("new-window-decision", function (v, uri, reason)
  176. -- if reason == "link-clicked" then
  177. -- window.new({uri})
  178. -- else
  179. -- w:new_tab(uri)
  180. -- end
  181. -- return true
  182. -- end)
  183. --end,
  184. create_webview = function (view, w)
  185. -- Return a newly created webview in a new tab
  186. view:add_signal("create-web-view", function (v)
  187. return w:new_tab()
  188. end)
  189. end,
  190. -- Creates context menu popup from table (and nested tables).
  191. -- Use `true` for menu separators.
  192. --populate_popup = function (view, w)
  193. -- view:add_signal("populate-popup", function (v)
  194. -- return {
  195. -- true,
  196. -- { "_Toggle Source", function () w:toggle_source() end },
  197. -- { "_Zoom", {
  198. -- { "Zoom _In", function () w:zoom_in() end },
  199. -- { "Zoom _Out", function () w:zoom_out() end },
  200. -- true,
  201. -- { "Zoom _Reset", function () w:zoom_set() end }, }, },
  202. -- }
  203. -- end)
  204. --end,
  205. -- Action to take on resource request.
  206. resource_request_decision = function (view, w)
  207. view:add_signal("resource-request-starting", function(v, uri)
  208. info("Requesting: %s", uri)
  209. -- Return false to cancel the request.
  210. end)
  211. end,
  212. }
  213. -- These methods are present when you index a window instance and no window
  214. -- method is found in `window.methods`. The window then checks if there is an
  215. -- active webview and calls the following methods with the given view instance
  216. -- as the first argument. All methods must take `view` & `w` as the first two
  217. -- arguments.
  218. webview.methods = {
  219. -- Reload with or without ignoring cache
  220. reload = function (view, w, bypass_cache)
  221. if bypass_cache then
  222. view:reload_bypass_cache()
  223. else
  224. view:reload()
  225. end
  226. end,
  227. -- Toggle source view
  228. toggle_source = function (view, w, show)
  229. if show == nil then
  230. view.view_source = not view.view_source
  231. else
  232. view.view_source = show
  233. end
  234. view:reload()
  235. end,
  236. -- Zoom functions
  237. zoom_in = function (view, w, step, full_zoom)
  238. view.full_content_zoom = not not full_zoom
  239. step = step or globals.zoom_step or 0.1
  240. view.zoom_level = view.zoom_level + step
  241. end,
  242. zoom_out = function (view, w, step, full_zoom)
  243. view.full_content_zoom = not not full_zoom
  244. step = step or globals.zoom_step or 0.1
  245. view.zoom_level = math.max(0.01, view.zoom_level) - step
  246. end,
  247. zoom_set = function (view, w, level, full_zoom)
  248. view.full_content_zoom = not not full_zoom
  249. view.zoom_level = level or 1.0
  250. end,
  251. -- History traversing functions
  252. back = function (view, w, n)
  253. view:go_back(n or 1)
  254. end,
  255. forward = function (view, w, n)
  256. view:go_forward(n or 1)
  257. end,
  258. }
  259. function webview.methods.scroll(view, w, new)
  260. local s = view.scroll
  261. for _, axis in ipairs{ "x", "y" } do
  262. -- Relative px movement
  263. if rawget(new, axis.."rel") then
  264. s[axis] = s[axis] + new[axis.."rel"]
  265. -- Relative page movement
  266. elseif rawget(new, axis .. "pagerel") then
  267. s[axis] = s[axis] + math.ceil(s[axis.."page_size"] * new[axis.."pagerel"])
  268. -- Absolute px movement
  269. elseif rawget(new, axis) then
  270. local n = new[axis]
  271. if n == -1 then
  272. s[axis] = s[axis.."max"]
  273. else
  274. s[axis] = n
  275. end
  276. -- Absolute page movement
  277. elseif rawget(new, axis.."page") then
  278. s[axis] = math.ceil(s[axis.."page_size"] * new[axis.."page"])
  279. -- Absolute percent movement
  280. elseif rawget(new, axis .. "pct") then
  281. s[axis] = math.ceil(s[axis.."max"] * (new[axis.."pct"]/100))
  282. end
  283. end
  284. end
  285. function webview.new(w)
  286. local view = widget{type = "webview"}
  287. view.show_scrollbars = false
  288. view.enforce_96_dpi = false
  289. -- Call webview init functions
  290. for k, func in pairs(webview.init_funcs) do
  291. func(view, w)
  292. end
  293. return view
  294. end
  295. -- Insert webview method lookup on window structure
  296. table.insert(window.indexes, 1, function (w, k)
  297. if k == "view" then
  298. local view = w.tabs[w.tabs:current()]
  299. if view and type(view) == "widget" and view.type == "webview" then
  300. w.view = view
  301. return view
  302. end
  303. end
  304. -- Lookup webview method
  305. local func = webview.methods[k]
  306. if not func then return end
  307. local view = w.view
  308. if view then
  309. return function (_, ...) return func(view, w, ...) end
  310. end
  311. end)
  312. -- vim: et:sw=4:ts=8:sts=4:tw=80