2 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
4 * Portions of this file were derived from Vimperator,
5 * (C) Copyright 2007 Doug Kearns
6 * (C) Copyright 2007-2008 Martin Stubenschrott.
8 * Use, modification, and distribution are subject to the terms specified in the
14 require("element.js");
16 const RELATIONSHIP_NEXT = 0;
17 const RELATIONSHIP_PREVIOUS = 1;
19 var browser_relationship_rel_regexp = ["next", "prev|previous"];
20 var browser_relationship_rev_regexp = ["prev|previous", "next"];
22 define_variable("browser_relationship_patterns", {},
23 "Patterns used by `follow-next' and `follow-previous'. "+
24 "User value may be overridden for specific websites by "+
27 browser_relationship_patterns[RELATIONSHIP_NEXT] =
29 new RegExp("^>$","i"),
30 new RegExp("^(>>|»)$","i"),
31 new RegExp("^(>|»)","i"),
32 new RegExp("(>|»)$","i"),
33 new RegExp("\\bnext","i")
36 browser_relationship_patterns[RELATIONSHIP_PREVIOUS] =
37 [/^(prev|previous)$/i,
38 new RegExp("^<$","i"),
39 new RegExp("^(<<|«)$","i"),
40 new RegExp("^(<|«)","i"),
41 new RegExp("(<|«)$","i"),
42 new RegExp("\\bprev|previous\\b","i")
45 function document_get_element_by_relationship (doc, patterns, relationship) {
46 patterns = patterns[relationship];
47 var rel_name = new RegExp(browser_relationship_rel_regexp[relationship], "i");
48 var rev_name = new RegExp(browser_relationship_rev_regexp[relationship], "i");
50 var elems = doc.getElementsByTagName("link");
51 // links have higher priority than anchors
52 for (var i = 0; i < elems.length; i++) {
53 if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
57 // no links? look for anchors
58 elems = doc.getElementsByTagName("a");
59 for (var i = 0; i < elems.length; i++) {
60 if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
64 for (var j = 0; j < patterns.length; ++j) {
65 var pattern = patterns[j];
66 for (var i = 0; i < elems.length; i++) { // loop through list of anchors again
67 if (pattern.test(elems[i].textContent))
70 // images with alt text being href
71 var children = elems[i].childNodes;
72 for (var k = 0; k < children.length; k++) {
73 if (children[k].alt && pattern.test(children[k].alt))
81 define_browser_object_class("relationship-next", null,
82 function (I, prompt) {
83 var doc = I.buffer.document;
84 for (let frame in frame_iterator(I.buffer.top_frame, I.buffer.focused_frame)) {
85 let elem = document_get_element_by_relationship(
87 I.local.browser_relationship_patterns,
90 yield co_return(elem);
92 throw interactive_error("No \"next\" link found.");
95 define_browser_object_class("relationship-previous", null,
96 function (I, prompt) {
97 var doc = I.buffer.document;
98 for (let frame in frame_iterator(I.buffer.top_frame, I.buffer.focused_frame)) {
99 let elem = document_get_element_by_relationship(
101 I.local.browser_relationship_patterns,
102 RELATIONSHIP_PREVIOUS);
104 yield co_return(elem);
106 throw interactive_error("No \"previous\" link found.");
109 provide("follow-relationship");