| 4 | | // @include http://www.amazon.tld/* |
| 5 | | // @include http://amazon.tld/* |
| 6 | | // @include http://www.oreilly.co.jp/books/* |
| 7 | | // @include http://www.bookoffonline.co.jp/display/* |
| 8 | | // @include http://www.ebookoff.co.jp/detail/* |
| 9 | | // @include http://books.google.tld/books* |
| 10 | | // @include http://bookweb.kinokuniya.co.jp/* |
| 11 | | // @include http://item.rakuten.co.jp/book/* |
| 12 | | // @include http://books.livedoor.com/item* |
| 13 | | // @include http://www.cbook24.com/bm_detail.asp* |
| 14 | | // @include http://www.7andy.jp/books/detail* |
| 15 | | // @include http://*.bk1.jp/product/* |
| 16 | | // @include http://www.seshop.com/detail.asp* |
| 17 | | // @include http://seshop.com/detail.asp* |
| 18 | | // @include http://www.e-hon.ne.jp/bec/SA/Detail* |
| 19 | | // @include http://www.junkudo.co.jp/detail2.jsp* |
| 20 | | // @include http://junkudo.co.jp/detail2.jsp* |
| 21 | | // @include http://www.books.or.jp/ResultDetail.aspx* |
| 22 | | // @include http://nichibou.shop-pro.jp/* |
| 23 | | // @include http://gazoo.com/book/s_01.asp* |
| 24 | | // @include http://books.yahoo.co.jp/book_detail/* |
| 25 | | // @include http://www.asahiya.com/book_search/book_search_BookDetail.asp |
| 26 | | // @include http://lib.city.shinagawa.tokyo.jp/cgi-bin/Sopcsvis.sh |
| | 4 | // @include http://* |
| 34 | | |
| 35 | | const SITEINFO = [ |
| 36 | | { url: '^http://(?:www\\.)?amazon\\.[^/]+/', |
| 37 | | xpaths: { |
| 38 | | isbn10: 'normalize-space(//li[b/text()="ISBN-10:"]/text())', |
| 39 | | isbn13: 'translate(//li[b/text()="ISBN-13:"]/text(), "- ", "")' |
| 40 | | } }, |
| 41 | | { url: '^http://www\\.oreilly\\.co\\.jp/books/', |
| 42 | | xpaths: { |
| 43 | | isbn10: 'translate(//meta[string-length(@content)=13 and @name="isbn"]/@content, "-", "")', |
| 44 | | isbn13: 'translate(//meta[string-length(@content)=17 and @name="isbn"]/@content, "-", "")' |
| 45 | | } }, |
| 46 | | { url: '^http://www\\.bookoffonline\\.co\\.jp/display/', |
| 47 | | xpaths: { |
| 48 | | isbn13: '//tr[th/text()="JAN"]/td/text()' |
| 49 | | } }, |
| 50 | | { url: '^http://www\\.ebookoff\\.co\\.jp/detail/', |
| 51 | | xpaths: { |
| 52 | | isbn10: 'substring(//tr[td/b/text()="ISBN"]/td[3]/text(), 1, 10)', |
| 53 | | isbn13: 'substring(//tr[td/b/text()="ISBN"]/td[3]/text(), 13, 13)' |
| 54 | | } }, |
| 55 | | { url: '^http://books\\.google\\.[^/]+/books', |
| 56 | | xpaths: { |
| 57 | | isbn10: 'substring-before(substring-after(//a[contains(@href, "ISBN:")]/@href, "ISBN:"), "&")', |
| 58 | | isbn10: 'substring-after(//td/text()[starts-with(., "ISBN ")], "ISBN ")' |
| 59 | | } }, |
| 60 | | { url: '^http://bookweb\\.kinokuniya\\.co\\.jp/.+', |
| 61 | | xpaths: { |
| 62 | | isbn10: '//input[@name="ISBN"]/@value', |
| 63 | | isbn13: 'substring(substring-after(//td[span[@class="BookTitle"]]/text()[4], "ISBN:"), 1, 13)' |
| 64 | | } }, |
| 65 | | { url: '^http://item\\.rakuten\\.co\\.jp/book/', |
| 66 | | xpaths: { |
| 67 | | isbn13: 'substring-after(//span[@class="item_number"]/text(), "ISBN:")' |
| 68 | | } }, |
| 69 | | { url: '^http://books\\.livedoor\\.com/item', |
| 70 | | xpaths: { |
| 71 | | isbn10: 'substring-after(//p[@class="itemData"]/text()[4], "管理コード:")', |
| 72 | | isbn13: 'substring-after(//p[@class="itemData"]/text()[3], "ISBN:")' |
| 73 | | } }, |
| 74 | | { url: "^http://www\\.cbook24\\.com/bm_detail\\.asp", |
| 75 | | xpaths: { |
| 76 | | isbn13: 'translate(normalize-space(//tr/td[@class="body2" and contains(text(), "ISBN")]/following-sibling::td/text()), "-", "")' |
| 77 | | } }, |
| 78 | | { url: "^http://www\\.7andy\\.jp/books/detail", |
| 79 | | xpaths: { |
| 80 | | isbn10: 'substring-after(substring-before(translate(//tr/td[normalize-space(.//text())="出版社名"]/following-sibling::td[1]' + |
| 81 | | '//text()[string-length(substring-after(substring-before(translate(., "-", ""), ")"), "ISBN:"))=10], "-", ""), ")"), "ISBN:")', |
| 82 | | isbn13: 'substring-after(substring-before(translate(//tr/td[normalize-space(.//text())="出版社名"]/following-sibling::td[1]' + |
| 83 | | '//text()[string-length(substring-after(substring-before(translate(., "-", ""), ")"), "ISBN:"))=13], "-", ""), ")"), "ISBN:")' |
| 84 | | } }, |
| 85 | | { url: "^http://[^/]+\\.bk1\\.jp/product/", |
| 86 | | xpaths: { |
| 87 | | isbn10: 'normalize-space(translate(substring-after(//td[@width="350"]/font[@size="-1"]/text()[contains(., "ISBN")' + |
| 88 | | ' and string-length(normalize-space(translate(substring-after(., ":"), "-", "")))=10], ":"), "-", ""))', |
| 89 | | isbn13: 'normalize-space(translate(substring-after(//td[@width="350"]/font[@size="-1"]/text()[contains(., "ISBN")' + |
| 90 | | ' and string-length(normalize-space(translate(substring-after(., ":"), "-", "")))=13], ":"), "-", ""))' |
| 91 | | } }, |
| 92 | | { url: "^http://(?:www\\.)?seshop\\.com/detail\\.asp", |
| 93 | | xpaths: { |
| 94 | | isbn10: '//td/b[contains(text(), "ISBN")]/following-sibling::text()[position()=1 and string-length()=10]', |
| 95 | | isbn13: '//td/b[contains(text(), "ISBN")]/following-sibling::text()[position()=1 and string-length()=13]' |
| 96 | | } }, |
| 97 | | { url: "^http://www\\.e-hon\\.ne\\.jp/bec/SA/Detail", |
| 98 | | xpaths: { |
| 99 | | isbn10: 'substring(translate(//table[@cellpadding="3"]//table//table//table//tr[contains(.//font/text(), "ISBN")]' + |
| 100 | | '/following-sibling::tr/td[2]/font, "-", ""), 2, 10)', |
| 101 | | isbn13: 'translate(//table[@cellpadding="3"]//table//table//table//tr[contains(.//font/text(), "ISBN")]/td[2]/font, "-", "")' |
| 102 | | } }, |
| 103 | | { url: "^http://(?:www\\.)?junkudo\\.co\\.jp/detail2\\.jsp", |
| 104 | | xpaths: { |
| 105 | | isbn10: '//input[@name="ISBN" and @value]/@value', |
| 106 | | isbn13: 'substring(//input[@name="freetext" and number(substring(@value, 1, 13))]/@value, 1, 13)' |
| 107 | | } }, |
| 108 | | { url: "^http://www\\.books\\.or\\.jp/ResultDetail\\.aspx", |
| 109 | | xpaths: { |
| 110 | | isbn10: 'translate(normalize-space(//table[@id="tblBookInfo"]//td[.//text()="ISBN"]/following-sibling::td[1]/text()[1]), "-", "")', |
| 111 | | isbn13: 'translate(normalize-space(//table[@id="tblBookInfo"]//td[.//text()="ISBN"]/following-sibling::td[1]/text()[2]), "-", "")' |
| 112 | | } }, |
| 113 | | { url: "^http://nichibou\\.shop-pro\\.jp/", |
| 114 | | xpaths: { |
| 115 | | isbn13: 'translate(substring-after(//div[@class="explain"]/text()[contains(., "ISBN/")], "ISBN/"), "-", "")' |
| 116 | | } }, |
| 117 | | { url: "^http://gazoo\\.com/book/s_01\\.asp", |
| 118 | | xpaths: { |
| 119 | | isbn13: 'substring-after(//font[@class="font2" and contains(.//text(), "ISBN:")]/text(), "ISBN:")' |
| 120 | | } }, |
| 121 | | //{ url: "^http://books\\.yahoo\\.co\\.jp/book_detail/", |
| 122 | | // xpaths: { |
| 123 | | // isbn10: '', |
| 124 | | // isbn13: '' |
| 125 | | //} }, |
| 126 | | { url: "^http://www\\.asahiya\\.com/book_search/book_search_BookDetail\\.asp", |
| 127 | | xpaths: { |
| 128 | | isbn10: '//table[@class="BookDetails"]//tr[contains(th/text(), "ISBN")]/td[string-length(text())=10]/text()' |
| 129 | | } }, |
| 130 | | { url: "^http://lib\\.city\\.shinagawa\\.tokyo\\.jp/cgi-bin/Sopcsvis\\.sh", |
| 131 | | xpaths: { |
| 132 | | isbn10: 'translate(//tr[contains(td, "ISBN")]/td[3], "-", "")' |
| 133 | | } } |
| 134 | | ]; |
| 135 | | |
| 717 | | var book = (function (infos) { |
| 718 | | var info; |
| 719 | | for (var i = 0, m = infos.length; i < m; ++i) { |
| 720 | | info = infos[i]; |
| 721 | | if (!RegExp(info.url).test(location.href)) |
| 722 | | continue; |
| 723 | | |
| 724 | | var book = {}; |
| 725 | | for (var key in info.xpaths) { |
| 726 | | if (book[key]) |
| 727 | | continue; |
| 728 | | var value = document.evaluate( |
| 729 | | info.xpaths[key], document, null, XPathResult.STRING_TYPE, null).stringValue; |
| 730 | | if (value) |
| 731 | | book[key] = value; |
| 732 | | } |
| 733 | | if (keys(book).length <= 0) |
| 734 | | return null; |
| 735 | | |
| 736 | | if (!book.isbn10 && !book.isbn13) |
| 737 | | return book; |
| 738 | | |
| 739 | | var isbn = ISBN.parse(book.isbn10 || book.isbn13); |
| 740 | | if (!isbn) |
| 741 | | return null; |
| 742 | | |
| 743 | | if (!book.isbn10) |
| 744 | | book.isbn10 = isbn.asIsbn10(); |
| 745 | | if (!book.isbn13) |
| 746 | | book.isbn13 = isbn.asIsbn10(); |
| 747 | | book.isbn10h = isbn.asIsbn10(true); |
| 748 | | book.isbn13h = isbn.asIsbn13(true); |
| 749 | | |
| 750 | | return book; |
| 751 | | } |
| 752 | | return null; |
| 753 | | })(SITEINFO); |
| 754 | | |
| 755 | | if (!book) |
| 756 | | return; |
| 757 | | |
| 758 | | GM_addStyle(CSS); |
| 759 | | |
| 760 | | var bar = (function() { |
| 761 | | |
| 762 | | var config = (function() { |
| 763 | | var ctn = document.createElement('div'); |
| 764 | | ctn.id = 'cbs_config'; |
| 765 | | ctn.areas = {}; |
| 766 | | |
| 767 | | var img_x = document.createElement('img'); |
| 768 | | img_x.className = 'cbs_close'; |
| 769 | | img_x.src = IMG_GIF_X; |
| 770 | | img_x.addEventListener('click', function() { |
| 771 | | document.body.removeChild(ctn); |
| 772 | | }, false); |
| 773 | | ctn.appendChild(img_x); |
| 774 | | |
| 775 | | var combo = document.createElement('select'); |
| 776 | | combo.className = 'cbs'; |
| 777 | | combo.addEventListener('change', function() { |
| 778 | | var opt = combo.options[combo.selectedIndex]; |
| 779 | | ctn.replaceChild(ctn.areas[opt.value], ctn.lastChild); |
| 780 | | }, false); |
| 781 | | ctn.appendChild(combo); |
| 782 | | ctn.appendChild(document.createElement('br')); |
| 783 | | |
| 784 | | for (var c1 in LIBINFO) { |
| 785 | | for (var c2 in LIBINFO[c1]) { |
| 786 | | var area = LIBINFO[c1][c2]; |
| 787 | | var key = c1 + '_' + c2; |
| 788 | | ctn.areas[key] = document.createElement('div'); |
| 789 | | ctn.areas[key].id = 'targets'; |
| 790 | | ctn.areas[key].className = 'cbs_unit'; |
| 791 | | |
| 792 | | var opt = document.createElement('option'); |
| 793 | | opt.text = area.name; |
| 794 | | opt.value = key; |
| 795 | | combo.appendChild(opt); |
| 796 | | |
| 797 | | for (var target in area.targets) { |
| 798 | | var check = document.createElement('input'); |
| 799 | | check.type = 'checkbox'; |
| 800 | | check.name = c1 + '.' + c2; |
| 801 | | check.value = target; |
| 802 | | check.checked = isEnabled(check.name, check.value); |
| 803 | | check.addEventListener('change', function() { |
| 804 | | setEnabled(this.name, this.value, this.checked); |
| 805 | | }, false); |
| 806 | | |
| 807 | | var label = document.createElement('label'); |
| 808 | | label.appendChild(check); |
| 809 | | label.appendChild(document.createTextNode(area.targets[target].name)); |
| 810 | | ctn.areas[key].appendChild(label); |
| | 593 | var scraper = new ISBNScraper(); |
| | 594 | scraper.scrape(document, function(books) { |
| | 595 | if (!books || books.length <= 0) |
| | 596 | return; |
| | 597 | search(books[0]); |
| | 598 | }); |
| | 599 | |
| | 600 | function search(book) { |
| | 601 | GM_addStyle(CSS); |
| | 602 | |
| | 603 | var bar = (function() { |
| | 604 | |
| | 605 | var config = (function() { |
| | 606 | var ctn = document.createElement('div'); |
| | 607 | ctn.id = 'cbs_config'; |
| | 608 | ctn.areas = {}; |
| | 609 | |
| | 610 | var img_x = document.createElement('img'); |
| | 611 | img_x.className = 'cbs_close'; |
| | 612 | img_x.src = IMG_GIF_X; |
| | 613 | img_x.addEventListener('click', function() { |
| | 614 | document.body.removeChild(ctn); |
| | 615 | }, false); |
| | 616 | ctn.appendChild(img_x); |
| | 617 | |
| | 618 | var combo = document.createElement('select'); |
| | 619 | combo.className = 'cbs'; |
| | 620 | combo.addEventListener('change', function() { |
| | 621 | var opt = combo.options[combo.selectedIndex]; |
| | 622 | ctn.replaceChild(ctn.areas[opt.value], ctn.lastChild); |
| | 623 | }, false); |
| | 624 | ctn.appendChild(combo); |
| | 625 | ctn.appendChild(document.createElement('br')); |
| | 626 | |
| | 627 | for (var c1 in LIBINFO) { |
| | 628 | for (var c2 in LIBINFO[c1]) { |
| | 629 | var area = LIBINFO[c1][c2]; |
| | 630 | var key = c1 + '_' + c2; |
| | 631 | ctn.areas[key] = document.createElement('div'); |
| | 632 | ctn.areas[key].id = 'targets'; |
| | 633 | ctn.areas[key].className = 'cbs_unit'; |
| | 634 | |
| | 635 | var opt = document.createElement('option'); |
| | 636 | opt.text = area.name; |
| | 637 | opt.value = key; |
| | 638 | combo.appendChild(opt); |
| | 639 | |
| | 640 | for (var target in area.targets) { |
| | 641 | var check = document.createElement('input'); |
| | 642 | check.type = 'checkbox'; |
| | 643 | check.name = c1 + '.' + c2; |
| | 644 | check.value = target; |
| | 645 | check.checked = isEnabled(check.name, check.value); |
| | 646 | check.addEventListener('change', function() { |
| | 647 | setEnabled(this.name, this.value, this.checked); |
| | 648 | }, false); |
| | 649 | |
| | 650 | var label = document.createElement('label'); |
| | 651 | label.appendChild(check); |
| | 652 | label.appendChild(document.createTextNode(area.targets[target].name)); |
| | 653 | ctn.areas[key].appendChild(label); |
| | 654 | } |
| | 657 | |
| | 658 | var names = keys(ctn.areas); |
| | 659 | if (names.length > 0) |
| | 660 | ctn.appendChild(ctn.areas[names[0]]); |
| | 661 | |
| | 662 | return ctn; |
| | 663 | })(); |
| | 664 | |
| | 665 | var root = document.createElement('div'); |
| | 666 | root.id = 'cbs_bar'; |
| | 667 | |
| | 668 | var header = (function() { |
| | 669 | var ctn = document.createElement('div'); |
| | 670 | ctn.id = 'cbs_header'; |
| | 671 | |
| | 672 | var img_x = document.createElement('img'); |
| | 673 | img_x.className = 'cbs_close'; |
| | 674 | img_x.src = IMG_GIF_X; |
| | 675 | img_x.addEventListener('click', function() { |
| | 676 | document.body.removeChild(root); |
| | 677 | }, false); |
| | 678 | ctn.appendChild(img_x); |
| | 679 | |
| | 680 | var img_o = document.createElement('img'); |
| | 681 | img_o.className = 'cbs_config'; |
| | 682 | img_o.src = IMG_GIF_O; |
| | 683 | img_o.addEventListener('click', function() { |
| | 684 | document.body.insertBefore(config, document.body.firstChild); |
| | 685 | }, false); |
| | 686 | ctn.appendChild(img_o); |
| | 687 | |
| | 688 | return ctn; |
| | 689 | })(); |
| | 690 | root.appendChild(header); |
| | 691 | |
| | 692 | var list = document.createElement('div'); |
| | 693 | list.id = 'cbs_list'; |
| | 694 | root.appendChild(list); |
| | 695 | |
| | 696 | return root; |
| | 697 | })(); |
| | 698 | document.body.insertBefore(bar, document.body.firstChild); |
| | 699 | |
| | 700 | (function() { |
| | 701 | |
| | 702 | var targets = GM_getValue('targets'); |
| | 703 | if (!targets) |
| | 704 | return; |
| | 705 | targets = eval(targets); |
| | 706 | var names = keys(targets); |
| | 707 | var resps = {}; |
| | 708 | next(); |
| | 709 | |
| | 710 | function response(resp) { |
| | 711 | GM_log(arguments.callee.name); |
| | 712 | GM_log( |
| | 713 | resp.name + ', ' + resp.owned + ', ' + resp.enabled + ', ' + |
| | 714 | (typeof resp.detail == 'string' ? resp.detail : uneval(resp.detail))); |
| | 715 | |
| | 716 | var unit = document.createElement('div'); |
| | 717 | unit.className = 'cbs_unit'; |
| | 718 | |
| | 719 | var link = (function(r) { |
| | 720 | if (r.owned) { |
| | 721 | var txt = r.name; |
| | 722 | if (r.price) |
| | 723 | txt += '(¥' + r.price + ')'; |
| | 724 | if (typeof r.detail == 'string') { |
| | 725 | var link = document.createElement('a'); |
| | 726 | link.className = r.enabled ? 'cbs_enabled' : 'cbs_notenabled'; |
| | 727 | link.href = r.detail; |
| | 728 | link.appendChild(document.createTextNode(txt)); |
| | 729 | return link; |
| | 730 | } else { |
| | 731 | var link = document.createElement('div'); |
| | 732 | link.className = r.enabled ? 'cbs_link_enabled' : 'cbs_link_notenabled'; |
| | 733 | link.id = resp.key; |
| | 734 | link.appendChild(document.createTextNode(txt)); |
| | 735 | link.addEventListener('click', function(e) { |
| | 736 | request(resps[e.currentTarget.id].detail); |
| | 737 | }, false); |
| | 738 | return link; |
| | 739 | } |
| | 740 | } else { |
| | 741 | return document.createTextNode(r.name); |
| | 742 | } |
| | 743 | })(resp); |
| | 744 | |
| | 745 | unit.appendChild(link); |
| | 746 | bar.lastChild.appendChild(unit); |
| | 747 | |
| | 748 | resps[resp.key] = resp; |
| | 749 | next(); |
| 815 | | var names = keys(ctn.areas); |
| 816 | | if (names.length > 0) |
| 817 | | ctn.appendChild(ctn.areas[names[0]]); |
| 818 | | |
| 819 | | return ctn; |
| 820 | | })(); |
| 821 | | |
| 822 | | var root = document.createElement('div'); |
| 823 | | root.id = 'cbs_bar'; |
| 824 | | |
| 825 | | var header = (function() { |
| 826 | | var ctn = document.createElement('div'); |
| 827 | | ctn.id = 'cbs_header'; |
| 828 | | |
| 829 | | var img_x = document.createElement('img'); |
| 830 | | img_x.className = 'cbs_close'; |
| 831 | | img_x.src = IMG_GIF_X; |
| 832 | | img_x.addEventListener('click', function() { |
| 833 | | document.body.removeChild(root); |
| 834 | | }, false); |
| 835 | | ctn.appendChild(img_x); |
| 836 | | |
| 837 | | var img_o = document.createElement('img'); |
| 838 | | img_o.className = 'cbs_config'; |
| 839 | | img_o.src = IMG_GIF_O; |
| 840 | | img_o.addEventListener('click', function() { |
| 841 | | document.body.insertBefore(config, document.body.firstChild); |
| 842 | | }, false); |
| 843 | | ctn.appendChild(img_o); |
| 844 | | |
| 845 | | return ctn; |
| 846 | | })(); |
| 847 | | root.appendChild(header); |
| 848 | | |
| 849 | | var list = document.createElement('div'); |
| 850 | | list.id = 'cbs_list'; |
| 851 | | root.appendChild(list); |
| 852 | | |
| 853 | | return root; |
| 854 | | })(); |
| 855 | | document.body.insertBefore(bar, document.body.firstChild); |
| 856 | | |
| 857 | | (function() { |
| 858 | | |
| 859 | | var targets = GM_getValue('targets'); |
| 860 | | if (!targets) |
| 861 | | return; |
| 862 | | targets = eval(targets); |
| 863 | | var names = keys(targets); |
| 864 | | var resps = {}; |
| 865 | | next(); |
| 866 | | |
| 867 | | function response(resp) { |
| 868 | | GM_log(arguments.callee.name); |
| 869 | | GM_log( |
| 870 | | resp.name + ', ' + resp.owned + ', ' + resp.enabled + ', ' + |
| 871 | | (typeof resp.detail == 'string' ? resp.detail : uneval(resp.detail))); |
| 872 | | |
| 873 | | var unit = document.createElement('div'); |
| 874 | | unit.className = 'cbs_unit'; |
| 875 | | |
| 876 | | var link = (function(r) { |
| 877 | | if (r.owned) { |
| 878 | | var txt = r.name; |
| 879 | | if (r.price) |
| 880 | | txt += '(¥' + r.price + ')'; |
| 881 | | if (typeof r.detail == 'string') { |
| 882 | | var link = document.createElement('a'); |
| 883 | | link.className = r.enabled ? 'cbs_enabled' : 'cbs_notenabled'; |
| 884 | | link.href = r.detail; |
| 885 | | link.appendChild(document.createTextNode(txt)); |
| 886 | | return link; |
| 887 | | } else { |
| 888 | | var link = document.createElement('div'); |
| 889 | | link.className = r.enabled ? 'cbs_link_enabled' : 'cbs_link_notenabled'; |
| 890 | | link.id = resp.key; |
| 891 | | link.appendChild(document.createTextNode(txt)); |
| 892 | | link.addEventListener('click', function(e) { |
| 893 | | request(resps[e.currentTarget.id].detail); |
| 894 | | }, false); |
| 895 | | return link; |
| 896 | | } |
| 897 | | } else { |
| 898 | | return document.createTextNode(r.name); |
| 899 | | } |
| 900 | | })(resp); |
| 901 | | |
| 902 | | unit.appendChild(link); |
| 903 | | bar.lastChild.appendChild(unit); |
| 904 | | |
| 905 | | resps[resp.key] = resp; |
| 906 | | next(); |
| 907 | | } |
| 908 | | |
| 909 | | function next() { |
| 910 | | var name; |
| 911 | | do { |
| 912 | | name = names.shift(); |
| | 752 | function next() { |
| | 753 | var name; |
| | 754 | do { |
| | 755 | name = names.shift(); |
| | 756 | if (!name) |
| | 757 | return; |
| | 758 | } while (!targets[name]); |