diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..1aec5af --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,12 @@ +# Contributing to OpenSpritz + +Please develop from the _dev_ branch, not the master branch! + +Please check for existing tickets before you open a new one. Please don't submit pull requests before opening a ticket +and discussing. + +Because of the way that OpenSpritz is deployed, all pull requests must be sent to the _dev_ branch rather than the +_master_ branch. Please also test your changes on a variety of sites, including CNN, the New York Times and The +Guardian. + +Also please add yourself to the Contributors list in the README, if you're so inclined! diff --git a/README.md b/README.md index 397bd44..613ad78 100644 --- a/README.md +++ b/README.md @@ -42,19 +42,33 @@ Please be sure to submit your pull requests to the _dev_ branch, rather than _ma version depends on accessing the raw resources from Github master, all changes must be reviewed for functionality and security testing before they can be merged directly. Thank you! +### Changelog + +* 1.1 + * Remove jQuery + * Replace Readability with Diffbot + * Add Play/Pause button + +* 1.0 + * Public release! + ### Contributors * [Rich Jones](https://github.com/Miserlou) * [Nick R](https://github.com/niroyb) +* [Eli White](https://github.com/TheSavior) +* [Tim B](https://github.com/Barbarrosa) ## Sister Projects -* [OpenSpritz-Android](https://github.com/OnlyInAmerica/OpenSpritz-Android) - An Android Spritz ePub Reader by [@OnlyInAmerica](https://github.com/OnlyInAmerica) +* [OpenSpritz-Android](https://github.com/OnlyInAmerica/OpenSpritz-Android) - An Android Spritz ePub Reader by [@OnlyInAmerica](https://github.com/OnlyInAmerica). Also works with Google Glass! * [SpritzerTextView](https://github.com/andrewgiang/SpritzerTextView) - An Android Spritz View by [@andrewgiang](https://github.com/andrewgiang) * [speedread](https://github.com/pasky/speedread) - A terminal Spritzer. by [@pasky](https://github.com/pasky) * [jetzt](https://github.com/ds300/jetzt) - jetzt, a Spritz Chrome extension by [@ds300](https://github.com/ds300) * [spread0r](https://github.com/xypiie/spread0r) (previously _gritz_) - A Spritz implementation in Perl by [@xypiee](https://github.com/xypiie/) * [Spray](https://github.com/chaimpeck/spray) - A Spritzifying website built with OpenSpritz, PHP and Bootstrap. By [@chaimpeck](https://github.com/chaimpeck/) +* [Speed-ReaderFF](https://github.com/jbmartinez/speed-readerff) - A Firefox exension of OpenSpritz. By [@jbmartinez](https://github.com/jbmartinez/) +* [spritz-it!](https://github.com/the-happy-hippo/spritz-it) - A Spritzer designed for mobile browsers. By [@the-happy-hippo](https://github.com/the-happy-hippo/) #### A Note About the Name diff --git a/index.css b/index.css index bafc98b..bc352f8 100644 --- a/index.css +++ b/index.css @@ -32,7 +32,9 @@ font-style:normal; height:38px; line-height:38px; - width:125px; + width: auto; + padding-left: 6px; + padding-right: 6px; text-decoration:none; text-align:center; } diff --git a/index.html b/index.html index 9e2cc24..3085235 100644 --- a/index.html +++ b/index.html @@ -28,6 +28,18 @@

George Orwell, 12 January 1946

+
+ + OpenSpritz this! (Remote Dev) + +
+ +
+ + OpenSpritz this! (Local) + +
+

