├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.markdown ├── build.rb ├── build_fx.sh ├── src ├── 0f0.png ├── _locales │ ├── en │ │ └── messages.json │ ├── ja │ │ └── messages.json │ └── ru │ │ └── messages.json ├── autopagerize.user.js ├── background.html ├── background.js ├── error.html ├── extension.js ├── icons │ ├── 00f.png │ ├── 0f0.png │ ├── 0ff.png │ ├── ccc.png │ ├── f0f.png │ ├── icon128.png │ ├── icon16.png │ ├── icon32.png │ └── icon48.png ├── index.html ├── loading.gif ├── loading.html ├── locale.js ├── manifest.json ├── options.css ├── options.html ├── options.js ├── popup.html ├── popup.js └── siteinfo.js └── updates.xml /.gitignore: -------------------------------------------------------------------------------- 1 | autopagerize_for_chrome.pem 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'crxmake' 3 | gem 'rubyzip', '~> 1.2.1' 4 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | crxmake (2.1.3) 5 | zip (~> 2.0.2) 6 | rubyzip (1.2.1) 7 | zip (2.0.2) 8 | 9 | PLATFORMS 10 | ruby 11 | 12 | DEPENDENCIES 13 | crxmake 14 | rubyzip (~> 1.2.1) 15 | 16 | BUNDLED WITH 17 | 1.16.1 18 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # AutoPagerize for Chrome 2 | 3 | ## Description 4 | 5 | Chrome extension to loading next page and inserting into current page. 6 | 7 | Original Firefox(Greasemonkey user script) version is here. 8 | AutoPagerize: 9 | 10 | ## Install 11 | 12 | Install Chrome Extension here. 13 | 14 | 15 | Chrome Web Store 16 | https://chrome.google.com/webstore/detail/autopagerize/igiofjhpmpihnifddepnpngfjhkfenbp 17 | -------------------------------------------------------------------------------- /build.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'crxmake' 5 | 6 | CrxMake.zip( 7 | :ex_dir => "./src", 8 | :pkey => "./autopagerize_for_chrome.pem", 9 | :zip_output => "./autopagerize_for_chrome.zip", 10 | :verbose => true, 11 | :ignorefile => /\.swp/, 12 | :ignoredir => /\.(?:svn|git|cvs)/ 13 | ) 14 | 15 | # CrxMake.make( 16 | # :ex_dir => "./src", 17 | # :pkey => "./autopagerize_for_chrome.pem", 18 | # :crx_output => "./autopagerize_for_chrome.crx", 19 | # :verbose => true, 20 | # :ignorefile => /\.swp/, 21 | # :ignoredir => /\.(?:svn|git|cvs)/ 22 | # ) 23 | -------------------------------------------------------------------------------- /build_fx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd src && zip -r -FS ../autopagerize_for_firefox.zip * 4 | -------------------------------------------------------------------------------- /src/0f0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/0f0.png -------------------------------------------------------------------------------- /src/_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": { 3 | "message": "A browser Extension for auto loading paginated web pages. AutoPagerize use in many web site, and provide efficiently web browsing." 4 | }, 5 | "options" : { 6 | "message": "Options" 7 | }, 8 | "exclude_patterns" : { 9 | "message": "Exclude Patterns" 10 | }, 11 | "example" : { 12 | "message": "Example" 13 | }, 14 | "regexp" : { 15 | "message": "Regexp" 16 | }, 17 | "wildcard" : { 18 | "message": "Wildcard" 19 | }, 20 | "save" : { 21 | "message": "Save" 22 | }, 23 | "status" : { 24 | "message": "Status" 25 | }, 26 | "on_off" : { 27 | "message": "On/Off" 28 | }, 29 | "go_to_web" : { 30 | "message": "Go to website" 31 | }, 32 | "on" : { 33 | "message": "On" 34 | }, 35 | "off" : { 36 | "message": "Off" 37 | }, 38 | "loading" : { 39 | "message": "Loading" 40 | }, 41 | "terminated" : { 42 | "message": "All page loaded" 43 | }, 44 | "error" : { 45 | "message": "Error" 46 | }, 47 | "display_message_bar" : { 48 | "message": "Display Message Bar" 49 | }, 50 | "siteinfo" : { 51 | "message": "Siteinfo" 52 | }, 53 | "update_siteinfo" : { 54 | "message": "Update Siteinfo" 55 | }, 56 | "updated_at" : { 57 | "message": "Updated at" 58 | }, 59 | "size" : { 60 | "message": "Size" 61 | }, 62 | "update_siteinfo_complete" : { 63 | "message": "Updated." 64 | }, 65 | "dummy" : { 66 | "message": "" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/_locales/ja/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": { 3 | "message": "ページごとに分けられたWebページを自動で読み込み継ぎ足し表示を行うブラウザ拡張です。 AutoPagerizeは様々なWebサイトで利用でき、効率的なWebブラウジングを提供します。" 4 | }, 5 | "options" : { 6 | "message": "設定" 7 | }, 8 | "exclude_patterns" : { 9 | "message": "除外パターン" 10 | }, 11 | "example" : { 12 | "message": "例" 13 | }, 14 | "regexp" : { 15 | "message": "正規表現" 16 | }, 17 | "wildcard" : { 18 | "message": "ワイルドカード" 19 | }, 20 | "save" : { 21 | "message": "保存" 22 | }, 23 | "status" : { 24 | "message": "ステータス" 25 | }, 26 | "on_off" : { 27 | "message": "オン/オフ" 28 | }, 29 | "go_to_web" : { 30 | "message": "Webサイトへ" 31 | }, 32 | "on" : { 33 | "message": "有効にする" 34 | }, 35 | "off" : { 36 | "message": "無効にする" 37 | }, 38 | "loading" : { 39 | "message": "ロード中" 40 | }, 41 | "terminated" : { 42 | "message": "全ページ読み込み完了" 43 | }, 44 | "error" : { 45 | "message": "エラー" 46 | }, 47 | "display_message_bar" : { 48 | "message": "メッセージバーを表示" 49 | }, 50 | "siteinfo" : { 51 | "message": "サイト情報" 52 | }, 53 | "update_siteinfo" : { 54 | "message": "サイト情報を更新する" 55 | }, 56 | "updated_at" : { 57 | "message": "更新日時" 58 | }, 59 | "size" : { 60 | "message": "登録数" 61 | }, 62 | "update_siteinfo_complete" : { 63 | "message": "サイト情報を更新しました" 64 | }, 65 | "dummy" : { 66 | "message": "" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/_locales/ru/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": { 3 | "message": "Расширение для браузера для авто-загрузки последующих страниц на сайтах которые это поддерживают AutoPagerize поддерживает множество сайтов, повышая эффективность веб серфинга." 4 | }, 5 | "options" : { 6 | "message": "Настройки" 7 | }, 8 | "exclude_patterns" : { 9 | "message": "Отключить на следующих сайтах" 10 | }, 11 | "example" : { 12 | "message": "Пример" 13 | }, 14 | "regexp" : { 15 | "message": "Regexp" 16 | }, 17 | "wildcard" : { 18 | "message": "Wildcard" 19 | }, 20 | "save" : { 21 | "message": "Сохранить" 22 | }, 23 | "status" : { 24 | "message": "Status" 25 | }, 26 | "on_off" : { 27 | "message": "Вкл./Выкл." 28 | }, 29 | "go_to_web" : { 30 | "message": "Перейти на сайт" 31 | }, 32 | "on" : { 33 | "message": "Вкл" 34 | }, 35 | "off" : { 36 | "message": "Выкл" 37 | }, 38 | "loading" : { 39 | "message": "Загрузка" 40 | }, 41 | "terminated" : { 42 | "message": "Все страницы загружены" 43 | }, 44 | "error" : { 45 | "message": "Ошибка" 46 | }, 47 | "display_message_bar" : { 48 | "message": "Отображать информационную панель" 49 | }, 50 | "dummy" : { 51 | "message": "" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/autopagerize.user.js: -------------------------------------------------------------------------------- 1 | // AutoPagerize 2 | // loading next page and inserting into current page. 3 | // http://autopagerize.net/ 4 | 5 | // 6 | // It doesn't work in Greasemonkey any longer. 7 | // 8 | // this script based on 9 | // GoogleAutoPager(http://la.ma.la/blog/diary_200506231749.htm) and 10 | // estseek autopager(http://la.ma.la/blog/diary_200601100209.htm). 11 | // thanks to ma.la. 12 | // 13 | // Released under the GPL license 14 | // http://www.gnu.org/copyleft/gpl.html 15 | // 16 | 17 | (function() { 18 | 19 | var DEBUG = false 20 | var BASE_REMAIN_HEIGHT = 400 21 | var MIN_REQUEST_INTERVAL = 2000 22 | var FORCE_TARGET_WINDOW = true // FIXME config 23 | var SITEINFO_IMPORT_URLS = [ 24 | 'http://wedata.net/databases/AutoPagerize/items.json', 25 | ] 26 | var SITEINFO = [ 27 | /* sample 28 | { 29 | url: 'http://(.*).google.+/(search).+', 30 | nextLink: 'id("navbar")//td[last()]/a', 31 | pageElement: '//div[@id="res"]/div', 32 | exampleUrl: 'http://www.google.com/search?q=nsIObserver', 33 | }, 34 | */ 35 | /* template 36 | { 37 | url: '', 38 | nextLink: '', 39 | pageElement: '', 40 | exampleUrl: '', 41 | }, 42 | */ 43 | ] 44 | var MICROFORMAT = { 45 | url: '.*', 46 | nextLink: '//a[@rel="next"] | //link[@rel="next"]', 47 | insertBefore: '//*[contains(@class, "autopagerize_insert_before")]', 48 | pageElement: '//*[contains(@class, "autopagerize_page_element")]', 49 | } 50 | 51 | function AutoPager(info) { 52 | this.pageNum = 1 53 | this.info = info 54 | this.state = settings.disable ? 'disable' : 'enable' 55 | var self = this 56 | var url = this.getNextURL(info.nextLink, document, location.href) 57 | 58 | if (!url) { 59 | debug("getNextURL returns null.", info.nextLink) 60 | return 61 | } 62 | if (info.insertBefore) { 63 | this.insertPoint = getFirstElementByXPath(info.insertBefore) 64 | } 65 | 66 | if (!this.insertPoint) { 67 | var lastPageElement = getElementsByXPath(info.pageElement).pop() 68 | if (lastPageElement) { 69 | this.insertPoint = lastPageElement.nextSibling || 70 | lastPageElement.parentNode.appendChild(document.createTextNode(' ')) 71 | } 72 | } 73 | 74 | if (!this.insertPoint) { 75 | debug("insertPoint not found.", lastPageElement, info.pageElement) 76 | return 77 | } 78 | 79 | this.requestURL = url 80 | this.loadedURLs = {} 81 | this.loadedURLs[location.href] = true 82 | var toggle = function() { self.stateToggle() } 83 | this.toggle = toggle 84 | this.scroll= function() { self.onScroll() } 85 | window.addEventListener("scroll", this.scroll, false) 86 | 87 | this.initMessageBar() 88 | extension.addListener('toggleRequest', function(res) { 89 | if (ap) { 90 | ap.toggle() 91 | } 92 | }) 93 | extension.addListener('enableRequest', function(res) { 94 | if (ap) { 95 | ap.enable() 96 | } 97 | }) 98 | extension.addListener('disableRequest', function(res) { 99 | if (ap) { 100 | ap.disable() 101 | } 102 | }) 103 | extension.postMessage('launched', {url: location.href }) 104 | if (Extension.isSafari()) { 105 | document.addEventListener('contextmenu', function(event) { 106 | safari.self.tab.setContextMenuEventUserInfo(event, 'launched') 107 | }, false) 108 | } 109 | 110 | var scrollHeight = getScrollHeight() 111 | var bottom = getElementPosition(this.insertPoint).top || 112 | this.getPageElementsBottom() || 113 | (Math.round(scrollHeight * 0.8)) 114 | this.remainHeight = scrollHeight - bottom + BASE_REMAIN_HEIGHT 115 | this.reqTime = new Date() 116 | this.onScroll() 117 | 118 | var that = this 119 | document.addEventListener('AutoPagerizeToggleRequest', function() { 120 | that.toggle() 121 | }, false) 122 | document.addEventListener('AutoPagerizeEnableRequest', function() { 123 | that.enable() 124 | }, false) 125 | document.addEventListener('AutoPagerizeDisableRequest', function() { 126 | that.disable() 127 | }, false) 128 | document.addEventListener('AutoPagerizeUpdateSettingsRequest', function() { 129 | extension.postMessage('settings', {}, function(res) { 130 | settings = res 131 | }) 132 | }, false) 133 | } 134 | 135 | AutoPager.prototype.getPageElementsBottom = function() { 136 | try { 137 | var elems = getElementsByXPath(this.info.pageElement) 138 | var bs = elems.map(function(i) { return getElementBottom(i) }) 139 | return Math.max.apply(Math, bs) 140 | } 141 | catch(e) {} 142 | } 143 | 144 | AutoPager.prototype.initMessageBar = function() { 145 | var frame = document.createElement('iframe') 146 | frame.id = 'autopagerize_message_bar' 147 | frame.style.display = 'none' 148 | frame.style.position = 'fixed' 149 | frame.style.bottom = '0px' 150 | frame.style.left = '0px' 151 | frame.style.height = '25px' 152 | frame.style.border = '0px' 153 | frame.style.opacity = '0.8' 154 | frame.style.zIndex = '1000' 155 | frame.width = '100%' 156 | frame.scrolling = 'no' 157 | this.messageFrame = frame 158 | 159 | // no icon. 160 | var u = 'data:text/html;base64,PGh0bWw+CjxoZWFkPgo8c3R5bGU+CmJvZHkgewogIG1hcmdpbjogMDsKICBwYWRkaW5nOiA0cHggMCAwIDEwcHg7CiAgY29sb3I6ICNmZmY7CiAgYmFja2dyb3VuZC1jb2xvcjogIzAwMDsKICBmb250LXNpemU6IDEycHg7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CmltZyB7CiAgdmVydGljYWwtYWxpZ246IHRvcDsKfQo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5PkxvYWRpbmcuLi48L2JvZHk+CjwvaHRtbD4K' 161 | if (settings['extension_path']) { 162 | u = settings['extension_path'] + 'loading.html' 163 | } 164 | else if (settings['loading_html']) { 165 | u = settings['loading_html'] 166 | } 167 | this.messageFrame.src = u 168 | document.body.appendChild(frame) 169 | } 170 | 171 | AutoPager.prototype.onScroll = function() { 172 | var scrollHeight = Math.max(document.documentElement.scrollHeight, 173 | document.body.scrollHeight) 174 | var remain = scrollHeight - window.innerHeight - window.scrollY 175 | if (this.state == 'enable' && remain < this.remainHeight) { 176 | this.request() 177 | } 178 | } 179 | 180 | AutoPager.prototype.stateToggle = function() { 181 | if (this.state == 'enable') { 182 | this.disable() 183 | } 184 | else { 185 | this.enable() 186 | } 187 | } 188 | 189 | AutoPager.prototype.enable = function() { 190 | this.state = 'enable' 191 | } 192 | 193 | AutoPager.prototype.disable = function() { 194 | this.state = 'disable' 195 | } 196 | 197 | AutoPager.prototype.request = function() { 198 | if (!this.requestURL || this.lastRequestURL == this.requestURL) { 199 | return 200 | } 201 | var self = this 202 | var now = new Date() 203 | if (this.reqTime && now - this.reqTime < MIN_REQUEST_INTERVAL) { 204 | setTimeout(function() { self.onScroll() }, MIN_REQUEST_INTERVAL) 205 | return 206 | } 207 | else { 208 | this.reqTime = now 209 | } 210 | 211 | this.lastRequestURL = this.requestURL 212 | this.showLoading(true) 213 | var f = ('responseURL' in new XMLHttpRequest()) ? loadWithXHR : loadWithIframe 214 | f(this.requestURL, function(doc, url) { 215 | self.load(doc, url) 216 | }, function(err) { 217 | self.error() 218 | }) 219 | } 220 | 221 | AutoPager.prototype.showLoading = function(sw) { 222 | if (sw) { 223 | if (this.messageFrame && settings['display_message_bar']) { 224 | this.messageFrame.style.display = 'block' 225 | } 226 | } 227 | else { 228 | if (this.messageFrame) { 229 | this.messageFrame.style.display = 'none' 230 | } 231 | } 232 | } 233 | 234 | AutoPager.prototype.load = function(htmlDoc, url) { 235 | if (url && !isSameDomain(url)) { 236 | this.error() 237 | return 238 | } 239 | try { 240 | var page = getElementsByXPath(this.info.pageElement, htmlDoc) 241 | var url = this.getNextURL(this.info.nextLink, htmlDoc, this.requestURL) 242 | } 243 | catch(e){ 244 | this.error() 245 | return 246 | } 247 | 248 | if (!page || page.length < 1 ) { 249 | debug('pageElement not found.' , this.info.pageElement) 250 | this.terminate() 251 | return 252 | } 253 | 254 | if (this.loadedURLs[this.requestURL]) { 255 | debug('page is already loaded.', this.requestURL, this.info.nextLink) 256 | this.terminate() 257 | return 258 | } 259 | 260 | this.loadedURLs[this.requestURL] = true 261 | page = this.addPage(htmlDoc, page) 262 | AutoPager.filters.forEach(function(i) { 263 | i(page) 264 | }) 265 | this.requestURL = url 266 | this.showLoading(false) 267 | this.onScroll() 268 | if (!url) { 269 | debug('nextLink not found.', this.info.nextLink, htmlDoc) 270 | this.terminate() 271 | } 272 | var ev = document.createEvent('Event') 273 | ev.initEvent('GM_AutoPagerizeNextPageLoaded', true, false) 274 | document.dispatchEvent(ev) 275 | } 276 | 277 | AutoPager.prototype.addPage = function(htmlDoc, page) { 278 | var HTML_NS = 'http://www.w3.org/1999/xhtml' 279 | var hr = document.createElementNS(HTML_NS, 'hr') 280 | var p = document.createElementNS(HTML_NS, 'p') 281 | hr.setAttribute('class', 'autopagerize_page_separator') 282 | p.setAttribute('class', 'autopagerize_page_info') 283 | var self = this 284 | 285 | if (getRoot(this.insertPoint) != document) { 286 | var lastPageElement = getElementsByXPath(this.info.pageElement).pop() 287 | if (lastPageElement) { 288 | this.insertPoint = lastPageElement.nextSibling || 289 | lastPageElement.parentNode.appendChild(document.createTextNode(' ')) 290 | } 291 | } 292 | 293 | if (page[0] && /tr/i.test(page[0].tagName)) { 294 | var insertParent = this.insertPoint.parentNode 295 | var colNodes = getElementsByXPath('child::tr[1]/child::*[self::td or self::th]', insertParent) 296 | 297 | var colums = 0 298 | for (var i = 0, l = colNodes.length; i < l; i++) { 299 | var col = colNodes[i].getAttribute('colspan') 300 | colums += parseInt(col, 10) || 1 301 | } 302 | var td = document.createElement('td') 303 | // td.appendChild(hr) 304 | td.appendChild(p) 305 | var tr = document.createElement('tr') 306 | td.setAttribute('colspan', colums) 307 | tr.appendChild(td) 308 | insertParent.insertBefore(tr, this.insertPoint) 309 | } 310 | else { 311 | this.insertPoint.parentNode.insertBefore(hr, this.insertPoint) 312 | this.insertPoint.parentNode.insertBefore(p, this.insertPoint) 313 | } 314 | 315 | var aplink = document.createElement('a') 316 | aplink.className = 'autopagerize_link' 317 | aplink.href = this.requestURL 318 | aplink.appendChild(document.createTextNode(String(++this.pageNum))) 319 | p.appendChild(document.createTextNode('page: ')) 320 | p.appendChild(aplink) 321 | 322 | return page.map(function(i) { 323 | var pe = document.importNode(i, true) 324 | self.insertPoint.parentNode.insertBefore(pe, self.insertPoint) 325 | var ev = document.createEvent('MutationEvent') 326 | ev.initMutationEvent('AutoPagerize_DOMNodeInserted', true, false, 327 | self.insertPoint.parentNode, null, 328 | self.requestURL, null, null) 329 | pe.dispatchEvent(ev) 330 | return pe 331 | }) 332 | } 333 | 334 | AutoPager.prototype.getNextURL = function(xpath, doc, url) { 335 | var nextLink = getFirstElementByXPath(xpath, doc) 336 | if (nextLink) { 337 | var nextValue = nextLink.getAttribute('href') || 338 | nextLink.getAttribute('action') || nextLink.value 339 | if (nextValue.match(/^http(s)?:/)) { 340 | return nextValue 341 | } 342 | else { 343 | var base = getFirstElementByXPath('//base[@href]', doc) 344 | return resolvePath(nextValue, (base ? base.href : url)) 345 | } 346 | } 347 | } 348 | 349 | AutoPager.prototype.terminate = function() { 350 | window.removeEventListener('scroll', this.scroll, false) 351 | var self = this 352 | setTimeout(function() { 353 | if (self.icon) { 354 | self.icon.parentNode.removeChild(self.icon) 355 | } 356 | if (self.messageFrame) { 357 | var mf = self.messageFrame 358 | mf.parentNode.removeChild(mf) 359 | } 360 | }, 1500) 361 | } 362 | 363 | AutoPager.prototype.error = function() { 364 | window.removeEventListener('scroll', this.scroll, false) 365 | if (this.messageFrame) { 366 | var mf = this.messageFrame 367 | var u = 'data:text/html;base64,PGh0bWw+CjxoZWFkPgo8c3R5bGU+CmJvZHkgewogIG1hcmdpbjogMDsKICBwYWRkaW5nOiA0cHggMCAwIDEwcHg7CiAgY29sb3I6ICNmZmY7CiAgYmFja2dyb3VuZC1jb2xvcjogI2EwMDsKICBmb250LXNpemU6IDEycHg7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CmltZyB7CiAgdmVydGljYWwtYWxpZ246IHRvcDsKfQo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5PkVycm9yITwvYm9keT4KPC9odG1sPgo=' 368 | if (settings['extension_path']) { 369 | u = settings['extension_path'] + 'error.html' 370 | } 371 | else if (settings['error_html']) { 372 | u = settings['error_html'] 373 | } 374 | mf.src = u 375 | mf.style.display = 'block' 376 | setTimeout(function() { 377 | if (mf) { 378 | mf.parentNode.removeChild(mf) 379 | } 380 | }, 3000) 381 | } 382 | } 383 | AutoPager.filters = [] 384 | AutoPager.launchAutoPager = function(list) { 385 | if (list.length == 0) { 386 | return 387 | } 388 | for (var i = 0; i < list.length; i++) { 389 | try { 390 | if (ap) { 391 | return 392 | } 393 | else if (!location.href.match(list[i].url)) { 394 | } 395 | else if (!getFirstElementByXPath(list[i].nextLink)) { 396 | // FIXME microformats case detection. 397 | // limiting greater than 12 to filter microformats like SITEINFOs. 398 | if (list[i].url.length > 12 ) { 399 | debug("nextLink not found.", list[i].nextLink) 400 | } 401 | } 402 | else if (!getFirstElementByXPath(list[i].pageElement)) { 403 | if (list[i].url.length > 12 ) { 404 | debug("pageElement not found.", list[i].pageElement) 405 | } 406 | } 407 | else { 408 | ap = new AutoPager(list[i]) 409 | return 410 | } 411 | } 412 | catch(e) { 413 | continue 414 | } 415 | } 416 | } 417 | 418 | // firefox about:addon(http://localhost/extensions-dummy/discoveryURL) 419 | // Error: Permission denied to access property 'href' 420 | if (Extension.isFirefox()) { 421 | try { 422 | if (window.location.href != window.parent.location.href) { 423 | return 424 | } 425 | } 426 | catch(e) { 427 | return 428 | } 429 | } 430 | else if (window != window.parent) { 431 | return 432 | } 433 | 434 | if (Extension.isFirefox()) { 435 | fixResolvePath() 436 | } 437 | 438 | if (typeof(window.AutoPagerize) == 'undefined') { 439 | window.AutoPagerize = {} 440 | window.AutoPagerize.addFilter = function(f) { 441 | AutoPager.filters.push(f) 442 | } 443 | window.AutoPagerize.launchAutoPager = AutoPager.launchAutoPager 444 | var ev = document.createEvent('Event') 445 | ev.initEvent('GM_AutoPagerizeLoaded', true, false) 446 | document.dispatchEvent(ev) 447 | } 448 | 449 | var settings = {} 450 | var ap = null 451 | var extension = new Extension() 452 | extension.postMessage('settings', {}, function(res) { 453 | settings = res 454 | extension.postMessage('siteinfo', { url: location.href }, function(res) { 455 | if (!settings['exclude_patterns'] || !isExclude(settings['exclude_patterns'])) { 456 | var f = function() { 457 | AutoPager.launchAutoPager(SITEINFO) 458 | AutoPager.launchAutoPager(res) 459 | AutoPager.launchAutoPager([MICROFORMAT]) 460 | } 461 | f() 462 | !ap && setTimeout(f, 2000) 463 | } 464 | }) 465 | }) 466 | extension.addListener('updateSettings', function(res) { 467 | settings = res 468 | }) 469 | 470 | // new google search sucks! 471 | if (location.href.match('^http://[^.]+\.google\.(?:[^.]{2,3}\.)?[^./]{2,3}/.*(&fp=)')) { 472 | var to = location.href.replace(/&fp=.*/, '') 473 | // console.log([location.href, to]) 474 | location.href = to 475 | } 476 | // fix youtube thumbnails 477 | // http://www.youtube.com/results?search_query=a 478 | if ((/^https?:\/\/www.youtube.com\/results.+/).test(location.href)) { 479 | var youtubeSearchShowThumbnalFilter = function(nodes) { 480 | nodes.forEach(function(i) { 481 | Array.prototype.slice.call( 482 | i.querySelectorAll('img[data-thumb]') 483 | ).forEach(function(i) { 484 | if ((/\.gif$/).test(i.src) && i.dataset.thumb) { 485 | i.src = i.dataset.thumb 486 | } 487 | }) 488 | }) 489 | } 490 | AutoPager.filters.push(youtubeSearchShowThumbnalFilter) 491 | } 492 | 493 | // utility functions. 494 | function getElementsByXPath(xpath, node) { 495 | var nodesSnapshot = getXPathResult(xpath, node, 496 | XPathResult.ORDERED_NODE_SNAPSHOT_TYPE || 7) 497 | var data = [] 498 | for (var i = 0; i < nodesSnapshot.snapshotLength; i++) { 499 | data.push(nodesSnapshot.snapshotItem(i)) 500 | } 501 | return data 502 | } 503 | 504 | function getFirstElementByXPath(xpath, node) { 505 | var result = getXPathResult(xpath, node, 506 | XPathResult.FIRST_ORDERED_NODE_TYPE || 9) 507 | return result.singleNodeValue 508 | } 509 | 510 | function getXPathResult(xpath, node, resultType) { 511 | var node = node || document 512 | var doc = node.ownerDocument || node 513 | var resolver = doc.createNSResolver(node.documentElement || node) 514 | // Use |node.lookupNamespaceURI('')| for Opera 9.5 515 | var defaultNS = node.lookupNamespaceURI(null) 516 | 517 | if (defaultNS) { 518 | const defaultPrefix = '__default__' 519 | xpath = addDefaultPrefix(xpath, defaultPrefix) 520 | var defaultResolver = resolver 521 | resolver = function (prefix) { 522 | return (prefix == defaultPrefix) 523 | ? defaultNS : defaultResolver.lookupNamespaceURI(prefix) 524 | } 525 | } 526 | return doc.evaluate(xpath, node, resolver, resultType, null) 527 | } 528 | 529 | function addDefaultPrefix(xpath, prefix) { 530 | const tokenPattern = /([A-Za-z_\u00c0-\ufffd][\w\-.\u00b7-\ufffd]*|\*)\s*(::?|\()?|(".*?"|'.*?'|\d+(?:\.\d*)?|\.(?:\.|\d+)?|[\)\]])|(\/\/?|!=|[<>]=?|[\(\[|,=+-])|([@$])/g 531 | const TERM = 1, OPERATOR = 2, MODIFIER = 3 532 | var tokenType = OPERATOR 533 | prefix += ':' 534 | function replacer(token, identifier, suffix, term, operator, modifier) { 535 | if (suffix) { 536 | tokenType = 537 | (suffix == ':' || (suffix == '::' && 538 | (identifier == 'attribute' || identifier == 'namespace'))) 539 | ? MODIFIER : OPERATOR 540 | } 541 | else if (identifier) { 542 | if (tokenType == OPERATOR && identifier != '*') { 543 | token = prefix + token 544 | } 545 | tokenType = (tokenType == TERM) ? OPERATOR : TERM 546 | } 547 | else { 548 | tokenType = term ? TERM : operator ? OPERATOR : MODIFIER 549 | } 550 | return token 551 | } 552 | return xpath.replace(tokenPattern, replacer) 553 | } 554 | 555 | function debug() { 556 | if (typeof DEBUG != 'undefined' && DEBUG && console.log.apply) { 557 | console.log.apply(console, arguments) 558 | } 559 | } 560 | 561 | function getElementPosition(elem) { 562 | var offsetTrail = elem 563 | var offsetLeft = 0 564 | var offsetTop = 0 565 | while (offsetTrail) { 566 | offsetLeft += offsetTrail.offsetLeft 567 | offsetTop += offsetTrail.offsetTop 568 | offsetTrail = offsetTrail.offsetParent 569 | } 570 | offsetTop = offsetTop || null 571 | offsetLeft = offsetLeft || null 572 | return {left: offsetLeft, top: offsetTop} 573 | } 574 | 575 | function getElementBottom(elem) { 576 | var c_style = document.defaultView.getComputedStyle(elem, '') 577 | var height = 0 578 | var prop = ['height', 'borderTopWidth', 'borderBottomWidth', 579 | 'paddingTop', 'paddingBottom', 580 | 'marginTop', 'marginBottom'] 581 | prop.forEach(function(i) { 582 | var h = parseInt(c_style[i]) 583 | if (typeof h == 'number') { 584 | height += h 585 | } 586 | }) 587 | var top = getElementPosition(elem).top 588 | return top ? (top + height) : null 589 | } 590 | 591 | function getScrollHeight() { 592 | return Math.max(document.documentElement.scrollHeight, 593 | document.body.scrollHeight) 594 | } 595 | 596 | function isSameDomain(url) { 597 | if (url.match(/^\w+:/)) { 598 | return location.host == url.split('/')[2] 599 | } 600 | else { 601 | return true 602 | } 603 | } 604 | 605 | function isSameBaseUrl(urlA, urlB) { 606 | return (urlA.replace(/[^/]+$/, '') == urlB.replace(/[^/]+$/, '')) 607 | } 608 | 609 | function resolvePath(path, base) { 610 | if (path.match(/^https?:\/\//)) { 611 | return path 612 | } 613 | else if (path.match(/^\?/)) { 614 | return base.replace(/\?.+$/, '') + path 615 | } 616 | else if (path.match(/^[^\/]/)) { 617 | return base.replace(/[^/]+$/, '') + path 618 | } 619 | else { 620 | return base.replace(/([^/]+:\/\/[^/]+)\/.*/, '\$1') + path 621 | } 622 | } 623 | 624 | function fixResolvePath() { 625 | if (resolvePath('', 'http://resolve.test/') == 'http://resolve.test/') { 626 | return 627 | } 628 | // A workaround for WebKit and Mozilla 1.9.2a1pre, 629 | // which don't support XML Base in HTML. 630 | // https://bugs.webkit.org/show_bug.cgi?id=17423 631 | // https://bugzilla.mozilla.org/show_bug.cgi?id=505783 632 | var XML_NS = 'http://www.w3.org/XML/1998/namespace' 633 | var baseElement = document.createElementNS(null, 'base') 634 | var pathElement = document.createElementNS(null, 'path') 635 | baseElement.appendChild(pathElement) 636 | resolvePath = function resolvePath_workaround(path, base) { 637 | baseElement.setAttributeNS(XML_NS, 'xml:base', base) 638 | pathElement.setAttributeNS(XML_NS, 'xml:base', path) 639 | return pathElement.baseURI 640 | } 641 | } 642 | 643 | function strip_html_tag(str) { 644 | var chunks = str.split(/(]*)?>)/) 645 | if (chunks.length >= 3) { 646 | chunks.splice(0, 2) 647 | } 648 | str = chunks.join('') 649 | chunks = str.split(/(<\/html[ \t\r\n]*>)/) 650 | if (chunks.length >= 3) { 651 | chunks.splice(chunks.length - 2) 652 | } 653 | return chunks.join('') 654 | } 655 | 656 | function wildcard2regep(str) { 657 | return '^' + str.replace(/([-()\[\]{}+?.$\^|,:# 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/background.js: -------------------------------------------------------------------------------- 1 | var SITEINFO_IMPORT_URLS = [ 2 | 'http://wedata.net/databases/AutoPagerize/items_all.json', 3 | ] 4 | var CACHE_EXPIRE = 24 * 60 * 60 * 1000 5 | var siteinfo = {} 6 | window.onload = init 7 | 8 | var excludes = [ 9 | 'https://mail.google.com/*', 10 | 'http://b.hatena.ne.jp/*', 11 | 'http://www.facebook.com/plugins/like.php*', 12 | 'http://api.tweetmeme.com/button.js*' 13 | ] 14 | function init() { 15 | if (!localStorage['settings']) { 16 | var defaultSettings = { 17 | extension_path: chrome.extension.getURL(''), 18 | display_message_bar: true, 19 | exclude_patterns: localStorage['exclude_patterns'] || '' 20 | } 21 | localStorage['settings'] = JSON.stringify(defaultSettings) 22 | } 23 | chrome.runtime.onConnect.addListener(function(port) { 24 | port.onMessage.addListener(function(message, con) { 25 | if (message.name == 'settings') { 26 | var res = JSON.parse(localStorage['settings']) 27 | res.exclude_patterns += ' ' + excludes.join(' ') 28 | con.postMessage({ name: message.name, data: res }) 29 | } 30 | else if (message.name == 'siteinfo') { 31 | var res = SITEINFO_IMPORT_URLS.reduce(function(r, url) { 32 | return r.concat(siteinfo[url].info) 33 | }, []).filter(function(s) { 34 | try { 35 | return message.data.url.match(s.url) 36 | } 37 | catch(e) { 38 | // console.log(e); 39 | } 40 | }) 41 | con.postMessage({ name: message.name, data: res }) 42 | } 43 | else if (message.name == 'launched') { 44 | var tabid = con.sender.tab.id 45 | chrome.pageAction.show(tabid) 46 | chrome.pageAction.setIcon({ 47 | tabId:tabid, path: 'icons/icon16.png' 48 | }) 49 | } 50 | else if (message.name == 'siteinfo_meta') { 51 | var u = SITEINFO_IMPORT_URLS[0] 52 | var len = siteinfo[u].info.length 53 | var updated_at = siteinfo[u].expire - CACHE_EXPIRE 54 | con.postMessage({ name: message.name, len: len, updated_at: updated_at }) 55 | } 56 | else if (message.name == 'update_siteinfo') { 57 | refreshSiteinfo({ force: true, callback: function() { 58 | con.postMessage({ name: message.name, res: 'ok' }) 59 | }}) 60 | } 61 | }) 62 | 63 | // popup|options -> bg -> content 64 | chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { 65 | if (request.name == 'disable_from_popup') { 66 | port.postMessage({ name: request.data }) 67 | } 68 | else if (request.name == 'update_setting_from_options') { 69 | port.postMessage({ name: 'updateSettings', data: request.data }) 70 | } 71 | }) 72 | }) 73 | } 74 | 75 | function loadLocalSiteinfoCallback(data) { 76 | var url = 'http://wedata.net/databases/AutoPagerize/items_all.json' 77 | var url_old = 'http://wedata.net/databases/AutoPagerize/items.json' 78 | var cache = JSON.parse(localStorage['cacheInfo'] || '{}') 79 | if (!cache[url]) { 80 | siteinfo[url] = { 81 | url: url, 82 | expire: new Date().getTime() - 1, 83 | info: reduceWedataJSON(data) 84 | } 85 | cache[url] = siteinfo[url] 86 | localStorage['cacheInfo'] = JSON.stringify(cache) 87 | } 88 | else { 89 | siteinfo[url] = cache[url] 90 | } 91 | 92 | // remove old url cache 93 | if (cache[url_old]) { 94 | delete cache[url_old] 95 | localStorage['cacheInfo'] = JSON.stringify(cache) 96 | } 97 | refreshSiteinfo() 98 | } 99 | 100 | function reduceWedataJSON(data) { 101 | var r_keys = ['url', 'nextLink', 'insertBefore', 'pageElement'] 102 | var info = data.map(function(i) { 103 | return i.data 104 | }).filter(function(i) { 105 | return ('url' in i) 106 | }) 107 | if (info.length == 0) { 108 | return [] 109 | } 110 | else { 111 | info.sort(function(a, b) { 112 | return (b.url.length - a.url.length) 113 | }) 114 | return info.map(function(i) { 115 | var item = {} 116 | r_keys.forEach(function(key) { 117 | if (i[key]) { 118 | item[key] = i[key] 119 | } 120 | }) 121 | return item 122 | }) 123 | } 124 | } 125 | 126 | function refreshSiteinfo(opt) { 127 | var opt = opt || {} 128 | var cache = JSON.parse(localStorage['cacheInfo'] || '{}') 129 | SITEINFO_IMPORT_URLS.forEach(function(url) { 130 | if (opt.force || !cache[url] || (cache[url].expire && new Date(cache[url].expire) < new Date())) { 131 | var callback = function(res) { 132 | if (res.status != 200) { 133 | return 134 | } 135 | var info = reduceWedataJSON(JSON.parse(res.responseText)) 136 | if (info.length == 0) { 137 | return 138 | } 139 | siteinfo[url] = { 140 | url: url, 141 | expire: new Date().getTime() + CACHE_EXPIRE, 142 | info: info 143 | } 144 | cache[url] = siteinfo[url] 145 | localStorage['cacheInfo'] = JSON.stringify(cache) 146 | if (opt.callback) { 147 | opt.callback() 148 | } 149 | } 150 | try { 151 | get(url, callback) 152 | } 153 | catch(e) { 154 | } 155 | } 156 | }) 157 | } 158 | 159 | function get(url, callback, opt) { 160 | var xhr = new XMLHttpRequest() 161 | xhr.onreadystatechange = function() { 162 | if (xhr.readyState == 4) { 163 | callback(xhr) 164 | } 165 | } 166 | xhr.open('GET', url, true) 167 | xhr.send(null) 168 | return xhr 169 | } 170 | -------------------------------------------------------------------------------- /src/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | Error! 18 | 19 | -------------------------------------------------------------------------------- /src/extension.js: -------------------------------------------------------------------------------- 1 | // Extension.js 2 | // Browser Extension API Abstraction 3 | // The MIT License 4 | // Copyright (c) 2010 swdyh 5 | function Extension() { 6 | this.listeners = {} 7 | var that = this 8 | var callback = function(message) { 9 | if (message && message.name && that.listeners[message.name]) { 10 | that.listeners[message.name](message.data) 11 | } 12 | } 13 | if (Extension.isSafari()) { 14 | safari.self.addEventListener('message', function(event) { 15 | callback({ name: event.name, data: event.message }) 16 | }) 17 | } 18 | else if (Extension.isChrome()) { 19 | this.port = chrome.runtime.connect({ name: 'message' }) 20 | this.port.onMessage.addListener(callback) 21 | chrome.runtime.onConnect.addListener(function(port) { 22 | if (port.name == 'message') { 23 | port.onMessage.addListener(callback) 24 | } 25 | }) 26 | chrome.runtime.onMessage.addListener(callback) 27 | } 28 | else if (Extension.isFirefox()) { 29 | self.on('message', function(res) { 30 | callback({ name: res.name, data: res.data }) 31 | }) 32 | } 33 | } 34 | Extension.prototype.postMessage = function(name, data, callback) { 35 | this.listeners[name] = callback || function() {} 36 | if (Extension.isSafari()) { 37 | safari.self.tab.dispatchMessage(name, data) 38 | } 39 | else if (Extension.isChrome()) { 40 | this.port.postMessage({ name: name, data: data }) 41 | } 42 | else if (Extension.isFirefox()) { 43 | self.postMessage({ name: name, data: data }) 44 | } 45 | } 46 | Extension.prototype.addListener = function(name, callback) { 47 | this.listeners[name] = callback 48 | } 49 | Extension.isSafari = function() { 50 | return (typeof safari == 'object') && 51 | (typeof safari.extension == 'object') 52 | } 53 | Extension.isChrome = function() { 54 | return (typeof chrome == 'object') && 55 | (typeof chrome.extension == 'object') 56 | } 57 | Extension.isGreasemonkey = function() { 58 | return (typeof GM_log == 'function') 59 | } 60 | Extension.isFirefox = function() { 61 | // FIXME 62 | return (!Extension.isGreasemonkey() && !Extension.isSafari() && !Extension.isChrome()) 63 | } 64 | -------------------------------------------------------------------------------- /src/icons/00f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/icons/00f.png -------------------------------------------------------------------------------- /src/icons/0f0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/icons/0f0.png -------------------------------------------------------------------------------- /src/icons/0ff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/icons/0ff.png -------------------------------------------------------------------------------- /src/icons/ccc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/icons/ccc.png -------------------------------------------------------------------------------- /src/icons/f0f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/icons/f0f.png -------------------------------------------------------------------------------- /src/icons/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/icons/icon128.png -------------------------------------------------------------------------------- /src/icons/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/icons/icon16.png -------------------------------------------------------------------------------- /src/icons/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/icons/icon32.png -------------------------------------------------------------------------------- /src/icons/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/icons/icon48.png -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | AutoPagerize for Chrome 4 | 5 | Settings 6 | Not implemented 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swdyh/autopagerize_for_chrome/2d77be57cdd54a0b537b7ff6b6aff181b469801a/src/loading.gif -------------------------------------------------------------------------------- /src/loading.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | Loading... 18 | 19 | -------------------------------------------------------------------------------- /src/locale.js: -------------------------------------------------------------------------------- 1 | function setLocalesAll() { 2 | var es = document.querySelectorAll('.i18n') 3 | Array.prototype.slice.call(es).forEach(function(i) { 4 | setLocales(i) 5 | }) 6 | } 7 | 8 | function setLocales(node) { 9 | var name = null 10 | if (node.nodeName == 'INPUT' && (node.type == 'submit' || node.type == 'button')) { 11 | name = node.value 12 | } 13 | else { 14 | name = node.innerHTML 15 | } 16 | var message = chrome.i18n.getMessage(name) 17 | if (message) { 18 | if (node.nodeName == 'INPUT' && (node.type == 'submit' || node.type == 'button')) { 19 | node.value = message 20 | } 21 | else { 22 | //node.innerText = message 23 | node.innerHTML = message 24 | } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "homepage_url": "http://autopagerize.net/", 4 | "content_scripts": [ 5 | { 6 | "js": [ 7 | "extension.js", 8 | "autopagerize.user.js" 9 | ], 10 | "matches": [ 11 | "http://*/*", 12 | "https://*/*" 13 | ], 14 | "run_at": "document_end" 15 | } 16 | ], 17 | "description": "A browser Extension for auto loading paginated web pages. AutoPagerize use in many web site, and provide efficiently web browsing.", 18 | "name": "AutoPagerize", 19 | "permissions": [ 20 | "http://wedata.net/*", 21 | "tabs" 22 | ], 23 | "background": { 24 | "page": "background.html" 25 | }, 26 | "options_ui": { "page": "options.html" }, 27 | "version": "0.3.9", 28 | "icons": { 29 | "16": "icons/icon16.png", 30 | "32": "icons/icon32.png", 31 | "48": "icons/icon48.png", 32 | "128": "icons/icon128.png" 33 | }, 34 | "page_action": { 35 | "default_title": "Autopagerize for Chrome", 36 | "default_popup": "popup.html", 37 | "default_icon": "icons/icon16.png" 38 | }, 39 | "default_locale": "en", 40 | "web_accessible_resources": [ 41 | "error.html", 42 | "loading.html", 43 | "loading.gif" 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /src/options.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0 20px; 3 | font-family: sans-serif; 4 | background-color: #eee; 5 | color: #444; 6 | } 7 | .desc { 8 | margin: 3px 0 10px 7px; 9 | font-size: 90%; 10 | } 11 | code { 12 | background-color: #fffff9; 13 | } 14 | textarea { 15 | background-color: #fffff9; 16 | color: #444; 17 | } 18 | .icon { 19 | vertical-align: bottom; 20 | } 21 | .footer { 22 | position: fixed; 23 | bottom: 1em; 24 | font-size: 80%; 25 | } 26 | a, a:visited { 27 | color: #333; 28 | } 29 | .footer a { 30 | font-size: 90%; 31 | } 32 | -------------------------------------------------------------------------------- /src/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | options 10 | 11 | 12 | 13 | display_message_bar 14 | 15 | 16 | 17 | 18 | exclude_patterns 19 | 20 | 21 | 22 | 23 | 24 | example(wildcard): http://www.example.com/search?* 25 | 26 | example(regexp): /[^.]+\.example\.com\// 27 | 28 | 29 | 30 | 31 | 32 | 33 | siteinfo 34 | size: 35 | updated_at: 36 | 37 | 38 | 39 | 40 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/options.js: -------------------------------------------------------------------------------- 1 | function set(key, val) { 2 | localStorage[key] = val 3 | return val 4 | } 5 | function init() { 6 | setLocalesAll() 7 | 8 | var settings = JSON.parse(localStorage['settings']) 9 | var form = document.getElementById('settings_form') 10 | var form_ep = document.getElementById('form_ep') 11 | var form_dm = document.getElementById('form_dm') 12 | form_ep.value = settings['exclude_patterns'] || '' 13 | form_dm.checked = settings['display_message_bar'] === false ? false : 'checked' 14 | form.addEventListener('submit', function() { 15 | settings['exclude_patterns'] = form_ep.value 16 | settings['display_message_bar'] = !!form_dm.checked 17 | localStorage['settings'] = JSON.stringify(settings) 18 | chrome.runtime.sendMessage({ name: 'update_setting_from_options', data: settings }) 19 | }, false) 20 | updateCacheInfoInfo() 21 | 22 | var us = document.getElementById('update_siteinfo') 23 | us.addEventListener('click', updateCacheInfo) 24 | } 25 | 26 | function updateCacheInfoInfo() { 27 | var port = chrome.runtime.connect( { name: 'siteinfo_meta' }) 28 | port.onMessage.addListener(function(res) { 29 | if (res.len) { 30 | document.getElementById('siteinfo_size').innerHTML = res.len 31 | } 32 | if (res.updated_at) { 33 | var d = new Date(res.updated_at) 34 | document.getElementById('siteinfo_updated_at').innerHTML = d 35 | } 36 | }) 37 | port.postMessage({ name: 'siteinfo_meta' }) 38 | } 39 | 40 | function updateCacheInfo() { 41 | var port = chrome.runtime.connect( { name: 'update_siteinfo' }) 42 | port.onMessage.addListener(function(res) { 43 | if (res.res == 'ok') { 44 | updateCacheInfoInfo() 45 | alert(chrome.i18n.getMessage('update_siteinfo_complete')) 46 | } 47 | }) 48 | port.postMessage({ name: 'update_siteinfo' }) 49 | } 50 | 51 | window.addEventListener('load', init, false) 52 | -------------------------------------------------------------------------------- /src/popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 33 | 34 | 35 | 36 | AutoPagerize 37 | 38 | on_off 39 | options 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/popup.js: -------------------------------------------------------------------------------- 1 | function toggle() { 2 | var settings = JSON.parse(localStorage['settings']) 3 | chrome.runtime.sendMessage({ name: 'disable_from_popup', data: settings.disable ? 'enableRequest' : 'disableRequest' }) 4 | settings.disable = !settings.disable 5 | localStorage['settings'] = JSON.stringify(settings) 6 | window.close() 7 | } 8 | function openOptionsPage() { 9 | window.close() 10 | window.open('options.html') 11 | } 12 | function init() { 13 | var settings = JSON.parse(localStorage['settings']) 14 | var t = document.getElementById('toggle') 15 | t.innerText = settings.disable ? 'on' : 'off' 16 | t.addEventListener('click', toggle, false) 17 | var o = document.getElementById('open_options_page') 18 | o.addEventListener('click', openOptionsPage, false) 19 | setLocalesAll() 20 | } 21 | window.addEventListener('load', init, false) 22 | -------------------------------------------------------------------------------- /updates.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | --------------------------------------------------------------------------------
Not implemented
http://www.example.com/search?*
/[^.]+\.example\.com\//