interactive_context: construct with `new' instead of ad-hoc
[conkeror.git] / modules / follow-relationship.js
bloba8e47257eaa34bffe974a3416e801b0edbd9bc04
1 /**
2  * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
3  *
4  * Portions of this file were derived from Vimperator,
5  * (C) Copyright 2007 Doug Kearns
6  * (C) Copyright 2007-2008 Martin Stubenschrott.
7  *
8  * Use, modification, and distribution are subject to the terms specified in the
9  * COPYING file.
10 **/
12 require("element.js");
14 const RELATIONSHIP_NEXT = 0;
15 const RELATIONSHIP_PREVIOUS = 1;
17 var browser_relationship_rel_name = ["next", "previous"];
18 var browser_relationship_rel_regexp = ["next", "prev|previous"];
19 var browser_relationship_rev_regexp = ["prev|previous", "next"];
21 define_variable("browser_relationship_patterns", {},
22     "Patterns used by `follow-next' and `follow-previous'. "+
23     "User value may be overridden for specific websites by "+
24     "page-modes.");
26 browser_relationship_patterns[RELATIONSHIP_NEXT] =
27     [/^next$/i,
28      new RegExp("^>$","i"),
29      new RegExp("^(>>|»)$","i"),
30      new RegExp("^(>|»)","i"),
31      new RegExp("(>|»)$","i"),
32      new RegExp("\\bnext","i")
33     ];
35 browser_relationship_patterns[RELATIONSHIP_PREVIOUS] =
36     [/^(prev|previous)$/i,
37      new RegExp("^<$","i"),
38      new RegExp("^(<<|«)$","i"),
39      new RegExp("^(<|«)","i"),
40      new RegExp("(<|«)$","i"),
41      new RegExp("\\bprev|previous\\b","i")
42     ];
44 function document_get_element_by_relationship(buffer, doc, relationship) {
45     var patterns = buffer.get('browser_relationship_patterns')[relationship];
46     var rel_name = new RegExp(browser_relationship_rel_regexp[relationship], "i");
47     var rev_name = new RegExp(browser_relationship_rev_regexp[relationship], "i");
49     var elems = doc.getElementsByTagName("link");
50     // links have higher priority than normal <a> hrefs
51     for (var i = 0; i < elems.length; i++)
52     {
53         if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
54             return elems[i];
55     }
57     // no links? ok, look for hrefs
58     elems = doc.getElementsByTagName("a");
59     for (var i = 0; i < elems.length; i++)
60     {
61         if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
62             return elems[i];
63     }
65     for (var j = 0; j < patterns.length; ++j)
66     {
67         var pattern = patterns[j];
68         for (var i = 0; i < elems.length; i++) // Loop through list of A elements again
69         {
70             if (pattern.test(elems[i].textContent))
71                 return elems[i];
73             // images with alt text being href
74             var children = elems[i].childNodes;
75             for (var k = 0; k < children.length; k++)
76             {
77                 if (pattern.test(children[k].alt))
78                     return elems[i];
79             }
80         }
81     }
82     return null;
85 define_browser_object_class(
86     "relationship-next", "Relationship-Next", null,
87     function (I, prompt) {
88         var doc = I.buffer.document;
89         for (let frame in frame_iterator(I.buffer.top_frame, I.buffer.focused_frame)) {
90             let elem = document_get_element_by_relationship(
91                 I.buffer, frame.document, RELATIONSHIP_NEXT);
92             if (elem)
93                 yield co_return(elem);
94         }
95         throw interactive_error("No \"next\" link found.");
96     });
98 define_browser_object_class(
99     "relationship-previous", "Relationship-Previous", null,
100     function (I, prompt) {
101         var doc = I.buffer.document;
102         for (let frame in frame_iterator(I.buffer.top_frame, I.buffer.focused_frame)) {
103             let elem = document_get_element_by_relationship(
104                 I.buffer, frame.document, RELATIONSHIP_PREVIOUS);
105             if (elem)
106                 yield co_return(elem);
107         }
108         throw interactive_error("No \"previous\" link found.");
109     });