Created
August 19, 2009 04:28
-
-
Save canadaduane/170167 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CmdUtils.CreateCommand({ | |
names: ["eyes like lightning"], | |
arguments: [ {role: 'object', nountype: noun_arb_text, label: 'input'} ], | |
author: {name: "Duane Johnson", email: "[email protected]"}, | |
license: "GPL", | |
description: "Opens a speed-reading window above the currently selected text.", | |
help: "Select some text, and then use the eyes like lightning command to start reading it.", | |
preview: function(pblock, args) { | |
var t = args.object.text.substring(0, 20); | |
pblock.innerHTML = "Read <b>" + t + "</b>"; | |
}, | |
execute: function(args) { | |
var index = 0; | |
var text = args.object.text; | |
var words = []; | |
var window = CmdUtils.getWindowInsecure(); | |
var phash = new persistentHash('eyeslikelightning'); | |
var interval_multiplier = 50; | |
var wpm; | |
var set_wpm = function(value) { | |
wpm = parseInt(value); | |
phash.setString('wpm', value.toString()); | |
return value; | |
}; | |
// Get/Set default words-per-minute from persistent hash | |
set_wpm(parseInt(phash.getString('wpm') || 500)); | |
var make_popup = function($) { | |
CmdUtils.injectCss( | |
'#ell-popup > div { margin: 5px auto; text-align: center; } ' + | |
'.ell-s{ font-size: 35px; height: 35px; } ' + | |
'.ell-m{ font-size: 35px; height: 35px; visibility: hidden; } ' + | |
'.ell-l{ font-size: 35px; height: 35px; visibility: hidden; } ' + | |
'#ell-control td { border: 1px dotted blue; } ' + | |
// The following base64 code was create with: | |
// ruby -e 'print [IO.read(File.join(Dir.pwd, ARGV[0]))].pack("m")' center.png > center.b64 | |
'.ell-s{ background: url(data:image/png;base64,' + | |
'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAADO2lDQ1BJQ0Mg' + | |
'UHJvZmlsZQAAeAGFlEto1FAUhv+MKYK0gqi1FpTgQou0JT7QilDbabXWkXEY' + | |
'+9AiyDRzZxpNMzGZGR+ISEHc+VqKGx+IiyriQrpQcKULkULra1EEcaUiiEI3' + | |
'Usb/Ju1MKlYvJPlyzn/P64YAVQ9TjmNFNGDYzrvJrqh26PCAtngCVahBNbhS' + | |
'hue0JxL7faZWPuev6bdQpGWyScaK9R2Y+LRt9f1Lj2Lv6572+p75+nlvNS4T' + | |
'AopG64pswFslDwa8V/LJvJOn5ohkYyiVJjvkRrcn2UG+QV6aDfFgiNPCM4Cq' + | |
'NmpyhuMyTmQFuaVoZGXMUbJup02bPCXtac8Ypob9Rn7IWdDGlY8BrWuARS8r' + | |
'tgEPGL0LrFpfsTXUASv7gbEtFdvPpD8fpXbcy2zZ7IdTqqOs6UOp9HM9sPga' + | |
'MHO1VPp1q1Sauc0crOOZZRTcoq9lYcorIKg32M34yTlaiIOefFULcJNz7F8C' + | |
'xC4A1z8CGx4Ayx8DiRqgZwci59lucOXFKc4F6Mg5p10zO5TXNuv6dq2dRyu0' + | |
'bttobtRSlqX5Lk9zhSfcokg3Y9gqcM7+WsZ7tbB7D/LJ/iLnhLd7lpWRdKqT' + | |
's0Qz2/qSFp27yY3kexlzTze5gddUxt3TG7Cy0cx39wQc6bOtOM9FaiJ19mD8' + | |
'AJnxFdXJR+U8JI94xYMypm8/ltqXINfTnjyei0lNLfe2nRnq4RlJVqwzQx3x' + | |
'WX7tFpIy7zpq7jiW/82ztshzHIYFARM27zY0JNGFKJrgwEUOGXpMKkxapV/Q' + | |
'asLD8b8qLSTKuywquvCZez77e06gwN0yfh+icYw0liNo+jv9m/5Gv6nf0b9e' + | |
'qS80VDwj7lHTGL/8nXFlZlmNjBvUKOPLmoL4Bqttp9dCltZhXkFPXlnfFK4u' + | |
'Y1+pL3s0mUNcjE+HuhShTE0YZDzZtey+SLb4Jvx8c9kWmh61L84+qavkeqOO' + | |
'HZmsfnE2XA1r/7OrYNKyq/DkjZAuPGuhrlU3qd1qi7oDmrpLbVNb1U6+7VT3' + | |
'l3f0clYmTrJul9Wn2ION0/RWTroyWwT/Fn4x/C91CVu4pqHJf2jCzWVMS/iO' + | |
'4PYfd0j5L/wNAYUVDXxLOzsAAAAJcEhZcwAACxMAAAsTAQCanBgAAAGJSURB' + | |
'VDgRzZRPS8NAEMUnrRe1IiU5FIyQQimeKujH89KLX7CnIgULptCDIsVqTzb+' + | |
'ZnbzR5pGCh66MJnNzntvp5u3FTn2ETQ1mI0lkrZ05VtODdeWDfP3YCyv+3i1' + | |
'giYkMoAUE5EEcm4CmXySVSwlZnXCO4LZg1zT1Yi4kUwSiD2iQ+hYE0s2mNPp' + | |
'lJgEj/JiFf84qb5YZ1sTu0NsRG0I+Yr5peECWTFfED02PNM1OJtqp78EqQ98' + | |
'ZyOE7iH2iXJkEvISUruw9bZ8kd9YK860laP9ucUAEtaG5H5e28muphjFxp5r' + | |
'sEKQzrqsRETPfqaVGx56FO58nRM8tBRUa7iv2WFnd2YNeh7TMU5uK/ClYBP5' + | |
'gFopqKZ1Pluz6+pPDYdZG0e5fpSC3ADW9GstAS1ywN7sMEvjOK5BC0HvpZTu' + | |
'5lSeyM+GqHu4mmIUmzb5cIb7QzOt898HpDpjq9jEbktLZtU9g+qLzvFULFu5' + | |
'9QZPWDro6u0IelH14//8OahgPuwGHPj3lXOPN/8AwEKFiwLbAywAAAAASUVO' + | |
'RK5CYII=' + | |
') center 4px no-repeat; }' + | |
'</style>'); | |
$('body').append($( | |
'<div id="ell-popup" title="Eyes Like Lightning">' + | |
'<div id="ell-l1" class="ell-l"></div>' + | |
'<div id="ell-l2" class="ell-m"></div>' + | |
'<div id="ell-l3" class="ell-s"></div>' + | |
'<div id="ell-l4" class="ell-m"></div>' + | |
'<div id="ell-l5" class="ell-l" style="margin: 5px auto 20px auto;"></div>' + | |
'<div id="ell-slider" style="width: 200px"></div>' + | |
'<div id="ell-info" style="">' + | |
'<span>WPM:</span>' + | |
'<span id="ell-wpm">' + wpm + '</span>' + | |
'</div>' + | |
'</div>' | |
)); | |
var timer_handle; | |
var forward = function(new_wpm) { | |
set_wpm(new_wpm); | |
$('#ell-wpm').html(wpm); | |
var step_forward = function() { | |
$('#ell-l1').html($('#ell-l2').html()); | |
$('#ell-l2').html($('#ell-l3').html()); | |
$('#ell-l3').html($('#ell-l4').html()); | |
$('#ell-l4').html($('#ell-l5').html()); | |
var line = "", i = 0; | |
if (index < 0) index = 0; | |
if (words[index] == "~") { | |
line = "-"; | |
} else { | |
for (i = 0; i < 3; i++) { | |
if (words[index + i] == "~") break; | |
if (index + i < words.length) | |
line += words[index + i] + " "; | |
if (line.length > 0) | |
break; | |
} | |
} | |
$('#ell-l5').html(line); | |
index += i + 1; | |
if (index >= words.length) index = words.length; | |
}; | |
// Set the WPM display | |
var interval = 180000 / wpm; | |
// Reset the timer to a (possibly) new interval | |
if (timer_handle) window.clearInterval(timer_handle); | |
timer_handle = window.setInterval(step_forward, interval); | |
}; | |
var paused = true; | |
var buttonpane = function() { return $('#ell-popup ~ .ui-dialog-buttonpane'); } | |
var set_pause = function(pval) { | |
var pane = buttonpane(); | |
if (pval) { | |
pane.find('button:contains(Pause)').html('Continue'); | |
if (timer_handle) window.clearInterval(timer_handle); | |
} else { | |
pane.find('button:contains(Continue)').html('Pause'); | |
pane.find('button:contains(Start)').html('Pause'); | |
forward(wpm); | |
} | |
paused = pval; | |
}; | |
var restart = function() { | |
if (timer_handle) window.clearInterval(timer_handle); | |
$('#ell-l1').html(''); | |
$('#ell-l2').html(''); | |
$('#ell-l3').html(''); | |
$('#ell-l4').html(''); | |
$('#ell-l5').html(''); | |
index = 0; | |
set_pause(true); | |
}; | |
$("#ell-popup").dialog({ | |
resizable: false, | |
autoOpen: true, | |
height: 420, | |
width: 600, | |
modal: true, | |
draggable: true, | |
buttons: { | |
'Close': function() { | |
$('#ell-popup').dialog('close'); | |
}, | |
'Start': function() { | |
paused = !paused; | |
set_pause(paused); | |
}, | |
'Restart': restart, | |
'Preferences': function() { | |
} | |
}, | |
close: function() { | |
if (timer_handle) window.clearInterval(timer_handle); | |
index = 0; | |
set_pause(false); | |
} | |
}); | |
$('#ell-slider').slider({ | |
animate: true, | |
value: parseInt(wpm / interval_multiplier), | |
slide: function(e, ui) { | |
if (!paused) { | |
forward(ui.value * interval_multiplier); | |
} else { | |
set_wpm(ui.value * interval_multiplier); | |
$('#ell-wpm').html(wpm); | |
} | |
} | |
}); | |
} | |
CmdUtils.loadJQuery(function($) { | |
// Default to the entire document if nothing is selected | |
if (!text || text == "") { text = $('body').text(); } | |
// Double line-end characters denote new paragraph | |
words = text.replace(/\n\s*\n\s*/g, " ~ ").replace("-", "- ").split(/\s+/); | |
var css = "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css"; | |
var js = "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"; | |
if ($('#ell-popup').length == 0) { | |
$('body').append('<link rel="stylesheet" href="' + css + '" type="text/css" />'); | |
CmdUtils.injectJavascript(js, function() { | |
make_popup($); | |
}); | |
reopen_dialog = function() { $('#ell-popup').dialog('open'); }; | |
} else { | |
// For some reason, we need a closure here instead of a direct call to .dialog('open')... | |
reopen_dialog(); | |
} | |
}); | |
} | |
}); | |
/* | |
* This represents a persistent hash for Firefox. It is a hash of | |
* hashes. The root hash has keys made of owners and each hash under | |
* each owner contains the key value pairs that the owner wishes. | |
* | |
* It utilizes the Mozilla FUEL libraries in FF3. The entire hash is | |
* stored as JSON within a preference in Firefox. | |
* | |
* This was specifically deisgned to allow Ubiquity commands to save | |
* values which would persist even after the browser has been | |
* restarted. In order to use this please add this code with the | |
* Ubiquity commands that would hypothetically use it. | |
* | |
* How the data is held: | |
* Extension->Preferences->Preference->Owner->Key->Value | |
* | |
* author: Jonathan Micklos ([email protected]) | |
* | |
* param: This is the UID for an owner to store key value pairs in | |
* the hash. For an example, in Ubiquity, each command could | |
* be an owner with it's own hash of key value pairs to own. | |
* owner => key => value | |
* | |
*/ | |
function persistentHash(owner) { | |
//You will need to change this for any given extension | |
var extensionKey = "[email protected]"; | |
//We do not want to make a new preference for each key-value. | |
//In addition, we do not want to give users the ability to | |
//overwrite preferences the extension may already use. | |
var primaryKey = "persistentHash"; | |
/* | |
* Check for Sanity | |
*/ | |
function isSane(){ | |
//Check to make sure the extension key exists. | |
if(!Application.extensions.has(extensionKey)) { | |
displayMessage("ERROR: Cannot find extension " + extensionKey); | |
return false; | |
} | |
return true; | |
} | |
function getBaseHash() { | |
//Check for sanity | |
if(!isSane()) return null; | |
//See if the owner exists in the preferences | |
if(!Application.extensions.get(extensionKey).prefs.has(primaryKey)) return new Array(); | |
var res = Application.extensions.get(extensionKey).prefs.get(primaryKey).value; | |
//if the JSON is an empty string, give them a new array | |
if(res == '') return new Array(); | |
//if all is good, get the JSON | |
return eval('(' + Application.extensions.get(extensionKey).prefs.get(primaryKey).value + ')' ); | |
} | |
function getHash() { | |
var baseHash = getBaseHash(); | |
if(typeof baseHash[owner] == "undefined") return new Array(); | |
return baseHash[owner]; | |
} | |
function setHash(hash) { | |
//Check for sanity | |
if(!isSane()) return; | |
var baseHash = getBaseHash(); | |
baseHash[owner] = hash; | |
var res = "{"; | |
for (var baseKey in baseHash) { | |
var tempRes = ""; | |
hash = baseHash[baseKey]; | |
//escape double quotes | |
baseKey = baseKey.replace('"','\\"'); | |
for(var key in hash) { | |
var value = hash[key]; | |
//escape double quotes | |
key = key.replace('"','\\"'); | |
value = value.replace('"','\\"'); | |
tempRes += '"' + key + '":"' + value + '",'; | |
} | |
if(tempRes!="") { | |
res += '"' + baseKey + '":{' + tempRes + "},"; | |
} | |
} | |
res += "}"; | |
if(res == "{}") res = ""; | |
//Set the newly created JSON in the preference | |
Application.extensions.get(extensionKey).prefs.setValue(primaryKey,res); | |
} | |
/* | |
* Check to see if a key is set in the hash. | |
*/ | |
this.isSet = function (key) { | |
var hash = getHash(); | |
if(hash == null) return false; | |
return !(typeof hash[key] == "undefined"); | |
}; | |
/* | |
* Get a value from the hash | |
*/ | |
this.getString = function (key) { | |
if(!this.isSet(key)) return null; | |
return getHash()[key]; | |
}; | |
/* | |
* Set a value in the hash | |
*/ | |
this.setString = function (key, value) { | |
if(!isSane() || !(typeof key == "string") || !(typeof value == "string")) return; | |
var hash = getHash(); | |
hash[key] = value; | |
setHash(hash); | |
}; | |
/* | |
* Get a copy of the hash. | |
*/ | |
this.getHashCopy = function () { | |
return getHash(); | |
}; | |
/* | |
* Clear the hash out. | |
*/ | |
this.clearHash = function () { | |
setHash(new Array()); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment