utils.js: Add coroutine interface to XMLHttpRequest
[conkeror.git] / modules / media.js
blob2bd5ae1cc6dd7b3ce92f278e23e02946aa423c81
3 /**
4  * Default media scraper
5  *
6  * Looks for <embed> and <object> elements, and also uses regular
7  * expresisons to attempt to match strings that look like URIs to
8  * embedded media.
9  **/
11 define_variable("media_scrape_default_regexp",
12                 new RegExp("(?:http://[a-zA-Z0-9.\\-]+/)?(?!://)[^=&<>\"'|\\s]+\\."
13                            + "(?:aiff|au|avi|flv|mid|mov|mp3|ogg|ra|rm|spl|wav|wma|wmv)(?!\\w)", "ig"),
14                 "Regular expression used by the default media scraper to match URIs for "
15                 + "embedded media in the page source code.");
17 function media_scrape_default(buffer) {
18     var results = [];
19     for_each_frame(buffer.top_frame, function (frame) {
20                        var text = frame.document.documentElement.innerHTML;
21                        var matches = text.match(media_scrape_default_regexp);
22                        //matches = matches.concat(unescape(text).match(media_scrape_default_regexp));
24                        let base_uri = frame.document.documentURIObject;
26                        var uris = new string_hashset();
27                        for each (let x in matches) {
28                            let str = x;
29                            dumpln("got match: " + str);
30                            try {
31                                let uri_obj = make_uri(str, null, base_uri);
32                                if (!uris.contains(uri_obj.spec))  {
33                                    uris.add(uri_obj.spec);
34                                    results.push(load_spec({uri: uri_obj.spec, source_frame: frame}));
35                                }
36                            } catch (e) {}
37                        }
38                    });
40     // If there is exactly 1, use the document title as the video title
41     if (results.length == 1) {
42         results[0].title = buffer.document.title;
43         results[0].suggest_filename_from_uri = false;
44     }
45     return results;
48 define_variable("media_scraper", media_scrape_default,
49                 "Function (or coroutine) to use to scrape the current buffer for embedded media.");
52 function media_scrape(buffer) {
53     var scraper = buffer.get("media_scraper");
54     if (scraper)
55         yield co_return((yield scraper(buffer)));
57     yield co_return(null);
60 function media_setup_local_object_classes(buffer) {
61     buffer.local_variables.default_browser_object_classes = {
62         __proto__: default_browser_object_classes,
63         save: "media",
64         shell_command: "media",
65         shell_command_url: "media"
66     };
69 define_browser_object_class("media", $handler = function (buf, prompt) {
70     let media = yield media_scrape(buf);
71     if (!media || media.length == 0)
72         throw interactive_error("No media found.");
74     if (media.length == 1)
75         yield co_return(media[0]);
77     let completer = all_word_completer(
78         $completions = media,
79         $get_string = function (x) load_spec_uri_string(x),
80         $get_description = function (x) load_spec_title(x) || "");
82     let result = yield buf.window.minibuffer.read(
83         $prompt = prompt,
84         $match_required,
85         $completer = completer,
86         $auto_complete_initial,
87         $auto_complete = "media");
89     yield co_return(result);
90 });