Wed, 01 Sep 2010 04:03:42 +0100
Add note about required patch
-------------------------- -- WebKit WebView class -- -------------------------- -- Webview class table webview = {} -- Table of functions which are called on new webview widgets. webview.init_funcs = { -- Set global properties set_global_props = function (view, w) -- Set proxy options local proxy = globals.http_proxy or os.getenv("http_proxy") if proxy then view:set_prop('proxy-uri', proxy) end view:set_prop('user-agent', globals.useragent) -- Set ssl options if globals.ssl_strict ~= nil then view:set_prop('ssl-strict', globals.ssl_strict) end if globals.ca_file and os.exists(globals.ca_file) then view:set_prop('ssl-ca-file', globals.ca_file) -- Warning: update the following variable if 'ssl-ca-file' is -- changed anywhere else. w.checking_ssl = true end end, -- Update window and tab titles title_update = function (view, w) view:add_signal("property::title", function (v) w:update_tab_labels() if w:is_current(v) then w:update_win_title() end end) end, -- Update uri label in statusbar uri_update = function (view, w) view:add_signal("property::uri", function (v) w:update_tab_labels() if w:is_current(v) then w:update_uri(v) end end) end, -- Update scroll widget scroll_update = function (view, w) view:add_signal("expose", function (v) if w:is_current(v) then w:update_scroll(v) end end) end, -- Update progress widget progress_update = function (view, w) for _, sig in ipairs({"load-status", "property::progress"}) do view:add_signal(sig, function (v) if w:is_current(v) then w:update_progress(v) w:update_ssl(v) end end) end end, -- Display hovered link in statusbar link_hover_display = function (view, w) view:add_signal("link-hover", function (v, link) if w:is_current(v) and link then w.sbar.l.uri.text = "Link: " .. lousy.util.escape(link) end end) view:add_signal("link-unhover", function (v) if w:is_current(v) then w:update_uri(v) end end) end, -- Clicking a form field automatically enters insert mode form_insert_mode = function (view, w) view:add_signal("form-active", function () (w.search_state or {}).marker = nil w:set_mode("normal") end) view:add_signal("root-active", function () (w.search_state or {}).marker = nil w:set_mode() end) end, -- Stop key events hitting the webview if the user isn't in insert mode mode_key_filter = function (view, w) view:add_signal("key-press", function () if not w:is_mode("normal") then return true end end) end, -- Try to match a button event to a users button binding else let the -- press hit the webview. button_bind_match = function (view, w) -- Match button press view:add_signal("button-release", function (v, mods, button) (w.search_state or {}).marker = nil if w:hit(mods, button) then return true end end) end, -- Reset the mode on navigation mode_reset_on_nav = function (view, w) view:add_signal("load-status", function (v, status) if w:is_current(v) and status == "provisional" then w:set_mode() end end) end, -- Domain properties domain_properties = function (view, w) view:add_signal("load-status", function (v, status) if status ~= "provisional" then return end local domain = (v.uri and string.match(v.uri, "^%a+://([^/]*)/?")) or "about:blank" if string.match(domain, "^www.") then domain = string.sub(domain, 5) end local props = lousy.util.table.join(domain_props.all or {}, domain_props[domain] or {}) for k, v in pairs(props) do info("Domain prop: %s = %s (%s)", k, tostring(v), domain) view:set_prop(k, v) end end) end, -- Action to take on mime type decision request. mime_decision = function (view, w) -- Return true to accept or false to reject from this signal. view:add_signal("mime-type-decision", function (v, link, mime) info("Requested link: %s (%s)", link, mime) -- i.e. block binary files like *.exe --if mime == "application/octet-stream" then -- return false --end end) end, -- Action to take on window open request. window_decision = function (view, w) -- 'link' contains the download link -- 'reason' contains the reason of the request (i.e. "link-clicked") -- return TRUE to handle the request by yourself or FALSE to proceed -- with default behaviour view:add_signal("new-window-decision", function (v, link, reason) info("New window decision: %s (%s)", link, reason) if reason == "link-clicked" then window.new({ link }) return true end w:new_tab(link) end) end, create_webview = function (view, w) -- Return a newly created webview in a new tab view:add_signal("create-web-view", function (v) return w:new_tab() end) end, -- Action to take on download request. download_request = function (view, w) -- 'link' contains the download link -- 'filename' contains the suggested filename (from server or webkit) view:add_signal("download-request", function (v, link, filename) if not filename then return end -- Make download dir os.execute(string.format("mkdir -p %q", globals.download_dir)) local dl = globals.download_dir .. "/" .. filename local wget = string.format("wget -q %q -O %q", link, dl) info("Launching: %s", wget) luakit.spawn(wget) end) end, -- Creates context menu popup from table (and nested tables). -- Use `true` for menu separators. populate_popup = function (view, w) view:add_signal("populate-popup", function (v) return { true, { "_Toggle Source", function () w:toggle_source() end }, { "_Zoom", { { "Zoom _In", function () w:zoom_in(globals.zoom_step) end }, { "Zoom _Out", function () w:zoom_out(globals.zoom_step) end }, true, { "Zoom _Reset", function () w:zoom_reset() end }, }, }, } end) end, -- Action to take on resource request. resource_request_decision = function (view, w) view:add_signal("resource-request-starting", function(v, uri) if luakit.verbose then print("Requesting: "..uri) end -- Return false to cancel the request. end) end, } -- These methods are present when you index a window instance and no window -- method is found in `window.methods`. The window then checks if there is an -- active webview and calls the following methods with the given view instance -- as the first argument. All methods must take `view` & `w` as the first two -- arguments. webview.methods = { reload = function (view, w) view:reload() end, -- Property functions get = function (view, w, k) return view:get_prop(k) end, set = function (view, w, k, v) view:set_prop(k, v) end, -- evaluate javascript code and return string result eval_js = function (view, w, script, file) return view:eval_js(script, file or "(inline)") end, -- evaluate javascript code from file and return string result eval_js_from_file = function (view, w, file) local fh, err = io.open(file) if not fh then return error(err) end local script = fh:read("*a") fh:close() return view:eval_js(script, file) end, -- close the current tab close_tab = function (view, w) w.tabs:remove(view) view.uri = "about:blank" view:destroy() w:update_tab_count() w:update_tab_labels() end, -- Toggle source view toggle_source = function (view, w, show) if show == nil then show = not view:get_view_source() end view:set_view_source(show) end, -- Zoom functions zoom_in = function (view, w, step) view:set_prop("zoom-level", view:get_prop("zoom-level") + step) end, zoom_out = function (view, w, step) local value = view:get_prop("zoom-level") - step view:set_prop("zoom-level", ((value > 0.01) and value) or 0.01) end, zoom_reset = function (view, w) view:set_prop("zoom-level", 1.0) end, -- Searching functions start_search = function (view, w, text) if string.match(text, "^[\?\/]") then w:set_mode("search") local i = w.ibar.input i.text = text i:focus() i:set_position(-1) else return error("invalid search term, must start with '?' or '/'") end end, search = function (view, w, text, forward) if forward == nil then forward = true end -- Get search state (or new state) if not w.search_state then w.search_state = {} end local s = w.search_state -- Get search term text = text or s.last_search if not text or #text == 0 then return w:clear_search() end s.last_search = text if s.forward == nil then -- Haven't searched before, save some state. s.forward = forward s.marker = view:get_scroll_vert() else -- Invert direction if originally searching in reverse forward = (s.forward == forward) end view:search(text, false, forward, true); end, clear_search = function (view, w) view:clear_search() w.search_state = {} end, -- Webview scroll functions scroll_vert = function (view, w, value) local cur, max = view:get_scroll_vert() if type(value) == "string" then value = lousy.util.parse_scroll(cur, max, value) end view:set_scroll_vert(value) end, scroll_horiz = function (view, w, value) local cur, max = view:get_scroll_horiz() if type(value) == "string" then value = lousy.util.parse_scroll(cur, max, value) end view:set_scroll_horiz(value) end, -- vertical scroll of a multiple of the view_size scroll_page = function (view, w, value) local cur, max, size = view:get_scroll_vert() view:set_scroll_vert(cur + (size * value)) end, -- History traversing functions back = function (view, w, n) view:go_back(n or 1) end, forward = function (view, w, n) view:go_forward(n or 1) end, } function webview.new(w, uri) local view = widget{type = "webview"} -- Call webview init functions for k, func in pairs(webview.init_funcs) do func(view, w) end if uri then view.uri = uri end view.show_scrollbars = false return view end -- Insert webview method lookup on window structure table.insert(window.indexes, 1, function (w, k) -- Get current webview local view = w.tabs:atindex(w.tabs:current()) if not view then return end -- Lookup webview method local func = webview.methods[k] if not func then return end -- Return webview method wrapper function return function (_, ...) return func(view, w, ...) end end) -- vim: et:sw=4:ts=8:sts=4:tw=80