Add initial OpenSearch search engine support
[conkeror.git] / modules / follow-relationship.js
blob1bbb4ac45361122f13c8baffa056a221e368dd1e
1 require("element.js");
3 const RELATIONSHIP_NEXT = 0;
4 const RELATIONSHIP_PREVIOUS = 1;
6 var browser_relationship_rel_name = ["next", "previous"];
7 var browser_relationship_rel_regexp = ["next", "prev|previous"];
8 var browser_relationship_rev_regexp = ["prev|previous", "next"];
10 define_variable("browser_relationship_patterns", {}, "Patterns used by `browser-follow-next' and `browser-follow-previous'.");
12 browser_relationship_patterns[RELATIONSHIP_NEXT] = 
13     [new RegExp("\\bnext","i"),
14      new RegExp("^>$","i"),
15      new RegExp("^(>>|»)$","i"),
16      new RegExp("^(>|»)","i"),
17      new RegExp("(>|»)$","i")];
19 browser_relationship_patterns[RELATIONSHIP_PREVIOUS] = 
20     [new RegExp("\\bprev|previous\\b","i"), 
21      new RegExp("^<$","i"), 
22      new RegExp("^(<<|«)$","i"), 
23      new RegExp("^(<|«)","i"), 
24      new RegExp("(<|«)$","i")];
26 function document_get_element_by_relationship(doc, relationship) {
27     var patterns = browser_relationship_patterns[relationship];
28     var rel_name = new RegExp(browser_relationship_rel_regexp[relationship], "i");
29     var rev_name = new RegExp(browser_relationship_rev_regexp[relationship], "i");
30     
31     var elems = doc.getElementsByTagName("link");
32     // links have higher priority than normal <a> hrefs
33     for (var i = 0; i < elems.length; i++)
34     {
35         if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
36             return elems[i];
37     }
39     // no links? ok, look for hrefs
40     elems = doc.getElementsByTagName("a");
41     for (var i = 0; i < elems.length; i++)
42     {
43         if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
44             return elems[i];
45     }
47     for (var j = 0; j < patterns.length; ++j)
48     {
49         var pattern = patterns[j];
50         for (var i = 0; i < elems.length; i++) // Loop through list of A elements again
51         {
52             if (pattern.test(elems[i].textContent))
53                 return elems[i];
55             // images with alt text being href
56             var children = elems[i].childNodes;
57             for (var k = 0; k < children.length; k++)
58             {
59                 if (pattern.test(children[k].alt))
60                     return elems[i];
61             }
62         }
63     }
64     return null;
67 function browser_follow_relationship(buffer, relationship, target) {
68     check_buffer(buffer, content_buffer);
69     function helper(win) {
70         var elem = document_get_element_by_relationship(win.document, relationship);
71         if (elem)
72             return elem;
73         for (var i = 0; i < win.frames.length; ++i) {
74             elem = document_get_element_by_relationship(win.frames[i].document, relationship);
75             if (elem)
76                 return elem;
77         }
78         return null;
79     }
81     var elem = helper(buffer.top_frame);
82     if (!elem)
83         throw interactive_error("No \"" + browser_relationship_rel_name[relationship]
84                                 + "\" link found");
85     browser_element_follow(buffer, target, elem);
88 default_browse_targets["follow-relationship"] = "follow";
90 interactive("browser-follow-next", function (I) {
91     browser_follow_relationship(I.buffer, RELATIONSHIP_NEXT, I.browse_target("follow-relationship"))
92 });
94 interactive("browser-follow-previous", function (I) {
95     browser_follow_relationship(I.buffer, RELATIONSHIP_PREVIOUS, I.browse_target("follow-relationship"))
96 });