Replace for_each_frame and co_for_each_frame with frame_iterator
[conkeror.git] / modules / follow-relationship.js
blob995c3d4fc2430936503f761483b6b8fbb407f787
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", {}, "Patterns used by `follow-next' and `follow-previous'.");
23 browser_relationship_patterns[RELATIONSHIP_NEXT] =
24     [new RegExp("\\bnext","i"),
25      new RegExp("^>$","i"),
26      new RegExp("^(>>|»)$","i"),
27      new RegExp("^(>|»)","i"),
28      new RegExp("(>|»)$","i")];
30 browser_relationship_patterns[RELATIONSHIP_PREVIOUS] =
31     [new RegExp("\\bprev|previous\\b","i"),
32      new RegExp("^<$","i"),
33      new RegExp("^(<<|«)$","i"),
34      new RegExp("^(<|«)","i"),
35      new RegExp("(<|«)$","i")];
37 function document_get_element_by_relationship(doc, relationship) {
38     var patterns = browser_relationship_patterns[relationship];
39     var rel_name = new RegExp(browser_relationship_rel_regexp[relationship], "i");
40     var rev_name = new RegExp(browser_relationship_rev_regexp[relationship], "i");
42     var elems = doc.getElementsByTagName("link");
43     // links have higher priority than normal <a> hrefs
44     for (var i = 0; i < elems.length; i++)
45     {
46         if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
47             return elems[i];
48     }
50     // no links? ok, look for hrefs
51     elems = doc.getElementsByTagName("a");
52     for (var i = 0; i < elems.length; i++)
53     {
54         if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
55             return elems[i];
56     }
58     for (var j = 0; j < patterns.length; ++j)
59     {
60         var pattern = patterns[j];
61         for (var i = 0; i < elems.length; i++) // Loop through list of A elements again
62         {
63             if (pattern.test(elems[i].textContent))
64                 return elems[i];
66             // images with alt text being href
67             var children = elems[i].childNodes;
68             for (var k = 0; k < children.length; k++)
69             {
70                 if (pattern.test(children[k].alt))
71                     return elems[i];
72             }
73         }
74     }
75     return null;
78 function browser_follow_relationship(buffer, relationship, target) {
79     check_buffer(buffer, content_buffer);
80     for (let frame in frame_iterator(buffer.top_frame, buffer.focused_frame)) {
81         let elem = document_get_element_by_relationship(frame.document, relationship);
82         if (elem)
83             browser_element_follow(buffer, target, elem);
84     }
85     throw interactive_error("No \"" + browser_relationship_rel_name[relationship]
86                             + "\" link found");
89 default_browse_targets["follow-relationship"] = "follow";
91 interactive("follow-next", function (I) {
92     browser_follow_relationship(I.buffer, RELATIONSHIP_NEXT, I.browse_target("follow-relationship"))
93 });
95 interactive("follow-previous", function (I) {
96     browser_follow_relationship(I.buffer, RELATIONSHIP_PREVIOUS, I.browse_target("follow-relationship"))
97 });