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 @@ + + + + Page 1 + Created with Sketch. + + + + + + + + + + + + + + + + + + + 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

+
+ + + Help + + +
+ + Fork me on GitHub 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; +}