From b38415351bd56ae767e2ec49e3e5c9a191c4ba1a Mon Sep 17 00:00:00 2001 From: Umair Choudhary Date: Tue, 26 Jan 2021 09:54:12 -0800 Subject: [PATCH 1/5] Fix profile error due to misdetection of render backend --- src/background.ts | 19 +++++----------- src/detectShopify.ts | 9 +------- src/devtools.ts | 45 +++++++++++++++++++++++++------------ src/utils/getProfileData.ts | 8 +++---- 4 files changed, 42 insertions(+), 39 deletions(-) diff --git a/src/background.ts b/src/background.ts index 7470519..400b033 100644 --- a/src/background.ts +++ b/src/background.ts @@ -89,9 +89,6 @@ chrome.runtime.onMessage.addListener((event, sender) => { chrome.runtime.onMessage.addListener((event, sender) => { if (sender.tab && sender.tab.id && event.type === 'detect-shopify') { setIconAndPopup(event.hasDetectedShopify, sender.tab.id); - renderBackend = event.isCore - ? RenderBackend.Core - : RenderBackend.StorefrontRenderer; } }); @@ -117,11 +114,15 @@ chrome.runtime.onMessage.addListener(({type, origin}, _, sendResponse) => { // Listen for 'request-core-access-token' event and respond to the messenger // with a valid access token. This may trigger a login popup window if needed. -chrome.runtime.onMessage.addListener(({type, origin}, _, sendResponse) => { +chrome.runtime.onMessage.addListener(({type, origin, isCore}, _, sendResponse) => { if (type !== 'request-core-access-token') { return false; } + renderBackend = isCore + ? RenderBackend.Core + : RenderBackend.StorefrontRenderer; + const params = [ [ 'scope', @@ -131,6 +132,7 @@ chrome.runtime.onMessage.addListener(({type, origin}, _, sendResponse) => { ], ]; + // SFR does not need a destination. const destination = renderBackend === RenderBackend.Core ? `${origin}/admin` : ''; @@ -185,12 +187,3 @@ chrome.runtime.onMessage.addListener(({type, origin}, _, sendResponse) => { return true; }); - -chrome.runtime.onMessage.addListener(({type}, _, sendResponse) => { - if (type !== 'request-rendering-backend') return false; - - const name = renderBackend.toString(); - sendResponse({name}); - - return true; -}); diff --git a/src/detectShopify.ts b/src/detectShopify.ts index c161b9d..8d2a98c 100644 --- a/src/detectShopify.ts +++ b/src/detectShopify.ts @@ -4,20 +4,14 @@ // back-end that rendered this page. // Both are generated by {{content_for_header}}. let hasDetectedShopify = false; -let isCore = false; const scripts = document.querySelectorAll('script'); for (let i = 0; i < scripts.length; i++) { - // Short-circuit if we have found everything we need - if (isCore && hasDetectedShopify) break; - const content = scripts[i].textContent; if (typeof content === 'string') { if (/Shopify\.shop\s*=/.test(content)) { hasDetectedShopify = true; - } - if (/BOOMR\.application\s*=\s*"core"/.test(content)) { - isCore = true; + break } } } @@ -25,7 +19,6 @@ for (let i = 0; i < scripts.length; i++) { chrome.runtime.sendMessage({ type: 'detect-shopify', hasDetectedShopify, - isCore, }); if (document.location.search.includes('shopify_employee')) { diff --git a/src/devtools.ts b/src/devtools.ts index aa64b98..2c9206f 100644 --- a/src/devtools.ts +++ b/src/devtools.ts @@ -1,4 +1,5 @@ import {escape} from 'lodash'; +import {RenderBackend} from './env'; import Toolbar from './components/toolbar'; import LiquidFlamegraph from './components/liquid-flamegraph'; import { @@ -91,18 +92,31 @@ function getInspectedWindowURL(): Promise { }); } -function getRenderingBackend(): Promise { - return new Promise((resolve, reject) => { - chrome.runtime.sendMessage( - {type: 'request-rendering-backend'}, - ({name, error}) => { - if (error) { - return reject(error); +function determineRenderBackend(): Promise { + return new Promise(resolve => { + chrome.devtools.inspectedWindow.eval( + ` + function determineRenderBackend() { + const scripts = document.querySelectorAll('script'); + let isCore = false; + for (let i = 0; i < scripts.length; i++) { + const content = scripts[i].textContent; + if (typeof content === 'string') { + if (/BOOMR\\.application\\s*=\\s*"core"/.test(content)) { + isCore = true; + break; + } + } } - return resolve(name); - }, - ); - }); + return isCore + } + determineRenderBackend() + `, + function (isCore: boolean) { + resolve(isCore) + } + ) + }) } async function refreshPanel() { @@ -115,9 +129,14 @@ async function refreshPanel() { let profile: FormattedProfileData; const url = await getInspectedWindowURL(); + const isCore = await determineRenderBackend(); + + const renderingBackend = isCore + ? RenderBackend.Core + : RenderBackend.StorefrontRenderer; try { - profile = await getProfileData(url); + profile = await getProfileData(url, isCore); liquidFlamegraph = new LiquidFlamegraph( document.querySelector(selectors.flamegraphContainer), @@ -125,8 +144,6 @@ async function refreshPanel() { url, ); - const renderingBackend = await getRenderingBackend(); - // All events happening here are synchronous. The set timeout is for UI // purposes so that timing information gets displayed after the flamegraph is shown. setTimeout(function() { diff --git a/src/utils/getProfileData.ts b/src/utils/getProfileData.ts index 31500f7..6f2ddd4 100644 --- a/src/utils/getProfileData.ts +++ b/src/utils/getProfileData.ts @@ -1,11 +1,11 @@ import nullthrows from 'nullthrows'; import {SubjectAccessToken} from 'types'; -export async function getProfileData(url: URL): Promise { +export async function getProfileData(url: URL, isCore: boolean): Promise { const parser = new DOMParser(); const fetchOptions = {} as any; - const {accessToken} = await requestAccessToken(url); + const {accessToken} = await requestAccessToken(url, isCore); fetchOptions.headers = {Authorization: `Bearer ${accessToken}`}; url.searchParams.set('profile_liquid', 'true'); @@ -31,10 +31,10 @@ function noProfileFound(document: HTMLDocument) { return document.querySelector('#liquidProfileData') === null; } -function requestAccessToken({origin}: URL): Promise { +function requestAccessToken({origin}: URL, isCore: boolean): Promise { return new Promise((resolve, reject) => { return chrome.runtime.sendMessage( - {type: 'request-core-access-token', origin}, + {type: 'request-core-access-token', origin, isCore}, ({token, error}) => { if (error) { return reject(error); From ebe3d1062d3e5ee3ce76e5086818ef839602ef6c Mon Sep 17 00:00:00 2001 From: Umair Choudhary Date: Tue, 26 Jan 2021 10:41:53 -0800 Subject: [PATCH 2/5] linting --- src/background.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/background.ts b/src/background.ts index 400b033..6eee6ed 100644 --- a/src/background.ts +++ b/src/background.ts @@ -132,7 +132,6 @@ chrome.runtime.onMessage.addListener(({type, origin, isCore}, _, sendResponse) = ], ]; - // SFR does not need a destination. const destination = renderBackend === RenderBackend.Core ? `${origin}/admin` : ''; From 5f4475148c41e253835ca6f9a5e1ea03d3d6fec8 Mon Sep 17 00:00:00 2001 From: Umair Choudhary Date: Tue, 26 Jan 2021 13:03:45 -0800 Subject: [PATCH 3/5] Fix test --- test/test-helpers.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/test-helpers.ts b/test/test-helpers.ts index ec43045..4b0bff6 100644 --- a/test/test-helpers.ts +++ b/test/test-helpers.ts @@ -24,8 +24,10 @@ export function setDevtoolsEval(page: any) { window.chrome.devtools.inspectedWindow.eval = function(value, cb){ if (value === "typeof window.Shopify === 'object'") { return cb(true) - } else if (/Shopify\\.shop/.test(value)) { + } else if (/Shopify\\.shop/.test(value)) { return cb('shop1.myshopify.io') + } else if (/determineRenderBackend/.test(value)) { + return cb(true) } }; window.chrome.devtools.panels.create = () => {}; From 25ae5744b48461591256e8974e65a28171680f14 Mon Sep 17 00:00:00 2001 From: Umair Choudhary Date: Tue, 26 Jan 2021 13:09:30 -0800 Subject: [PATCH 4/5] linting --- src/background.ts | 76 +++++++++++++++++++------------------ src/detectShopify.ts | 2 +- src/devtools.ts | 10 ++--- src/utils/getProfileData.ts | 10 ++++- 4 files changed, 53 insertions(+), 45 deletions(-) diff --git a/src/background.ts b/src/background.ts index 6eee6ed..9c1d86e 100644 --- a/src/background.ts +++ b/src/background.ts @@ -114,43 +114,45 @@ chrome.runtime.onMessage.addListener(({type, origin}, _, sendResponse) => { // Listen for 'request-core-access-token' event and respond to the messenger // with a valid access token. This may trigger a login popup window if needed. -chrome.runtime.onMessage.addListener(({type, origin, isCore}, _, sendResponse) => { - if (type !== 'request-core-access-token') { - return false; - } - - renderBackend = isCore - ? RenderBackend.Core - : RenderBackend.StorefrontRenderer; - - const params = [ - [ - 'scope', - `${shopifyEmployee === true ? 'employee' : ''} ${ - env.DEVTOOLS_SCOPE[renderBackend] - } ${COLLABORATORS_SCOPE}`, - ], - ]; - - // SFR does not need a destination. - const destination = - renderBackend === RenderBackend.Core ? `${origin}/admin` : ''; - - const oauth = getOauth2Client(origin); - - getSubjectId(oauth, origin) - .then(subjectId => { - return oauth.getSubjectAccessToken(destination, subjectId, params); - }) - .then(token => { - sendResponse({token}); - }) - .catch(error => { - sendResponse({error}); - }); - - return true; -}); +chrome.runtime.onMessage.addListener( + ({type, origin, isCore}, _, sendResponse) => { + if (type !== 'request-core-access-token') { + return false; + } + + renderBackend = isCore + ? RenderBackend.Core + : RenderBackend.StorefrontRenderer; + + const params = [ + [ + 'scope', + `${shopifyEmployee === true ? 'employee' : ''} ${ + env.DEVTOOLS_SCOPE[renderBackend] + } ${COLLABORATORS_SCOPE}`, + ], + ]; + + // SFR does not need a destination. + const destination = + renderBackend === RenderBackend.Core ? `${origin}/admin` : ''; + + const oauth = getOauth2Client(origin); + + getSubjectId(oauth, origin) + .then(subjectId => { + return oauth.getSubjectAccessToken(destination, subjectId, params); + }) + .then(token => { + sendResponse({token}); + }) + .catch(error => { + sendResponse({error}); + }); + + return true; + }, +); // Listen for the 'request-user-info' event and respond to the messenger // with a the given_name of the currently logged in user. diff --git a/src/detectShopify.ts b/src/detectShopify.ts index 8d2a98c..4183b9e 100644 --- a/src/detectShopify.ts +++ b/src/detectShopify.ts @@ -11,7 +11,7 @@ for (let i = 0; i < scripts.length; i++) { if (typeof content === 'string') { if (/Shopify\.shop\s*=/.test(content)) { hasDetectedShopify = true; - break + break; } } } diff --git a/src/devtools.ts b/src/devtools.ts index 2c9206f..52e53c7 100644 --- a/src/devtools.ts +++ b/src/devtools.ts @@ -112,11 +112,11 @@ function determineRenderBackend(): Promise { } determineRenderBackend() `, - function (isCore: boolean) { - resolve(isCore) - } - ) - }) + function(isCore: boolean) { + resolve(isCore); + }, + ); + }); } async function refreshPanel() { diff --git a/src/utils/getProfileData.ts b/src/utils/getProfileData.ts index 6f2ddd4..e03f0f0 100644 --- a/src/utils/getProfileData.ts +++ b/src/utils/getProfileData.ts @@ -1,7 +1,10 @@ import nullthrows from 'nullthrows'; import {SubjectAccessToken} from 'types'; -export async function getProfileData(url: URL, isCore: boolean): Promise { +export async function getProfileData( + url: URL, + isCore: boolean, +): Promise { const parser = new DOMParser(); const fetchOptions = {} as any; @@ -31,7 +34,10 @@ function noProfileFound(document: HTMLDocument) { return document.querySelector('#liquidProfileData') === null; } -function requestAccessToken({origin}: URL, isCore: boolean): Promise { +function requestAccessToken( + {origin}: URL, + isCore: boolean, +): Promise { return new Promise((resolve, reject) => { return chrome.runtime.sendMessage( {type: 'request-core-access-token', origin, isCore}, From 300e951468acdcf85915f4e813872f99aad67f4b Mon Sep 17 00:00:00 2001 From: Umair Choudhary Date: Tue, 26 Jan 2021 14:36:04 -0800 Subject: [PATCH 5/5] Update changelog and bump version --- CHANGELOG.md | 3 +++ src/manifest.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36d1d6e..1e80603 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## v2.0.1 (Jan 26, 2021) +* [#83](https://github.com/Shopify/shopify-theme-inspector/pull/83) Fix profiling error due to incorrect detection of render backend + ## v2.0.0 (Jan 4, 2021) * [#77](https://github.com/Shopify/shopify-theme-inspector/pull/77) Update data format with change update diff --git a/src/manifest.json b/src/manifest.json index 58dc88d..cf1853a 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,6 +1,6 @@ { "name": "Shopify Theme Inspector for Chrome", - "version": "2.0.0", + "version": "2.0.1", "description": "Profile and debug Liquid template on your Shopify store", "devtools_page": "devtools.html", "permissions": ["storage", "identity", "activeTab"],