From 00ed6294432374e311247abffa43d15dab60e63b Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Fri, 23 Apr 2010 10:44:46 -0400 Subject: [PATCH] Ignoring fix urls path for now. --- apps/rss_feeds/importer.py | 30 +++- media/js/jquery.iscroll.js | 355 +++++++++++++++++++++++++++++++++++++ 2 files changed, 383 insertions(+), 2 deletions(-) create mode 100644 media/js/jquery.iscroll.js diff --git a/apps/rss_feeds/importer.py b/apps/rss_feeds/importer.py index c5462b1f0..a96c5e695 100644 --- a/apps/rss_feeds/importer.py +++ b/apps/rss_feeds/importer.py @@ -1,6 +1,7 @@ import urllib2 import logging import re +import urlparse import multiprocessing class PageImporter(object): @@ -26,14 +27,39 @@ class PageImporter(object): self.save_page(html) def rewrite_page(self, response): + BASE_RE = re.compile(r')', re.I) base_code = u'' % (self.feed.feed_link,) try: - html = re.sub(r')', r')', r' tags. You know, like + # Google Analytics. Ugh. + + FIND_RE = re.compile(r'\b(href|src)\s*=\s*("[^"]*"|\'[^\']*\'|[^"\'<>=\s]+)') + ret = [] + last_end = 0 + + for match in FIND_RE.finditer(document): + url = match.group(2) + if url[0] in "\"'": + url = url.strip(url[0]) + parsed = urlparse.urlparse(url) + if parsed.scheme == parsed.netloc == '': #relative to domain + url = urlparse.urljoin(self.feed.feed_link, url) + ret.append(document[last_end:match.start(2)]) + ret.append('"%s"' % (url,)) + last_end = match.end(2) + ret.append(document[last_end:]) + + return ''.join(ret) def save_page(self, html): self.feed.page_data = html diff --git a/media/js/jquery.iscroll.js b/media/js/jquery.iscroll.js new file mode 100644 index 000000000..2fac0f814 --- /dev/null +++ b/media/js/jquery.iscroll.js @@ -0,0 +1,355 @@ +/** + * + * Find more about the scrolling function at + * http://cubiq.org/scrolling-div-for-mobile-webkit-turns-3/16 + * + * Copyright (c) 2009 Matteo Spinelli, http://cubiq.org/ + * Released under MIT license + * http://cubiq.org/dropbox/mit-license.txt + * + * Version 3.0beta4 - Last updated: 2010.04.02 + * + */ + +function iScroll (el, options) { + this.element = typeof el == 'object' ? el : document.getElementById(el); + this.wrapper = this.element.parentNode; + + this.wrapper.style.overflow = 'hidden'; + this.wrapper.style.position = 'relative'; + this.element.style.webkitTransitionProperty = '-webkit-transform'; + this.element.style.webkitTransitionTimingFunction = 'cubic-bezier(0,0,0.25,1)'; + this.element.style.webkitTransitionDuration = '0'; + this.element.style.webkitTransform = 'translate3d(0,0,0)'; + + // Get options + this.options = { + bounce: true, + hScrollBar: true, + vScrollBar: true + }; + + if (typeof options == 'object') { + for (var i in options) { + this.options[i] = options[i]; + } + } + + this.refresh(); + + this.element.addEventListener('touchstart', this, false); + this.element.addEventListener('touchmove', this, false); + this.element.addEventListener('touchend', this, false); + window.addEventListener('orientationchange', this, false); +} + +iScroll.prototype = { + _x: 0, + _y: 0, + + handleEvent: function (e) { + switch (e.type) { + case 'touchstart': this.onTouchStart(e); break; + case 'touchmove': this.onTouchMove(e); break; + case 'touchend': this.onTouchEnd(e); break; + case 'webkitTransitionEnd': this.onTransitionEnd(e); break; + case 'orientationchange': this.refresh(); this.scrollTo(0,0,'0'); break; + } + }, + + refresh: function () { + this.element.style.webkitTransitionDuration = '0'; + this.scrollWidth = this.wrapper.clientWidth; + this.scrollHeight = this.wrapper.clientHeight; + this.maxScrollX = this.scrollWidth - this.element.offsetWidth; + this.maxScrollY = this.scrollHeight - this.element.offsetHeight; + this.scrollX = this.element.offsetWidth > this.scrollWidth ? true : false; + this.scrollY = this.element.offsetHeight > this.scrollHeight ? true : false; + + // Update horizontal scrollbar + if (this.options.hScrollBar && this.scrollX) { + this.scrollBarX = new scrollbar('horizontal', this.wrapper); + this.scrollBarX.init(this.scrollWidth, this.element.offsetWidth); + } else if (this.scrollBarX) { + this.scrollBarX = this.scrollBarX.remove(); + } + + // Update vertical scrollbar + if (this.options.vScrollBar && this.scrollY) { + this.scrollBarY = new scrollbar('vertical', this.wrapper); + this.scrollBarY.init(this.scrollHeight, this.element.offsetHeight); + } else if (this.scrollBarY) { + this.scrollBarY = this.scrollBarY.remove(); + } + }, + + get x() { + return this._x; + }, + + get y() { + return this._y; + }, + + setPosition: function (x, y) { + this._x = x !== null ? x : this._x; + this._y = y !== null ? y : this._y; + + this.element.style.webkitTransform = 'translate3d(' + this._x + 'px,' + this._y + 'px,0)'; + + // Move the scrollbars + if (this.scrollBarX) { + this.scrollBarX.setPosition(this.scrollBarX.maxScroll / this.maxScrollX * this._x); + } + if (this.scrollBarY) { + this.scrollBarY.setPosition(this.scrollBarY.maxScroll / this.maxScrollY * this._y); + } + }, + + onTouchStart: function(e) { + if (e.targetTouches.length != 1) { + return false; + } + + e.preventDefault(); + e.stopPropagation(); + + this.element.style.webkitTransitionDuration = '0'; + + if (this.scrollBarX) { + this.scrollBarX.bar.style.webkitTransitionDuration = '0, 250ms'; + } + if (this.scrollBarY) { + this.scrollBarY.bar.style.webkitTransitionDuration = '0, 250ms'; + } + + // Check if elem is really where it should be + var theTransform = new WebKitCSSMatrix(window.getComputedStyle(this.element).webkitTransform); + if (theTransform.m41 != this.x || theTransform.m42 != this.y) { + this.setPosition(theTransform.m41, theTransform.m42); + } + + this.touchStartX = e.touches[0].pageX; + this.scrollStartX = this.x; + + this.touchStartY = e.touches[0].pageY; + this.scrollStartY = this.y; + + this.scrollStartTime = e.timeStamp; + this.moved = false; + }, + + onTouchMove: function(e) { + if (e.targetTouches.length != 1) { + return false; + } + + var leftDelta = this.scrollX === true ? e.touches[0].pageX - this.touchStartX : 0; + var topDelta = this.scrollY === true ? e.touches[0].pageY - this.touchStartY : 0; + + if (this.x > 0 || this.x < this.maxScrollX) { + leftDelta = Math.round(leftDelta / 4); // Slow down if outside of the boundaries + } + + if (this.y > 0 || this.y < this.maxScrollY) { + topDelta = Math.round(topDelta / 4); // Slow down if outside of the boundaries + } + + if (this.scrollBarX && !this.scrollBarX.visible) { + this.scrollBarX.show(); + } + if (this.scrollBarY && !this.scrollBarY.visible) { + this.scrollBarY.show(); + } + + this.setPosition(this.x + leftDelta, this.y + topDelta); + + this.touchStartX = e.touches[0].pageX; + this.touchStartY = e.touches[0].pageY; + this.moved = true; + + // Prevent slingshot effect + if( e.timeStamp-this.scrollStartTime > 250 ) { + this.scrollStartX = this.x; + this.scrollStartY = this.y; + this.scrollStartTime = e.timeStamp; + } + }, + + onTouchEnd: function(e) { + if (e.targetTouches.length > 0) { + return false; + } + + if (!this.moved) { + var theEvent = document.createEvent('MouseEvents'); + theEvent.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null); + e.changedTouches[0].target.dispatchEvent(theEvent); + return false; + } + + var time = e.timeStamp - this.scrollStartTime; + + var momentumX = this.scrollX === true + ? this.momentum(this.x - this.scrollStartX, + time, + -this.x + 50, + this.x + this.element.offsetWidth - this.scrollWidth + 50) + : { dist: 0, time: 0 }; + + var momentumY = this.scrollY === true + ? this.momentum(this.y - this.scrollStartY, + time, + -this.y + /*this.scrollHeight/3*/ 50, + this.y + this.element.offsetHeight - this.scrollHeight + /*this.scrollHeight/3*/ 50) + : { dist: 0, time: 0 }; + + if (!momentumX.dist && !momentumY.dist) { + this.onTransitionEnd(); // I know, I know... This is lame + return false; + } + + var newDuration = Math.max(momentumX.time, momentumY.time); + var newPositionX = this.x + momentumX.dist; + var newPositionY = this.y + momentumY.dist; + + this.element.addEventListener('webkitTransitionEnd', this); + + this.scrollTo(newPositionX, newPositionY, newDuration + 'ms'); + + // Move the scrollbars + if (this.scrollBarX) { + this.scrollBarX.scrollTo(this.scrollBarX.maxScroll / this.maxScrollX * newPositionX, newDuration + 'ms'); + } + if (this.scrollBarY) { + this.scrollBarY.scrollTo(this.scrollBarY.maxScroll / this.maxScrollY * newPositionY, newDuration + 'ms'); + } + }, + + onTransitionEnd: function () { + this.element.removeEventListener('webkitTransitionEnd', this); + this.resetPosition(); + + // Hide the scrollbars + if (this.scrollBarX) { + this.scrollBarX.hide(); + } + if (this.scrollBarY) { + this.scrollBarY.hide(); + } + }, + + resetPosition: function () { + var resetX = resetY = null; + if (this.x > 0 || this.x < this.maxScrollX) { + resetX = this.x >= 0 ? 0 : this.maxScrollX; + } + + if (this.y > 0 || this.y < this.maxScrollY) { + resetY = this.y >= 0 ? 0 : this.maxScrollY; + } + + if (resetX !== null || resetY !== null) { + this.scrollTo(resetX, resetY, '500ms'); + + if (this.scrollBarX) { + this.scrollBarX.scrollTo(this.scrollBarX.maxScroll / this.maxScrollX * (resetX || this.x), '500ms'); + } + if (this.scrollBarY) { + this.scrollBarY.scrollTo(this.scrollBarY.maxScroll / this.maxScrollY * (resetY || this.y), '500ms'); + } + } + }, + + scrollTo: function (destX, destY, runtime) { + this.element.style.webkitTransitionDuration = runtime || '400ms'; + this.setPosition(destX, destY); + }, + + momentum: function (dist, time, maxDist1, maxDist2) { + friction = 0.1; + deceleration = 1.5; + + var speed = Math.abs(dist) / time * 1000; + var newDist = speed * speed / (20 * friction) / 1000; + + // Proportinally reduce speed if we are outside of the boundaries + if (dist > 0 && maxDist1 !== undefined && newDist > maxDist1) { + speed = speed * maxDist1 / newDist; + newDist = maxDist1; + } + if (dist < 0 && maxDist2 !== undefined && newDist > maxDist2) { + speed = speed * maxDist2 / newDist; + newDist = maxDist2; + } + + newDist = newDist * (dist < 0 ? -1 : 1); + + var newTime = -speed / -deceleration; + if (newTime < 1) { // We can't go back in time + newTime = 1; + } + + return { dist: Math.round(newDist), time: Math.round(newTime) }; + } +}; + +var scrollbar = function (dir, wrapper) { + this.dir = dir; + this.bar = document.createElement('div'); + this.bar.className = 'scrollbar ' + dir; + this.bar.style.webkitTransitionTimingFunction = 'cubic-bezier(0,0,0.25,1)'; + this.bar.style.webkitTransform = 'translate3d(0,0,0)'; + this.bar.style.webkitTransitionProperty = '-webkit-transform,opacity'; + this.bar.style.webkitTransitionDuration = '0,250ms'; + this.bar.style.pointerEvents = 'none'; + this.bar.style.opacity = '0'; + + wrapper.appendChild(this.bar); +} + +scrollbar.prototype = { + size: 0, + maxSize: 0, + maxScroll: 0, + visible: false, + + init: function (scroll, size) { + var offset = this.dir == 'horizontal' ? this.bar.offsetWidth - this.bar.clientWidth : this.bar.offsetHeight - this.bar.clientHeight; + this.maxSize = scroll - 8; // 8 = distance from top + distance from bottom + this.size = Math.round(this.maxSize * this.maxSize / size) + offset; + this.maxScroll = this.maxSize - this.size; + this.bar.style[this.dir == 'horizontal' ? 'width' : 'height'] = (this.size - offset) + 'px'; + }, + + setPosition: function (pos) { + if (pos < 0) { + pos = 0; + } else if (pos > this.maxScroll) { + pos = this.maxScroll; + } + + pos = this.dir == 'horizontal' ? 'translate3d(' + Math.round(pos) + 'px,0,0)' : 'translate3d(0,' + Math.round(pos) + 'px,0)'; + this.bar.style.webkitTransform = pos; + }, + + scrollTo: function (pos, runtime) { + this.bar.style.webkitTransitionDuration = (runtime || '400ms') + ',250ms'; + this.setPosition(pos); + }, + + show: function () { + this.visible = true; + this.bar.style.opacity = '1'; + }, + + hide: function () { + this.visible = false; + this.bar.style.opacity = '0'; + }, + + remove: function () { + this.bar.parentNode.removeChild(this.bar); + return null; + } +}; \ No newline at end of file