Skip to content

Commit

Permalink
CRX: persistent background page -> event page
Browse files Browse the repository at this point in the history
  • Loading branch information
ebidel committed Jan 18, 2017
1 parent 777fa4f commit 7a2d70b
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 138 deletions.
3 changes: 2 additions & 1 deletion lighthouse-extension/app/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"scripts": [
"scripts/chromereload.js",
"scripts/lighthouse-background.js"
]
],
"persistent": false
},
"permissions": [
"activeTab",
Expand Down
282 changes: 145 additions & 137 deletions lighthouse-extension/app/src/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,152 +16,117 @@
*/
'use strict';

document.addEventListener('DOMContentLoaded', _ => {
const background = chrome.extension.getBackgroundPage();
const defaultAggregations = background.getDefaultAggregations();

const siteNameEl = window.document.querySelector('header h2');
const generateReportEl = document.getElementById('generate-report');
const subpageVisibleClass = 'subpage--visible';

const statusEl = document.body.querySelector('.status');
const statusMessageEl = document.body.querySelector('.status__msg');
const statusDetailsMessageEl = document.body.querySelector('.status__detailsmsg');
const feedbackEl = document.body.querySelector('.feedback');

const generateOptionsEl = document.getElementById('configure-options');
const optionsEl = document.body.querySelector('.options');
const optionsList = document.body.querySelector('.options__list');
const okButton = document.getElementById('ok');
/**
* Error strings that indicate a problem in how Lighthouse was run, not in
* Lighthouse itself, mapped to more useful strings to report to the user.
*/
const NON_BUG_ERROR_MESSAGES = {
'Another debugger': 'You probably have DevTools open. Close DevTools to use Lighthouse',
'multiple tabs': 'You probably have multiple tabs open to the same origin. ' +
'Close the other tabs to use Lighthouse.',
// The extension debugger API is forbidden from attaching to the web store.
// @see https://chromium.googlesource.com/chromium/src/+/5d1f214db0f7996f3c17cd87093d439ce4c7f8f1/chrome/common/extensions/chrome_extensions_client.cc#232
'The extensions gallery cannot be scripted': 'The Lighthouse extension cannot audit the ' +
'Chrome Web Store. If necessary, use the Lighthouse CLI to do so.',
// The user tries to review an error page or has network issues
'Unable to load the page': 'Unable to load the page. Please verify the url you ' +
'are trying to review.'
};

const subpageVisibleClass = 'subpage--visible';

const getBackgroundPage = new Promise((resolve, reject) => {
chrome.runtime.getBackgroundPage(resolve);
});

const MAX_ISSUE_ERROR_LENGTH = 60;
let siteURL = null;
let statusEl = null;

let siteURL = null;

/**
* Error strings that indicate a problem in how Lighthouse was run, not in
* Lighthouse itself, mapped to more useful strings to report to the user.
*/
const NON_BUG_ERROR_MESSAGES = {
'Another debugger': 'You probably have DevTools open. Close DevTools to use Lighthouse',
'multiple tabs': 'You probably have multiple tabs open to the same origin. ' +
'Close the other tabs to use Lighthouse.',
// The extension debugger API is forbidden from attaching to the web store.
// @see https://chromium.googlesource.com/chromium/src/+/5d1f214db0f7996f3c17cd87093d439ce4c7f8f1/chrome/common/extensions/chrome_extensions_client.cc#232
'The extensions gallery cannot be scripted': 'The Lighthouse extension cannot audit the ' +
'Chrome Web Store. If necessary, use the Lighthouse CLI to do so.',
// The user tries to review an error page or has network issues
'Unable to load the page': 'Unable to load the page. Please verify the url you ' +
'are trying to review.'
};

function getLighthouseVersion() {
return chrome.runtime.getManifest().version;
}
function getLighthouseVersion() {
return chrome.runtime.getManifest().version;
}

function getChromeVersion() {
return /Chrome\/([0-9.]+)/.exec(navigator.userAgent)[1];
}
function getChromeVersion() {
return /Chrome\/([0-9.]+)/.exec(navigator.userAgent)[1];
}

function buildReportErrorLink(err) {
const reportErrorEl = document.createElement('a');
reportErrorEl.className = 'button button--report-error';
function startSpinner() {
statusEl.classList.add(subpageVisibleClass);
}

let qsBody = '**Lighthouse Version**: ' + getLighthouseVersion() + '\n';
qsBody += '**Chrome Version**: ' + getChromeVersion() + '\n';
function stopSpinner() {
statusEl.classList.remove(subpageVisibleClass);
}

if (siteURL) {
qsBody += '**URL**: ' + siteURL + '\n';
}

qsBody += '**Error Message**: ' + err.message + '\n';
qsBody += '**Stack Trace**:\n ```' + err.stack + '```';
function buildReportErrorLink(err) {
const MAX_ISSUE_ERROR_LENGTH = 60;

const base = 'https://github.com/googlechrome/lighthouse/issues/new?';
let titleError = err.message;
if (titleError.length > MAX_ISSUE_ERROR_LENGTH) {
titleError = `${titleError.substring(0, MAX_ISSUE_ERROR_LENGTH - 3)}...`;
}
const title = encodeURI('title=Extension Error: ' + titleError);
const body = '&body=' + encodeURI(qsBody);
let qsBody = '**Lighthouse Version**: ' + getLighthouseVersion() + '\n';
qsBody += '**Chrome Version**: ' + getChromeVersion() + '\n';

reportErrorEl.href = base + title + body;
reportErrorEl.textContent = 'Report Error';
reportErrorEl.target = '_blank';
return reportErrorEl;
if (siteURL) {
qsBody += '**URL**: ' + siteURL + '\n';
}

function startSpinner() {
statusEl.classList.add(subpageVisibleClass);
}
qsBody += '**Error Message**: ' + err.message + '\n';
qsBody += '**Stack Trace**:\n ```' + err.stack + '```';

function stopSpinner() {
statusEl.classList.remove(subpageVisibleClass);
}
const base = 'https://github.com/googlechrome/lighthouse/issues/new?';
let titleError = err.message;

function logstatus([, message, details]) {
statusMessageEl.textContent = message;
statusDetailsMessageEl.textContent = details;
if (titleError.length > MAX_ISSUE_ERROR_LENGTH) {
titleError = `${titleError.substring(0, MAX_ISSUE_ERROR_LENGTH - 3)}...`;
}

function createOptionItem(text, isChecked) {
const input = document.createElement('input');
input.setAttribute('type', 'checkbox');
input.setAttribute('value', text);
if (isChecked) {
input.setAttribute('checked', 'checked');
}

const label = document.createElement('label');
label.appendChild(input);
label.appendChild(document.createTextNode(text));
const listItem = document.createElement('li');
listItem.appendChild(label);

return listItem;
const title = encodeURI('title=Extension Error: ' + titleError);
const body = '&body=' + encodeURI(qsBody);

const reportErrorEl = document.createElement('a');
reportErrorEl.className = 'button button--report-error';
reportErrorEl.href = base + title + body;
reportErrorEl.textContent = 'Report Error';
reportErrorEl.target = '_blank';

return reportErrorEl;
}

function logstatus([, message, details]) {
document.querySelector('.status__msg').textContent = message;
const statusDetailsMessageEl = document.querySelector('.status__detailsmsg');
statusDetailsMessageEl.textContent = details;
}

function createOptionItem(text, isChecked) {
const input = document.createElement('input');
input.setAttribute('type', 'checkbox');
input.setAttribute('value', text);
if (isChecked) {
input.setAttribute('checked', 'checked');
}

/**
* Generates a document fragment containing a list of checkboxes and labels
* for the aggregation categories.
* @param {!Object<boolean>} selectedAggregations
* @return {!DocumentFragment}
*/
function generateOptionsList(list, selectedAggregations) {
const frag = document.createDocumentFragment();

defaultAggregations.forEach(aggregation => {
const isChecked = selectedAggregations[aggregation.name];
frag.appendChild(createOptionItem(aggregation.name, isChecked));
});

return frag;
}
const label = document.createElement('label');
label.appendChild(input);
label.appendChild(document.createTextNode(text));
const listItem = document.createElement('li');
listItem.appendChild(label);

if (background.isRunning()) {
startSpinner();
}
return listItem;
}

background.listenForStatus(logstatus);
background.loadSelectedAggregations().then(aggregations => {
const frag = generateOptionsList(optionsList, aggregations);
optionsList.appendChild(frag);
});
function onGenerateReportButtonClick() {
startSpinner();

generateReportEl.addEventListener('click', () => {
startSpinner();
feedbackEl.textContent = '';
const feedbackEl = document.querySelector('.feedback');
feedbackEl.textContent = '';

background.loadSelectedAggregations()
.then(selectedAggregations => {
getBackgroundPage.then(background => {
background.loadSelectedAggregations().then(selectedAggregations => {
return background.runLighthouseInExtension({
flags: {
disableCpuThrottling: true
},
restoreCleanState: true
}, selectedAggregations);
})
.catch(err => {
}).catch(err => {
let message = err.message;
let includeReportLink = true;

Expand All @@ -186,26 +151,69 @@ document.addEventListener('DOMContentLoaded', _ => {
background.console.error(err);
});
});
}

generateOptionsEl.addEventListener('click', () => {
optionsEl.classList.add(subpageVisibleClass);
});
document.addEventListener('DOMContentLoaded', _ => {
getBackgroundPage.then(background => {
statusEl = document.querySelector('.status');

/**
* Generates a document fragment containing a list of checkboxes and labels
* for the aggregation categories.
* @param {!Object<boolean>} selectedAggregations
* @return {!DocumentFragment}
*/
function generateOptionsList(list, selectedAggregations) {
const frag = document.createDocumentFragment();

const defaultAggregations = background.getDefaultAggregations();
defaultAggregations.forEach(aggregation => {
const isChecked = selectedAggregations[aggregation.name];
frag.appendChild(createOptionItem(aggregation.name, isChecked));
});

return frag;
}

okButton.addEventListener('click', () => {
// Save selected aggregation categories on options page close.
const checkedAggregations = Array.from(optionsEl.querySelectorAll(':checked'))
.map(input => input.value);
background.saveSelectedAggregations(checkedAggregations);
if (background.isRunning()) {
startSpinner();
}

optionsEl.classList.remove(subpageVisibleClass);
});
const optionsList = document.querySelector('.options__list');

chrome.tabs.query({active: true, lastFocusedWindow: true}, function(tabs) {
if (tabs.length === 0) {
return;
}
background.listenForStatus(logstatus);
background.loadSelectedAggregations().then(aggregations => {
const frag = generateOptionsList(optionsList, aggregations);
optionsList.appendChild(frag);
});

siteURL = new URL(tabs[0].url);
siteNameEl.textContent = siteURL.origin;
const generateReportEl = document.getElementById('generate-report');
generateReportEl.addEventListener('click', onGenerateReportButtonClick);

const generateOptionsEl = document.getElementById('configure-options');
const optionsEl = document.querySelector('.options');
generateOptionsEl.addEventListener('click', () => {
optionsEl.classList.add(subpageVisibleClass);
});

const okButton = document.getElementById('ok');
okButton.addEventListener('click', () => {
// Save selected aggregation categories on options page close.
const checkedAggregations = Array.from(optionsEl.querySelectorAll(':checked'))
.map(input => input.value);
background.saveSelectedAggregations(checkedAggregations);

optionsEl.classList.remove(subpageVisibleClass);
});

chrome.tabs.query({active: true, lastFocusedWindow: true}, function(tabs) {
if (tabs.length === 0) {
return;
}

siteURL = new URL(tabs[0].url);

document.querySelector('header h2').textContent = siteURL.origin;
});
});
});

0 comments on commit 7a2d70b

Please sign in to comment.