Commits

Anton Afanasyev committed 524ece7

beginning to work on loading pages 'in reverse' - when you scroll high up,
you'll get the previous page to load. unfortunately, this WILL require changes
to all existing SITEINFO structures, since they do not have a "prevLink" regexp

Comments (0)

Files changed (1)

 // @exclude        http://b.hatena.ne.jp/*
 // @exclude        http://www.facebook.com/plugins/like.php*
 // @exclude        http://api.tweetmeme.com/button.js*
-// @version        0.0.66
+// @version        0.0.67
 // @updateURL      https://bitbucket.org/aasoft/autopagerize-extended/raw/tip/autopagerize.user.js
 // @icon           http://autopagerize.net/img/icons/icon_032.png
 // @grant          GM_getValue
     if(null == rH || rH.toString() == 'NaN')
         rH = 0;
 
-    var scrollHeight = getScrollHeight();
-    var bottom = getElementPosition(this.insertPoint).top || this.getPageElementsBottom() || (Math.round(scrollHeight * 0.8));
-    this.remainHeight = scrollHeight - bottom + BASE_REMAIN_HEIGHT + rH;
+    // TODO: split these out into a separate setup function
+
+    var scrollHeight = getScrollHeight( document ); // the vertical height of the window
+    var bottom = getElementPosition(this.insertPoint).top || this.getPageElementsBottom() || (Math.round(scrollHeight * 0.8)); // where in the window the bottom of content is located
+    this.remainHeight = scrollHeight - bottom + BASE_REMAIN_HEIGHT + rH; // how much space between current viewport and the bottom can remain to start loading
+
+    var topSetup = getElementPosition( this.getPageElements() ).top;
+    this.remainHeightTop = topSetup + BASE_REMAIN_HEIGHT + rH; // if we're this far from the top, load previous page
 
     var that = this;
     document.addEventListener('AutoPagerizeToggleRequest', function() { that.toggle(); }, false);
     if(leftMouseDown)
         return;
     removeLastPageData(this, false);
-    var scrollHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
+    var scrollHeight = getScrollHeight( document );
     var remain = scrollHeight - window.innerHeight - window.scrollY;
     
-    // TODO: add prevLink
-    //                                                          AA
-    if (this.state == 'enable' && remain < this.remainHeight && !this.shouldLoadAll) {
-        this.request();
+    if (this.state == 'enable') {
+        // we force loading on scoll only if loading all wasn't triggered/force - loading next page will happen from there automatically
+        if( !this.shouldLoadAll ) {
+            if ( remain < this.remainHeight ) {
+                // request next page
+                this.request();
+            } else if ( window.scrollY < this.remainHeightTop ) {
+                // or the prev page
+                this.requestPrev();
+            }
+        }
     }
 }
 
         this.icon.style.background = color;
 }
 
+AutoPager.prototype.requestPrev = function() {
+    return;
+    if (!this.requestURL || this.lastRequestURL == this.requestURL) {
+        return;
+    }
+
+    /*// if the page want to load does not have a slash or a backslash, then strip the previous page of everything after the last slash (or backslash), and append the next page
+    var i = Math.max(this.requestURL.indexOf('/'), this.requestURL.indexOf('\\'));
+    if(i<0) {
+        // no slash found, so parse the previous page
+        i = Math.max(this.lastRequestURL.lastIndexOf('\\'), this.lastRequestURL.lastIndexOf('/'));
+        var t = this.lastRequestURL.substring(0, i+1);
+        this.requestURL = t + this.requestURL;
+    }*/
+
+    this.lastRequestURL = this.requestURL;
+    var self = this;
+    var mime = 'text/html; charset=' + document.characterSet;
+    var headers = {};
+    if (isSameDomain(this.requestURL)) {
+        headers.Cookie = document.cookie;
+    } else {
+        log("requesting not from same domain");
+        this.error();
+        return;
+    } 
+    var tt = this.requestURL;
+    var opt = {
+        method: 'GET',
+        url: this.requestURL,
+        headers: headers,
+        overrideMimeType: mime,
+        onerror: function(res) {
+            log(tt + "\nrequest prev error:\nstatus: " + res.status + "\nstatusText: " + res.statusText + "\nreadyState: " + res.readyState + "\nresponseText: " + res.responseText + "\nresponseHeaders: " + res.responseHeaders + "\nfinalUrl: " + res.finalUrl);
+            self.error()
+        },
+        onload: function(res) {
+            if (res.finalUrl) {
+                var url_s = res.finalUrl.split(/[\/\?]/);
+                if (url_s[0] == location.protocol && location.host == url_s[2]) {
+                    self.requestLoadPrev.apply(self, [res]);
+                    return;
+                }
+            }
+            log("loaded prev page, but returned url not same as requested. Loaded: '" + res.finalUrl + "'; Requested: '" + location.host + "'");
+            self.error();
+        }
+    };
+    AutoPager.requestFilters.forEach(function(i) { i(opt); }, this);
+    if (opt.stop) {
+        this.requestURL = opt.url;
+    } else {
+        this.showLoading(true);
+        GM_xmlhttpRequest(opt);
+    }};
+
 AutoPager.prototype.request = function() {
     if (!this.requestURL || this.lastRequestURL == this.requestURL) {
         return;
     }
 }
 
