This repository has been archived by the owner on Mar 10, 2020. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Implemented as a pageAction, with a supremely ugly "Notification" window for the "Saved!" message. - @todo: Suck it up and inject a script into every page to handle `ctrl-p` for saving, and a "Saved!" message that doesn't look stunningly bad. Look into the experimental 'infobar' API, as that might be Good Enough.
- Loading branch information
0 parents
commit d53adab
Showing
10 changed files
with
276 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
Instapaper Chrome Extension | ||
=========================== | ||
|
||
I don't use any bookmarking tools with any regularity, other than | ||
Instapaper, and I don't need an extension that does anything beyond | ||
simply sending articles into the service. This extension aims to | ||
make that as simple and streamlined as possible. | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>'Send to Instapaper' controller</title> | ||
<script src="sendtoinstapaper.js" type="text/javascript"></script> | ||
<script type="text/javascript"> | ||
window.addEventListener( 'load', SendToInstapaper.backgroundInit ); | ||
</script> | ||
</head> | ||
<body></body> | ||
</html> |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "Send to Instapaper", | ||
"version": "0.1", | ||
|
||
"description": "A simple, streamlined Instapapering tool.", | ||
"icons": { | ||
"16": "icon-16x16.png", | ||
"19": "icon-19x19.png", | ||
"48": "icon-48x48.png", | ||
"128": "icon-128x128.png" | ||
}, | ||
|
||
"page_action": { | ||
"default_icon": "icon-19x19.png", | ||
"default_title": "Send to Instapaper" | ||
}, | ||
"background_page": "background.html", | ||
"permissions": [ | ||
"tabs", | ||
"notifications", | ||
"https://www.instapaper.com/" | ||
] | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
/** | ||
* SendToInstapaper | ||
*/ | ||
var SendToInstapaper = ( function() { | ||
var URL_AUTH = "https://www.instapaper.com/api/authenticate", | ||
URL_ADD = "https://www.instapaper.com/api/add", | ||
|
||
STATUS_OK = 200, | ||
STATUS_CREATED = 201, | ||
STATUS_BADREQUEST = 400, | ||
STATUS_FORBIDDEN = 403, | ||
STATUS_ERROR = 500; | ||
|
||
function syncRequest( options ) { | ||
options.method = options.method || "GET"; | ||
options.async = false; | ||
var xhr = new XMLHttpRequest(), | ||
postData = ""; | ||
xhr.open( | ||
options.method, options.url, options.async | ||
); | ||
if ( options.username || options.password ) { | ||
xhr.setRequestHeader( "Authorization", "Basic " + btoa( options.username + ":" + options.password ) ); | ||
} | ||
if ( options.method === "POST" ) { | ||
xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' ); | ||
} | ||
console.log( "XHR: %o", options, xhr ); | ||
try { | ||
if ( options.data ) { | ||
for ( key in options.data ) { | ||
if ( options.data.hasOwnProperty( key ) ) { | ||
postData += encodeURIComponent( key ) + "=" + encodeURIComponent( options.data[ key ] ) + "&"; | ||
} | ||
} | ||
postData += "1=1"; | ||
} | ||
xhr.send( postData ); | ||
return xhr; | ||
} catch ( e ) { | ||
return { | ||
'status': 0, | ||
'exception': e | ||
}; | ||
} | ||
} | ||
|
||
function isAuthenticated( force ) { | ||
console.log( "Checking auth: %o", option( 'authenticated' ) ); | ||
if ( option( 'authenticated' ) !== STATUS_ERROR && !force ) { | ||
return option( 'authenticated' ); | ||
} | ||
|
||
option( 'authenticated', null ); | ||
if ( | ||
option( "username" ) !== undefined && | ||
option( "password" ) !== undefined | ||
) { | ||
var req = syncRequest( { | ||
'url': URL_AUTH, | ||
'username': option( "username" ), | ||
'password': option( "password" ) | ||
} ); | ||
switch ( req.status ) { | ||
case STATUS_OK: | ||
option( "authenticated", true ); | ||
break; | ||
case STATUS_FORBIDDEN: | ||
option( "authenticated", false ); | ||
break; | ||
case STATUS_ERROR: | ||
default: | ||
option( "authenticated", STATUS_ERROR ); | ||
break; | ||
} | ||
} | ||
return localStorage.authenticated; | ||
} | ||
|
||
function sendURL( tab ) { | ||
if ( isAuthenticated() ) { | ||
syncRequest( { | ||
'method': "POST", | ||
'url': URL_ADD, | ||
'username': option( "username" ), | ||
'password': option( "password" ), | ||
'data': { | ||
'url': tab.url, | ||
'title': tab.title | ||
} | ||
} ); | ||
} else { | ||
// Handle unauthenticated user here. | ||
} | ||
} | ||
|
||
function backgroundInit() { | ||
option( 'currentTab', null ); | ||
// When Chrome displays any tab, show the pageAction | ||
// icon in that tab's addressbar. | ||
chrome.tabs.onSelectionChanged.addListener( | ||
function(tabId) { | ||
option( 'currentTab', tabId ); | ||
|
||
chrome.pageAction.show( tabId ); | ||
setPopup(); | ||
} | ||
); | ||
// Display the pageAction icon for the current tab | ||
// (as it's already visible, `onSelectionChange` | ||
// won't have been called. | ||
chrome.tabs.getSelected( null, function( tab ) { | ||
option( 'currentTab', tab.id ); | ||
chrome.pageAction.show( tab.id ); | ||
setPopup(); | ||
} ); | ||
|
||
chrome.pageAction.onClicked.addListener( function ( tab ) { | ||
sendURL( tab ); | ||
webkitNotifications.createNotification( | ||
'icon.png', | ||
'Instaper', | ||
'Successfully saved "' + tab.title + '" to Instapaper.' | ||
).show(); | ||
} ); | ||
|
||
} | ||
|
||
function setPopup( ) { | ||
if ( isAuthenticated() !== true ) { | ||
console.log( "Setting popup." ); | ||
chrome.pageAction.setPopup( { | ||
'tabId': option( 'currentTab' ), | ||
'popup': 'setup.html' | ||
} ); | ||
} else { | ||
console.log( "Unsetting popup." ); | ||
chrome.pageAction.setPopup( { | ||
'tabId': option( 'currentTab' ), | ||
'popup': '' | ||
} ); | ||
} | ||
} | ||
|
||
function setupInit() { | ||
var theForm = document.getElementById( 'optionForm' ), | ||
user = document.getElementById( 'username' ), | ||
pass = document.getElementById( 'password' ), | ||
auth; | ||
|
||
user.value = option( 'username' ); | ||
pass.value = option( 'password' ); | ||
|
||
theForm.addEventListener( 'submit', function ( e ) { | ||
option( 'username', user.value ); | ||
option( 'password', pass.value ); | ||
auth = isAuthenticated( true ); | ||
if ( auth === true ) { | ||
theForm.appendChild( document.createTextNode( "Success!" ) ); | ||
} else if ( auth === false ) { | ||
theForm.appendChild( document.createTextNode( "Invalid username/password." ) ); | ||
} else if ( auth === STATUS_ERROR ) { | ||
theForm.appendChild( document.createTextNode( "Error communicating with Instapaper. Are you online?" ) ); | ||
} | ||
|
||
setPopup(); | ||
|
||
e.preventDefault(); e.stopPropagation(); | ||
return false; | ||
} ); | ||
} | ||
|
||
function option( key, value ) { | ||
if ( typeof( value ) !== "undefined" ) { | ||
localStorage[ key ] = JSON.stringify( { "value": value } ); | ||
} else { | ||
if ( typeof( localStorage[ key ] ) !== "undefined" ) { | ||
return JSON.parse( localStorage[ key ] ).value; | ||
} else { | ||
return undefined; | ||
} | ||
} | ||
} | ||
|
||
return { | ||
'backgroundInit': backgroundInit, | ||
'setupInit': setupInit, | ||
'option': option | ||
}; | ||
}() ); |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>'Send To Instapaper' Setup</title> | ||
<script src="sendtoinstapaper.js" type="text/javascript"></script> | ||
<style type="text/css"> | ||
body { | ||
margin: 0; | ||
padding: 10px; | ||
width: 250px; | ||
} | ||
h1 { | ||
font: 18px/1.2 Baskerville; | ||
font-weight: 700; | ||
margin: 0 0 10px; | ||
padding: 0; | ||
} | ||
label { | ||
display: block; | ||
margin: 10px 0; | ||
} | ||
label input { | ||
display: block; | ||
} | ||
</style> | ||
<script type="text/javascript"> | ||
window.addEventListener( 'load', SendToInstapaper.setupInit ); | ||
</script> | ||
</head> | ||
<body> | ||
<h1>'Send to Instapaper' Options</h1> | ||
<form action="#" id="optionForm"> | ||
<label> | ||
Email address or username: | ||
<input type="text" id="username" value=""> | ||
</label> | ||
<label> | ||
Password: | ||
<input type="password" id="password" value=""> | ||
</label> | ||
<input type="submit" value="Save"> | ||
</form> | ||
</body> | ||
</html> |