remove in_module mechanism
[conkeror.git] / modules / follow-relationship.js
blob65e95e077692a7ee27eaccfead0d50e2c704e6ba
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_regexp = ["next", "prev|previous"];
18 var browser_relationship_rev_regexp = ["prev|previous", "next"];
20 define_variable("browser_relationship_patterns", {},
21     "Patterns used by `follow-next' and `follow-previous'. "+
22     "User value may be overridden for specific websites by "+
23     "page-modes.");
25 browser_relationship_patterns[RELATIONSHIP_NEXT] =
26     [/^next$/i,
27      new RegExp("^>$","i"),
28      new RegExp("^(>>|»)$","i"),
29      new RegExp("^(>|»)","i"),
30      new RegExp("(>|»)$","i"),
31      new RegExp("\\bnext","i")
32     ];
34 browser_relationship_patterns[RELATIONSHIP_PREVIOUS] =
35     [/^(prev|previous)$/i,
36      new RegExp("^<$","i"),
37      new RegExp("^(<<|«)$","i"),
38      new RegExp("^(<|«)","i"),
39      new RegExp("(<|«)$","i"),
40      new RegExp("\\bprev|previous\\b","i")
41     ];
43 function document_get_element_by_relationship (doc, patterns, relationship) {
44     patterns = patterns[relationship];
45     var rel_name = new RegExp(browser_relationship_rel_regexp[relationship], "i");
46     var rev_name = new RegExp(browser_relationship_rev_regexp[relationship], "i");
48     var elems = doc.getElementsByTagName("link");
49     // links have higher priority than anchors
50     for (var i = 0; i < elems.length; i++) {
51         if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
52             return elems[i];
53     }
55     // no links? look for anchors
56     elems = doc.getElementsByTagName("a");
57     for (var i = 0; i < elems.length; i++) {
58         if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
59             return elems[i];
60     }
62     for (var j = 0; j < patterns.length; ++j) {
63         var pattern = patterns[j];
64         for (var i = 0; i < elems.length; i++) { // loop through list of anchors again
65             if (pattern.test(elems[i].textContent))
66                 return elems[i];
68             // images with alt text being href
69             var children = elems[i].childNodes;
70             for (var k = 0; k < children.length; k++) {
71                 if (children[k].alt && pattern.test(children[k].alt))
72                     return elems[i];
73             }
74         }
75     }
76     return null;
79 define_browser_object_class("relationship-next", null,
80     function (I, prompt) {
81         var doc = I.buffer.document;
82         for (let frame in frame_iterator(I.buffer.top_frame, I.buffer.focused_frame)) {
83             let elem = document_get_element_by_relationship(
84                 frame.document,
85                 I.local.browser_relationship_patterns,
86                 RELATIONSHIP_NEXT);
87             if (elem)
88                 yield co_return(elem);
89         }
90         throw interactive_error("No \"next\" link found.");
91     });
93 define_browser_object_class("relationship-previous", null,
94     function (I, prompt) {
95         var doc = I.buffer.document;
96         for (let frame in frame_iterator(I.buffer.top_frame, I.buffer.focused_frame)) {
97             let elem = document_get_element_by_relationship(
98                 frame.document,
99                 I.local.browser_relationship_patterns,
100                 RELATIONSHIP_PREVIOUS);
101             if (elem)
102                 yield co_return(elem);
103         }
104         throw interactive_error("No \"previous\" link found.");
105     });
107 provide("follow-relationship");