2 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
3 * (C) Copyright 2012 John Foerch
5 * Portions of this file were derived from Vimperator,
6 * (C) Copyright 2007 Doug Kearns
7 * (C) Copyright 2007-2008 Martin Stubenschrott.
9 * Use, modification, and distribution are subject to the terms specified in the
13 require("element.js");
15 const RELATIONSHIP_NEXT = 0;
16 const RELATIONSHIP_PREVIOUS = 1;
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 "+
26 browser_relationship_patterns[RELATIONSHIP_NEXT] =
28 new RegExp("^>$","i"),
29 new RegExp("^(>>|»)$","i"),
30 new RegExp("^(>|»)","i"),
31 new RegExp("(>|»)$","i"),
32 new RegExp("\\bnext","i")
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")
44 function document_get_element_by_relationship (doc, patterns, relationship) {
45 patterns = 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 anchors
51 for (var i = 0, n = elems.length; i < n; i++) {
52 if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
56 // no links? look for anchors
57 elems = doc.getElementsByTagName("a");
58 for (i = 0, n = elems.length; i < n; i++) {
59 if (rel_name.test(elems[i].rel) || rev_name.test(elems[i].rev))
63 for (var j = 0, p = patterns.length; j < p; ++j) {
64 var pattern = patterns[j];
65 if (pattern instanceof Function) {
66 var elem = pattern(doc);
70 for (i = 0, n = elems.length; i < n; i++) { // loop through list of anchors again
71 if (pattern.test(elems[i].textContent))
73 // images with alt text being href
74 var children = elems[i].childNodes;
75 for (var k = 0, c = children.length; k < c; k++) {
76 if (children[k].alt && pattern.test(children[k].alt))
85 define_browser_object_class("relationship-next", null,
86 function (I, prompt) {
87 var doc = I.buffer.document;
88 for (let frame in frame_iterator(I.buffer.top_frame, I.buffer.focused_frame)) {
89 let elem = document_get_element_by_relationship(
91 I.local.browser_relationship_patterns,
94 yield co_return(elem);
96 throw interactive_error("No \"next\" link found.");
99 define_browser_object_class("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(
105 I.local.browser_relationship_patterns,
106 RELATIONSHIP_PREVIOUS);
108 yield co_return(elem);
110 throw interactive_error("No \"previous\" link found.");
113 provide("follow-relationship");