diff --git a/spritz.html b/spritz.html index 5d616c5..4d136ec 100644 --- a/spritz.html +++ b/spritz.html @@ -35,9 +35,11 @@ + + - OpenSpritz + OpenSpritz 1.1 [x] @@ -48,18 +50,3 @@
- - diff --git a/spritz.js b/spritz.js index 1072bad..169e58e 100644 --- a/spritz.js +++ b/spritz.js @@ -5,64 +5,64 @@ // Please don't abuse this. var readability_token = '172b057cd7cfccf27b60a36f16b1acde12783893'; +var diffbot_token = '2efef432c72b5a923408e04353c39a7c'; -// Create the view from the remote resource. function create_spritz(){ spritz_loader = function() { - - $.get("https://rawgithub.com/Miserlou/OpenSpritz/master/spritz.html", function(data){ - - if (!($("#spritz_container").length) ) { - $("body").prepend(data); - } - - // I suppose it's better to add that to spritz.html - $('#spritz_selector') - .after('') - .after(''); - },'html'); + //getURL("https://rawgithub.com/Miserlou/OpenSpritz/master/spritz.html", function(data){ + + //getURL("https://rawgithub.com/Miserlou/OpenSpritz/dev/spritz.html", function(data){ + + // This won't work in Firefox because an old bug and won't work in Chrome because of security stuff: + //getURL("spritz.html", function(data){ + + //getURL("https://rawgithub.com/Miserlou/OpenSpritz/dev/spritz.html", function(data){ + getURL("https://rawgithub.com/Miserlou/OpenSpritz/master/spritz.html", function(data){ + var spritzContainer = document.getElementById("spritz_container"); + + if (!spritzContainer) { + var ele = document.createElement("div"); + data = data.replace(/(\r\n|\n|\r)/gm,""); + ele.innerHTML = data; + document.body.insertBefore(ele, document.body.firstChild); + document.getElementById("spritz_toggle").style.display = "none"; + }; + + document.getElementById("spritz_selector").addEventListener("change", function(e) { + clearTimeouts(); + spritz(); + }); + }); }; - load_jq(spritz_loader); + spritz_loader(); } -// jQuery loader: http://coding.smashingmagazine.com/2010/05/23/make-your-own-bookmarklets-with-jquery/ -// This is pretty fucked and should be replaced. Is there anyway we can just force -// the latest jQ? I wouldn't have a problem with that. -function load_jq(spritz_loader){ - - // the minimum version of jQuery we want - var v = "1.7.0"; - - // check prior inclusion and version - if (window.jQuery === undefined || window.jQuery.fn.jquery < v) { - var done = false; - var script = document.createElement("script"); - script.src = "https://ajax.googleapis.com/ajax/libs/jquery/" + v + "/jquery.min.js"; - script.onload = script.onreadystatechange = function(){ - if (!done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) { - done = true; - spritz_loader(); +function getURL(url, callback) { + var xmlhttp = new XMLHttpRequest(); + + xmlhttp.onreadystatechange = function() { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { + callback(xmlhttp.responseText); } - }; - document.getElementsByTagName("head")[0].appendChild(script); - } else{ - spritz_loader(); } + + xmlhttp.open("GET", url, true); + xmlhttp.send(); } function hide_spritz(){ - $('#spritz_spacer').slideUp(); - $('#spritz_container').slideUp(); - $('#spritz_holder').slideUp(); + document.getElementById("spritz_spacer").style.display = "none"; + document.getElementById("spritz_container").style.display = "none"; + document.getElementById("spritz_holder").style.display = "none"; } // Entry point to the beef. // Gets the WPM and the selected text, if any. function spritz(){ - var wpm = parseInt($("#spritz_selector").val(), 10); + var wpm = parseInt(document.getElementById("spritz_selector").value, 10); if(wpm < 1){ return; } @@ -79,16 +79,26 @@ function spritz(){ // The meat! function spritzify(input){ - var wpm = parseInt($("#spritz_selector").val(), 10); + var wpm = parseInt(document.getElementById("spritz_selector").value, 10); var ms_per_word = 60000/wpm; // Split on any spaces. var all_words = input.split(/\s+/); + // The reader won't stop if the selection starts or ends with spaces + if (all_words[0] == "") + { + all_words = all_words.slice(1, all_words.length); + } + + if (all_words[all_words.length - 1] == "") + { + all_words = all_words.slice(0, all_words.length - 1); + } + var word = ''; var result = ''; - // Preprocess words var temp_words = all_words.slice(0); // copy Array var t = 0; @@ -109,9 +119,9 @@ function spritzify(input){ // Add an additional space after punctuation. if(all_words[i].indexOf('.') != -1 || all_words[i].indexOf('!') != -1 || all_words[i].indexOf('?') != -1 || all_words[i].indexOf(':') != -1 || all_words[i].indexOf(';') != -1|| all_words[i].indexOf(')') != -1){ - temp_words.splice(t+1, 0, "."); - temp_words.splice(t+1, 0, "."); - temp_words.splice(t+1, 0, "."); + temp_words.splice(t+1, 0, " "); + temp_words.splice(t+1, 0, " "); + temp_words.splice(t+1, 0, " "); t++; t++; t++; @@ -124,10 +134,10 @@ function spritzify(input){ all_words = temp_words.slice(0); var currentWord = 0; - var running = false; + var running = true; var spritz_timers = new Array(); - $('#spritz_toggle').click(function() { + document.getElementById("spritz_toggle").addEventListener("click", function() { if(running) { stopSpritz(); } else { @@ -135,22 +145,20 @@ function spritzify(input){ } }); - $('#spritz_slider').change(function() { - updateValues($('#spritz_slider').val() - 1); - }); - function updateValues(i) { - $('#spritz_slider').val(i); + var p = pivot(all_words[i]); - $('#spritz_result').html(p); + document.getElementById("spritz_result").innerHTML = p; currentWord = i; + } function startSpritz() { - $('#spritz_toggle').html('Stop'); + + document.getElementById("spritz_toggle").style.display = "block"; + document.getElementById("spritz_toggle").textContent = "Pause"; + running = true; - // Set slider max value - $('#spritz_slider').attr("max", all_words.length); spritz_timers.push(setInterval(function() { updateValues(currentWord); @@ -166,65 +174,57 @@ function spritzify(input){ for(var i = 0; i < spritz_timers.length; i++) { clearTimeout(spritz_timers[i]); } - $('#spritz_toggle').html('Play'); + + document.getElementById("spritz_toggle").textContent = "Play"; running = false; } + + startSpritz(); } // Find the red-character of the current word. function pivot(word){ var length = word.length; - // Longer words are "right-weighted" for easier readability. - if(length<6){ - - var bit = 1; - while(word.length < 22){ - if(bit > 0){ - word = word + '.'; - } - else{ - word = '.' + word; - } - bit = bit * -1; - } - - var start = ''; - var end = ''; - if((length % 2) === 0){ - start = word.slice(0, word.length/2); - end = word.slice(word.length/2, word.length); - } else{ - start = word.slice(0, word.length/2); - end = word.slice(word.length/2, word.length); - } - - var result; - result = "" + start.slice(0, start.length -1); - result = result + ""; - result = result + start.slice(start.length-1, start.length); - result = result + ""; - result = result + end; - result = result + ""; - } - - else{ - - var tail = 22 - (word.length + 7); - word = '.......' + word + ('.'.repeat(tail)); + var bestLetter = 1; + switch (length) { + case 1: + bestLetter = 1; // first + break; + case 2: + case 3: + case 4: + case 5: + bestLetter = 2; // second + break; + case 6: + case 7: + case 8: + case 9: + bestLetter = 3; // third + break; + case 10: + case 11: + case 12: + case 13: + bestLetter = 4; // fourth + break; + default: + bestLetter = 5; // fifth + }; - var start = word.slice(0, word.length/2); - var end = word.slice(word.length/2, word.length); + word = decodeEntities(word); + var start = '.'.repeat((11-bestLetter)) + word.slice(0, bestLetter-1).replace('.', '•'); + var middle = word.slice(bestLetter-1,bestLetter).replace('.', '•'); + var end = word.slice(bestLetter, length).replace('.', '•') + '.'.repeat(Math.max(0,11-(word.length-bestLetter))); - var result; - result = "" + start.slice(0, start.length -1); - result = result + ""; - result = result + start.slice(start.length-1, start.length); - result = result + ""; - result = result + end; - result = result + ""; - - } + var result; + result = "" + start; + result = result + ""; + result = result + middle; + result = result + ""; + result = result + end; + result = result + ""; result = result.replace(/\./g, ""); @@ -261,34 +261,37 @@ function getSelectionText() { function spritzifyURL(){ var url = document.URL; - $.getJSON("https://www.readability.com/api/content/v1/parser?url="+ encodeURIComponent(url) +"&token=" + readability_token +"&callback=?", - function (data) { + //getURL("https://www.readability.com/api/content/v1/parser?url="+ encodeURIComponent(url) +"&token=" + readability_token +"&callback=?", + getURL("https://api.diffbot.com/v2/article?url="+ encodeURIComponent(url) +"&token=" + diffbot_token, // +"&callback=?", + function(data) { - if(data.error){ - $('#spritz_result').html("Article extraction failed. Try selecting text instead."); - return; - } + data = JSON.parse(data); - var title = ''; - if(data.title !== ""){ - title = data.title + ". "; - } + if(data.error){ + document.getElementById("spritz_result").innerText = "Article extraction failed. Try selecting text instead."; + return; + } - var author = ''; - if(data.author !== null){ - author = "By " + data.author + ". "; - } + var title = ''; + if(data.title !== ""){ + title = data.title + ". "; + } - var body = jQuery(data.content).text(); // Textify HTML content. - body = $.trim(body); // Trim trailing and leading whitespace. - body = body.replace(/\s+/g, ' '); // Shrink long whitespaces. + var author = ''; + if(data.author !== undefined){ + author = "By " + data.author + ". "; + } - var text_content = title + author + body; - text_content = text_content.replace(/\./g, '. '); // Make sure punctuation is apprpriately spaced. - text_content = text_content.replace(/\?/g, '? '); - text_content = text_content.replace(/\!/g, '! '); - spritzify(text_content); - }); + var body = data.text; + body = body.trim(); // Trim trailing and leading whitespace. + body = body.replace(/\s+/g, ' '); // Shrink long whitespaces. + + var text_content = title + author + body; + text_content = text_content.replace(/\./g, '. '); // Make sure punctuation is apprpriately spaced. + text_content = text_content.replace(/\?/g, '? '); + text_content = text_content.replace(/\!/g, '! '); + spritzify(text_content); + }); } @@ -305,9 +308,34 @@ function clearTimeouts(){ } } -// Let strings repeat themselves, -// because JavaScript isn't as awesome as Python. -String.prototype.repeat = function( num ){ - return new Array( num + 1 ).join( this ); +(function(repeatFunction){ + // String repeat function already exists, so return + if(repeatFunction) return; + + // Let strings repeat themselves, + // because JavaScript isn't as awesome as Python. + String.prototype.repeat = function( num ){ + + // Implementation based on ECMA 6 Draft + var res = '', str = this.toString(); + n |= 0; // force to Int; http://jsperf.com/repeat-string-n-times/2 + while (num > 0) { + if (num & 1) { + res += str; + } + num >>>= 1; + str += str; + } + return res; + }; +}(String.prototype.repeat)); + +function decodeEntities(s){ + var str, temp= document.createElement('p'); + temp.innerHTML= s; + str= temp.textContent || temp.innerText; + temp=null; + return str; } + diff --git a/style.css b/style.css index cb14290..dd17bad 100644 --- a/style.css +++ b/style.css @@ -78,6 +78,11 @@ body{ width: auto; } +#spritz_toggle{ + float: left; + width: auto; +} + .invisible{ font-family: 'Droid Sans Mono', sans-serif; color: #ffffff;