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/background.ts b/src/background.ts index 7470519..9c1d86e 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,39 +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}, _, sendResponse) => { - if (type !== 'request-core-access-token') { - return false; - } +chrome.runtime.onMessage.addListener( + ({type, origin, isCore}, _, sendResponse) => { + if (type !== 'request-core-access-token') { + return false; + } - 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}); - }); + renderBackend = isCore + ? RenderBackend.Core + : RenderBackend.StorefrontRenderer; - return true; -}); + 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. @@ -185,12 +188,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..4183b9e 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..52e53c7 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,15 +92,28 @@ 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); }, ); }); @@ -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/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"], diff --git a/src/utils/getProfileData.ts b/src/utils/getProfileData.ts index 31500f7..e03f0f0 100644 --- a/src/utils/getProfileData.ts +++ b/src/utils/getProfileData.ts @@ -1,11 +1,14 @@ 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 +34,13 @@ 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); 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 = () => {};