-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
177 additions
and
15 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 |
---|---|---|
|
@@ -6,3 +6,4 @@ dist | |
app/bower_components | ||
test/bower_components | ||
package | ||
*.swp |
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 |
---|---|---|
@@ -1,4 +1,19 @@ | ||
fullyfeedly | ||
FullyFeedly | ||
=========== | ||
|
||
Chrome extension to display the full content of articles in Feedly | ||
|
||
|
||
## Usage | ||
|
||
The RSS feed of some website contains only a preview of the articles. | ||
FullFeedly is a chrome extensions that allows you to read the full article without leaving Feedly.com | ||
|
||
When reading an imcomplete post, simply press the icon of FullFeedly in the URL bar to download the full text. | ||
|
||
|
||
## Developer | ||
|
||
Clone the repository and follow [this guide](http://minimul.com/developing-a-chrome-extension-with-yeoman.html) to build and debug the extension. | ||
|
||
The text of the article is extracted using the web API provided by [Boilerpipe](http://boilerpipe-web.appspot.com/). |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
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
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 |
---|---|---|
@@ -1,11 +1,45 @@ | ||
'use strict'; | ||
|
||
chrome.runtime.onInstalled.addListener(function (details) { | ||
console.log('previousVersion', details.previousVersion); | ||
console.log('FullyFeedly installed: previousVersion', details.previousVersion); | ||
}); | ||
|
||
chrome.tabs.onUpdated.addListener(function (tabId) { | ||
chrome.pageAction.show(tabId); | ||
|
||
function printResponse(response) { | ||
console.log('Content response:\n' + response); | ||
} | ||
|
||
/* Regex-pattern to check URLs against. | ||
It matches URLs like: http[s]://[...]feedly.com[...] */ | ||
var urlRegex = /^https?:\/\/(?:[^\.]+\.)?feedly\.com/; | ||
|
||
// When the browser-action button is clicked... | ||
chrome.pageAction.onClicked.addListener(function(tab) { | ||
// ...check the URL of the active tab against our pattern and... | ||
if (urlRegex.test(tab.url)) { | ||
// ...if it matches, send a message specifying a callback too | ||
chrome.tabs.sendMessage(tab.id, { text: 'extract_article' }, printResponse); | ||
} | ||
}); | ||
|
||
// When the extension is installed or upgraded ... | ||
chrome.runtime.onInstalled.addListener(function() { | ||
// Replace all rules ... | ||
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() { | ||
// With a new rule ... | ||
chrome.declarativeContent.onPageChanged.addRules([ | ||
{ | ||
// That fires when a page's URL contains a 'feedly.com' ... | ||
conditions: [ | ||
new chrome.declarativeContent.PageStateMatcher({ | ||
pageUrl: { urlContains: 'feedly.com' }, | ||
}) | ||
], | ||
// And shows the extension's page action. | ||
actions: [ new chrome.declarativeContent.ShowPageAction() ] | ||
} | ||
]); | ||
}); | ||
}); | ||
|
||
console.log('\'Allo \'Allo! Event Page for Page Action'); | ||
console.log('FullyFeedly: extension started'); |
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,97 @@ | ||
'use strict'; | ||
|
||
/** | ||
* Performs an XMLHttpRequest to boilerpipe to get the content of the artile. | ||
* | ||
* @param callback Function If the response from fetching url has a | ||
* HTTP status of 200, this function is called with a JSON decoded | ||
* response. Otherwise, this function is called with null. | ||
*/ | ||
function fetchPageContent(callback) { | ||
var xhr = new XMLHttpRequest(); | ||
xhr.onreadystatechange = function() { | ||
if (xhr.readyState === 4) { | ||
if (xhr.status === 200) { | ||
var data = JSON.parse(xhr.responseText); | ||
callback(data); | ||
} else { | ||
callback(null); | ||
} | ||
} | ||
}; | ||
|
||
// Search the link of the article that is currently opened | ||
var linkElement = document.querySelector('.websiteCallForAction'); | ||
if (linkElement === null) { | ||
console.log('There is something wrong: no link element found'); | ||
return; | ||
} | ||
|
||
// Get the link and convert it for usage as parameter in the GET request | ||
var pageUrl = linkElement.getAttribute('href'); | ||
var encodedPageUrl = encodeURIComponent(pageUrl); | ||
|
||
// Prepare the request to Boilerpipe | ||
var url = 'http://boilerpipe-web.appspot.com/extract?url=' + | ||
encodedPageUrl + | ||
'&extractor=ArticleExtractor&output=json&extractImages='; | ||
xhr.open('GET', url, true); | ||
xhr.send(); | ||
} | ||
|
||
/** | ||
* Process the content of the article and add it to the page | ||
* | ||
* @param data Object JSON decoded response. Null if the request failed. | ||
*/ | ||
function onArticleExtracted(data) { | ||
|
||
// Check if the request failed | ||
if (data === null) { | ||
console.log('Failed to load the content of the page'); | ||
return; | ||
} | ||
|
||
// Check if the API failed to extract the text | ||
if (data.status === null || data.status !== 'success') { | ||
console.log('API failed to extract the content'); | ||
return; | ||
} | ||
|
||
// Get the content of the article | ||
var articleContent = data.response.content; | ||
|
||
// Search the element of the page that will containt the text | ||
var contentElement = document.querySelector('.content'); | ||
if (contentElement === null) { | ||
console.log('There is something wrong: no content element found'); | ||
return; | ||
} | ||
|
||
// If there is an image we want to keep it | ||
var articleImage = contentElement.querySelector('img'); | ||
if (articleImage !== null) { | ||
articleImage = articleImage.cloneNode(); | ||
} | ||
|
||
// Replace the preview of the article with the full text | ||
contentElement.innerText = articleContent; | ||
|
||
// Put the image back at the beginning of the article | ||
if (articleImage !== null) { | ||
contentElement.insertBefore(articleImage, contentElement.firstChild); | ||
} | ||
|
||
} | ||
|
||
/* Listen for requests */ | ||
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) { | ||
// If the received message has the expected format... | ||
if (msg.text && (msg.text === 'extract_article')) { | ||
// Perform the specified operation | ||
fetchPageContent(onArticleExtracted); | ||
sendResponse('Got it!'); | ||
} | ||
}); | ||
|
||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.