Skip to content

Commit

Permalink
Merge pull request #83 from Shopify/profile-with-correct-render-backend
Browse files Browse the repository at this point in the history
Fix profile error due to incorrect detection of render backend
  • Loading branch information
umair-choudhary authored Jan 26, 2021
2 parents 5610ce3 + 300e951 commit 4b6315a
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 68 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
80 changes: 37 additions & 43 deletions src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
});

Expand All @@ -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.
Expand Down Expand Up @@ -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;
});
9 changes: 1 addition & 8 deletions src/detectShopify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,21 @@
// 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;
}
}
}

chrome.runtime.sendMessage({
type: 'detect-shopify',
hasDetectedShopify,
isCore,
});

if (document.location.search.includes('shopify_employee')) {
Expand Down
39 changes: 28 additions & 11 deletions src/devtools.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {escape} from 'lodash';
import {RenderBackend} from './env';
import Toolbar from './components/toolbar';
import LiquidFlamegraph from './components/liquid-flamegraph';
import {
Expand Down Expand Up @@ -91,15 +92,28 @@ function getInspectedWindowURL(): Promise<URL> {
});
}

function getRenderingBackend(): Promise<string> {
return new Promise((resolve, reject) => {
chrome.runtime.sendMessage(
{type: 'request-rendering-backend'},
({name, error}) => {
if (error) {
return reject(error);
function determineRenderBackend(): Promise<boolean> {
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);
},
);
});
Expand All @@ -115,18 +129,21 @@ 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),
profile,
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() {
Expand Down
2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
@@ -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"],
Expand Down
14 changes: 10 additions & 4 deletions src/utils/getProfileData.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import nullthrows from 'nullthrows';
import {SubjectAccessToken} from 'types';

export async function getProfileData(url: URL): Promise<FormattedProfileData> {
export async function getProfileData(
url: URL,
isCore: boolean,
): Promise<FormattedProfileData> {
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');
Expand All @@ -31,10 +34,13 @@ function noProfileFound(document: HTMLDocument) {
return document.querySelector('#liquidProfileData') === null;
}

function requestAccessToken({origin}: URL): Promise<SubjectAccessToken> {
function requestAccessToken(
{origin}: URL,
isCore: boolean,
): Promise<SubjectAccessToken> {
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);
Expand Down
4 changes: 3 additions & 1 deletion test/test-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => {};
Expand Down

0 comments on commit 4b6315a

Please sign in to comment.