diff --git a/src/extraction/index.js b/src/extraction/index.js
index 1391a9a..046f383 100644
--- a/src/extraction/index.js
+++ b/src/extraction/index.js
@@ -10,18 +10,42 @@
import config from 'commerce/config/content';
import extractProductWithFathom from 'commerce/extraction/fathom';
-import extractProductWithFallback from 'commerce/extraction/fallback';
+import extractProductWithFallback from 'commerce/extraction/selector';
+import extractProductWithOpenGraph from 'commerce/extraction/open_graph';
+
+/**
+ * Extraction methods are given the document object for the page, and must
+ * return either a valid ExtractedProduct, or null if a valid product could not
+ * be found.
+ */
+const EXTRACTION_METHODS = [
+ extractProductWithFathom,
+ extractProductWithFallback,
+ extractProductWithOpenGraph,
+];
+
+/**
+ * Perform product extraction, trying each method from EXTRACTION_METHODS in
+ * order until one of them returns a truthy result.
+ * @return {ExtractedProduct|null}
+ */
+function extractProduct() {
+ for (const extract of EXTRACTION_METHODS) {
+ const extractedProduct = extract(window.document);
+ if (extractedProduct) {
+ return extractedProduct;
+ }
+ }
+
+ return null;
+}
/**
* Checks to see if any product information for the page was found,
* and if so, sends it to the background script.
*/
async function attemptExtraction() {
- const extractedProduct = (
- extractProductWithFathom(window.document)
- || extractProductWithFallback()
- );
-
+ const extractedProduct = extractProduct();
if (extractedProduct) {
await browser.runtime.sendMessage({
from: 'content',
diff --git a/src/extraction/open_graph.js b/src/extraction/open_graph.js
new file mode 100644
index 0000000..144f7fc
--- /dev/null
+++ b/src/extraction/open_graph.js
@@ -0,0 +1,33 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Product extraction via Open Graph tags.
+ */
+
+const OPEN_GRAPH_PROPERTY_VALUES = {
+ title: 'og:title',
+ image: 'og:image',
+ price: 'og:price:amount',
+};
+
+/**
+ * Returns any product information available on the page from Open Graph
+ * tags.
+ */
+export default function extractProduct() {
+ const extractedProduct = {};
+ for (const [feature, propertyValue] of Object.entries(OPEN_GRAPH_PROPERTY_VALUES)) {
+ const metaEle = document.querySelector(`meta[property='${propertyValue}']`);
+
+ // Fail early if any required tags aren't found.
+ if (!metaEle) {
+ return null;
+ }
+
+ extractedProduct[feature] = metaEle.getAttribute('content');
+ }
+
+ return extractedProduct;
+}
diff --git a/src/extraction/fallback/index.js b/src/extraction/selector/index.js
similarity index 72%
rename from src/extraction/fallback/index.js
rename to src/extraction/selector/index.js
index 6dee32d..ccd87bb 100644
--- a/src/extraction/fallback/index.js
+++ b/src/extraction/selector/index.js
@@ -10,14 +10,7 @@
* Features: title, image, price
*/
-import extractionData from 'commerce/extraction/fallback/selectors';
-
-
-const OPEN_GRAPH_PROPERTY_VALUES = {
- title: 'og:title',
- image: 'og:image',
- price: 'og:price:amount',
-};
+import extractionData from 'commerce/extraction/selector/selectors';
/**
* Returns any extraction data found for the vendor based on the URL
@@ -54,22 +47,23 @@ function findValue(extractors) {
/**
* Returns any product information available on the page from CSS
- * selectors if they exist, otherwise from Open Graph tags.
+ * selectors if they exist.
*/
export default function extractProduct() {
- const extractedProduct = {};
const featureInfo = getFeatureInfo();
if (featureInfo) {
+ const extractedProduct = {};
for (const [feature, extractors] of Object.entries(featureInfo)) {
- extractedProduct[feature] = findValue(extractors);
- }
- } else {
- for (const [feature, propertyValue] of Object.entries(OPEN_GRAPH_PROPERTY_VALUES)) {
- const metaEle = document.querySelector(`meta[property='${propertyValue}']`);
- if (metaEle) {
- extractedProduct[feature] = metaEle.getAttribute('content');
+ const featureValue = findValue(extractors);
+ if (!featureValue) {
+ return null;
}
+
+ extractedProduct[feature] = featureValue;
}
+
+ return extractedProduct;
}
- return extractedProduct;
+
+ return null;
}
diff --git a/src/extraction/fallback/selectors.js b/src/extraction/selector/selectors.js
similarity index 100%
rename from src/extraction/fallback/selectors.js
rename to src/extraction/selector/selectors.js