diff --git a/app/images/mercury-help.png b/app/images/mercury-help.png
new file mode 100644
index 0000000..f86dc74
Binary files /dev/null and b/app/images/mercury-help.png differ
diff --git a/app/images/postlight-labs-logo.svg b/app/images/postlight-labs-logo.svg
new file mode 100644
index 0000000..29dbd1b
--- /dev/null
+++ b/app/images/postlight-labs-logo.svg
@@ -0,0 +1,24 @@
+
+
diff --git a/app/manifest.json b/app/manifest.json
index b132046..22cdbc2 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,6 +1,6 @@
{
"name": "__MSG_appName__",
- "version": "0.8.1",
+ "version": "0.9.0",
"manifest_version": 2,
"description": "__MSG_appDescription__",
"icons": {
@@ -47,8 +47,9 @@
"declarativeContent",
"activeTab",
"storage",
- "http://boilerpipe-web.appspot.com/*",
- "https://www.readability.com/api/*"
+ "https://boilerpipe-web.appspot.com/*",
+ "https://www.readability.com/api/*",
+ "https://mercury.postlight.com/*"
],
"options_page": "options.html"
}
diff --git a/app/options.html b/app/options.html
index 0f024ab..8c0ab5f 100644
--- a/app/options.html
+++ b/app/options.html
@@ -29,6 +29,7 @@
FullyFeedly
@@ -39,6 +40,13 @@ FullyFeedly
+
+
+
+
+
+
+
+
Setup your Mercury API key in two easy steps:
+
1. Create a free Mercury API account
+
Visit mercury.postlight.com/web-parser/
+
and create your free account.
+
You can also login using Google.
+
2. Get your API key
+
Your personal API key is available immediately after creating or logging in to your account on the main page.
+
+
+
+
+
diff --git a/app/scripts/content.js b/app/scripts/content.js
index 41b3c5a..b1784ee 100644
--- a/app/scripts/content.js
+++ b/app/scripts/content.js
@@ -7,6 +7,7 @@
var options = {
extractionAPI: 'Boilerpipe',
readabilityAPIKey: '',
+ mercuryAPIKey: '',
enableShortcut: false
};
@@ -176,13 +177,16 @@ function onBoilerpipeArticleExtracted(data, overlay) {
// Replace the preview of the article with the full text
var articlePreviewHTML = contentElement.innerHTML;
- contentElement.innerText = articleContent;
+ contentElement.innerHTML = articleContent;
- // Put the image back at the beginning of the article
- if (articleImage !== null) {
- contentElement.insertBefore(articleImage, contentElement.firstChild);
- }
+ // Clear image styles to fix formatting of images with class/style/width information in article markup
+ Array.prototype.slice.call(contentElement.querySelectorAll('img')).forEach(function(el) {
+ el.removeAttribute('class');
+ el.removeAttribute('width');
+ el.setAttribute('style', 'max-width:100%;');
+ });
+ // Toggle Success Overlay
addUndoButton(articlePreviewHTML);
successOverlay('done', overlay);
}
@@ -205,11 +209,11 @@ function boilerpipeRequest(xhr, overlay) {
};
}
-/* ===================== Readability ===================== */
+/* ===================== Readability/Mercury ===================== */
/**
* Process the content of the article and add it to the page
*/
-function onReadabilityArticleExtracted(data, overlay) {
+function onMercuryReadabilityArticleExtracted(data, overlay) {
// Check if the API failed to extract the text
if (data.content === null) {
@@ -238,6 +242,15 @@ function onReadabilityArticleExtracted(data, overlay) {
// Replace the preview of the article with the full text
var articlePreviewHTML = contentElement.innerHTML;
contentElement.innerHTML = articleContent;
+
+ // Clear image styles to fix formatting of images with class/style/width information in article markup
+ Array.prototype.slice.call(contentElement.querySelectorAll('img')).forEach(function(el) {
+ el.removeAttribute('class');
+ el.removeAttribute('width');
+ el.setAttribute('style', 'max-width:100%;');
+ });
+
+ // Toggle success overlay
successOverlay('done', overlay);
// Put the image back at the beginning of the article
@@ -248,19 +261,20 @@ function onReadabilityArticleExtracted(data, overlay) {
addUndoButton(articlePreviewHTML);
}
+/* ===================== Readability ===================== */
function readabilityRequest(xhr, overlay) {
return function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// Operation succeded
var data = JSON.parse(xhr.responseText);
- onReadabilityArticleExtracted(data, overlay);
+ onMercuryReadabilityArticleExtracted(data, overlay);
} else if (xhr.status === 400) {
console.log('[FullyFeedly] Readability API Bad request: ' +
'The server could not understand your request. ' +
'Verify that request parameters (and content, if any) are valid.');
failOverlay('APIBadRequest', overlay);
- } else if (xhr.status === 400) {
+ } else if (xhr.status === 403) {
console.log('[FullyFeedly] Readability API Authorization Required: ' +
'Authentication failed or was not provided.');
failOverlay('APIAuthorizationRequired', overlay);
@@ -272,6 +286,30 @@ function readabilityRequest(xhr, overlay) {
};
}
+/* ===================== Mercury ===================== */
+function mercuryRequest(xhr, overlay) {
+ return function() {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200) {
+ // Operation succeded
+ var data = JSON.parse(xhr.responseText);
+ onMercuryReadabilityArticleExtracted(data, overlay);
+ } else if (xhr.status === 400) {
+ console.log('[FullyFeedly] Mercury API Bad request: ' +
+ 'The server could not understand your request. ' +
+ 'Verify that request parameters (and content, if any) are valid.');
+ failOverlay('APIBadRequest', overlay);
+ } else if (xhr.status === 403) {
+ console.log('[FullyFeedly] Mercury API Authorization Required: ' +
+ 'Authentication failed or was not provided.');
+ failOverlay('APIAuthorizationRequired', overlay);
+ } else {
+ console.log('[FullyFeedly] Mercury API Unknown error');
+ failOverlay('APIUnknownError', overlay);
+ }
+ }
+ };
+}
/**
* Performs an XMLHttpRequest to boilerpipe to get the content of the artile.
@@ -300,7 +338,7 @@ function fetchPageContent() {
// Select the API to use to extract the article
if (options.extractionAPI === 'Boilerpipe') {
// Prepare the request to Boilerpipe
- url = 'http://boilerpipe-web.appspot.com/extract?url=' +
+ url = 'https://boilerpipe-web.appspot.com/extract?url=' +
encodedPageUrl +
'&extractor=ArticleExtractor&output=json&extractImages=';
@@ -319,11 +357,24 @@ function fetchPageContent() {
xhr.onreadystatechange = readabilityRequest(xhr, overlay);
}
+ else if (options.extractionAPI === 'Mercury') {
+ if (options.mercuryAPIKey === '') {
+ failOverlay('APIMissingKey', overlay);
+ return;
+ }
+
+ url = 'https://mercury.postlight.com/parser?url='+ encodedPageUrl;
+
+ xhr.onreadystatechange = mercuryRequest(xhr, overlay);
+ }
else {
failOverlay('InvalidAPI', overlay);
return;
}
xhr.open('GET', url, true);
+ if (options.extractionAPI === 'Mercury' && options.mercuryAPIKey !== '') {
+ xhr.setRequestHeader('x-api-key', options.mercuryAPIKey);
+ }
xhr.send();
}
diff --git a/app/scripts/options.js b/app/scripts/options.js
index 562375a..4ed629a 100644
--- a/app/scripts/options.js
+++ b/app/scripts/options.js
@@ -12,6 +12,13 @@ function updateForm() {
else {
$('#readabilityKeyForm').hide();
}
+
+ if (extractionAPI === 'Mercury') {
+ $('#mercuryKeyForm').show();
+ }
+ else {
+ $('#mercuryKeyForm').hide();
+ }
}
// Show a visual confirmation to the user
@@ -26,6 +33,7 @@ function onKeyboardShortcut() {
function saveOptions() {
var extractionAPI = $('#extractionAPI').val();
var readabilityAPIKey = $('#readabilityAPIKey').val();
+ var mercuryAPIKey = $('#mercuryAPIKey').val();
var enableShortcut = $('#enableShortcut').prop('checked');
var status = $('#status');
@@ -42,10 +50,23 @@ function saveOptions() {
return;
}
}
+ if (extractionAPI === 'Mercury') {
+ if (mercuryAPIKey === '') {
+ // Show the error message
+ status.text('Missing Mercury API key');
+ $('#mercuryKeyForm').addClass('has-error');
+ setTimeout(function() {
+ status.text('');
+ $('#mercuryKeyForm').removeClass('has-error');
+ }, 2000);
+ return;
+ }
+ }
chrome.storage.sync.set({
extractionAPI: extractionAPI,
readabilityAPIKey: readabilityAPIKey,
+ mercuryAPIKey: mercuryAPIKey,
enableShortcut: enableShortcut
}, function() {
// Update status to let user know options were saved.
@@ -62,10 +83,12 @@ function restoreOptions() {
chrome.storage.sync.get({
extractionAPI: 'Boilerpipe',
readabilityAPIKey: '',
+ mercuryAPIKey: '',
enableShortcut: false
}, function(items) {
$('#extractionAPI').val(items.extractionAPI);
$('#readabilityAPIKey').val(items.readabilityAPIKey);
+ $('#mercuryAPIKey').val(items.mercuryAPIKey);
$('#enableShortcut').prop('checked', items.enableShortcut);
updateForm();
});
diff --git a/app/styles/main.css b/app/styles/main.css
index 562fb45..7e6af99 100644
--- a/app/styles/main.css
+++ b/app/styles/main.css
@@ -3,7 +3,7 @@ body {
}
.jumbotron h1 {
- font-weight: bold;
+ font-weight: bold;
}
#tryShortcut {
@@ -13,4 +13,20 @@ body {
#icon128 {
margin: 10px 10px 0px 0px;
-}
\ No newline at end of file
+}
+
+#mercuryHelp .close {
+ color: #fff;
+}
+
+#postlightLogo {
+ position: absolute;
+ width: 46px;
+ height: 35px;
+ background: url('../images/postlight-labs-logo.svg') no-repeat 50%;
+ background-size: contain;
+}
+
+#mercuryHelpTitle {
+ padding-left: 50px;
+}