-AutoPager.prototype.requestLoad = function(res) {
+AutoPager.prototype.parseRequestLoad_ = function( res ) {
     AutoPager.responseFilters.forEach(function(i){ i(res, this.requestURL); }, this);
 
-    if (res.finalUrl)
-        this.requestURL = res.finalUrl;
-
     var htmlDoc = createHTMLDocumentByString(res.responseText);
     AutoPager.documentFilters.forEach(function(i) { i(htmlDoc, this.requestURL, this.info); }, this);
+    var page;
+    var url;
     try {
-        var page = this.getPageElements(htmlDoc);
-        var url = getNextURL(this.info.nextLink, htmlDoc, this.requestURL);
+        page = this.getPageElements(htmlDoc);
+        url = getNextURL(this.info.nextLink, htmlDoc, this.requestURL);
     } catch(e) {
         log(e);
         this.error();
-        return;
+        return null;
     }
 
-    if (!page || page.length < 1 ) {
+    var ret = {
+        isFinalUrl: res.finalUrl,
+        page:       page,
+        htmlDoc:    htmlDoc,
+        url:        url
+    };
+
+    return ret;
+};
+AutoPager.prototype.requestLoadPrev = function(res) {
+    var data = this.parseRequestLoad_( res );
+    if( !data )
+        return;
+
+    if( data.finalUrl )
+        this.requestURL = data.finalURL;
+
+    if ( !data.page || data.page.length < 1 ) {
         debug('pageElement not found.' , this.info.pageElement);
         this.terminate();
         return;
     }
 
     this.loadedURLs[this.requestURL] = true;
-    page = this.addPage(htmlDoc, page);
+    var page = this.addPage( data.htmlDoc, data.page, true );
     AutoPager.filters.forEach(function(i) { i(page); });
-    this.requestURL = url;
+    this.requestURL = data.url;
     this.showLoading(false);
-    if (!url) {
-        debug('nextLink not found.', this.info.nextLink, htmlDoc);
+    if (!data.url) {
+        debug('nextLink not found.', this.info.nextLink, data.htmlDoc);
+        this.forceForce = true;
+        this.terminate();
+// no backwards-load support in LoadAll scenarios. yet, at least.
+/*
+    } else { // for loading all
+        if(this.shouldLoadAll)
+            this.request();
+        else {
+            this.onScroll();
+        }
+*/
+    }
+    var ev = document.createEvent('Event');
+    ev.initEvent('GM_AutoPagerizeNextPageLoaded', true, false);
+    document.dispatchEvent(ev);
+};
+AutoPager.prototype.requestLoad = function(res) {
+    var data = this.parseRequestLoad_( res );
+    if( !data )
+        return;
+
+    if( data.finalUrl )
+        this.requestURL = data.finalURL;
+
+    if ( !data.page || data.page.length < 1 ) {
+        debug('pageElement not found.' , this.info.pageElement);
+        this.terminate();
+        return;
+    }
+
+    if (this.loadedURLs[this.requestURL]) {
+        debug('page is already loaded.', this.requestURL, this.info.nextLink);
+        this.terminate();
+        return;
+    }
+
+    this.loadedURLs[this.requestURL] = true;
+    var page = this.addPage( data.htmlDoc, data.page );
+    AutoPager.filters.forEach(function(i) { i(page); });
+    this.requestURL = data.url;
+    this.showLoading(false);
+    if (!data.url) {
+        debug('nextLink not found.', this.info.nextLink, data.htmlDoc);
         this.forceForce = true;
         this.terminate();
     } else { // for loading all
     var ev = document.createEvent('Event');
     ev.initEvent('GM_AutoPagerizeNextPageLoaded', true, false);
     document.dispatchEvent(ev);
-}
+};
 
-AutoPager.prototype.addPage = function( htmlDoc, page ) {
+AutoPager.prototype.addPage = function( htmlDoc, page, before ) {
+    before = before || false;
     var totalPages = this.getPageCount( htmlDoc );
     this.updatePageNum( this.pageNum + 1, totalPages );
     
     return top ? (top + height) : null;
 }
 
-function getScrollHeight() {
-    return Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
+function getScrollHeight( doc ) {
+    doc = doc || document;
+    return Math.max( doc.documentElement.scrollHeight, doc.body.scrollHeight );
 }
 
 function isSameDomain(url) {
     var tbrTop = getElementPosition(ap.toBeRemoved[0]).top;
     var tbrBottom = getElementBottom(ap.toBeRemoved[ap.toBeRemoved.length-1]);
     var wsy = window.scrollY;
-    var scrollHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
+    var scrollHeight = getScrollHeight( document );
 
     //document.title = wsy.toString() + " | " + tbrTop.toString() + ' | ' + tbrBottom.toString() + ' | ' + scrollHeight.toString() + ' | ';
 
     if(tbrBottom+ap.remainHeight<wsy || force) {
         window.scrollTo(0, wsy-(tbrBottom-tbrTop));
+        
         for(var cnt=0; cnt<ap.toBeRemoved.length; cnt++) {
             if(ap.toBeRemoved[cnt].parentNode) {
                 // remove the page # and the hr if they are enabled