Skip to content

Commit 2005e16

Browse files
committedApr 23, 2017
1. add BrowserWindow.addExtension, BrowserWindow.removeExtension, and BrowserWindow.getExtensions
2. change the way users load extensions 3. store datas into `userData/` when developing the project
1 parent 1bce422 commit 2005e16

File tree

8 files changed

+110
-63
lines changed

8 files changed

+110
-63
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ app/dist/about.css
1212
extensions/*
1313
builds/*
1414
dist/*
15+
userData/*
1516
coverage
1617
node_modules/
1718
npm-debug.log

‎app/pages/inject-to.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ exports.injectTo = (extensionId, isBackgroundPage, context, LocalStorage) => {
1313

1414
if (LocalStorage) {
1515
storagePath = process.env.NODE_ENV === 'development'
16-
? path.join(remote.app.getPath('temp'), 'lulumi-local-storage')
16+
? path.join(path.resolve('./userData'), 'lulumi-local-storage')
1717
: path.join(remote.app.getPath('userData'), 'lulumi-local-storage');
1818

1919
// eslint-disable-next-line no-undef

‎app/src/api/chrome-extension.js

+34-54
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { app, nativeImage, webContents } from 'electron';
1+
import { app, BrowserWindow, nativeImage, webContents } from 'electron';
22
import { Buffer } from 'buffer';
33
import fs from 'fs';
44
import path from 'path';
@@ -53,15 +53,13 @@ const getManifestFromPath = (srcDirectory) => {
5353
Object.assign(manifest, {
5454
srcDirectory: srcDirectory,
5555
extensionId: extensionId,
56-
// We can not use 'file://' directly because all resources in the extension
57-
// will be treated as relative to the root in Chrome.
5856
startPage: url.format({
59-
protocol: 'chrome-extension',
57+
protocol: 'lulumi-extension',
6058
slashes: true,
6159
hostname: extensionId,
62-
pathname: manifest.devtools_page
63-
})
64-
})
60+
pathname: manifest.devtools_page,
61+
}),
62+
});
6563
return manifest;
6664
} else if (manifest && manifest.name) {
6765
console.warn(`Attempted to load extension "${manifest.name}" that has already been loaded.`);
@@ -151,6 +149,7 @@ const injectContentScripts = (manifest) => {
151149
contentScripts: manifest.content_scripts.map(contentScriptToEntry),
152150
icons: iconsToEntry(manifest.icons),
153151
srcDirectory: manifest.srcDirectory,
152+
name: manifest.name,
154153
};
155154
global.renderProcessPreferences.push(entry);
156155
contentScripts[manifest.name] = entry;
@@ -168,8 +167,6 @@ const removeContentScripts = (manifest) => {
168167
delete contentScripts[manifest.name];
169168
}
170169

171-
// Transfer the |manifest| to a format that can be recognized by the
172-
// |DevToolsAPI.addExtensions|.
173170
const manifestToExtensionInfo = (manifest) => {
174171
return {
175172
startPage: manifest.startPage,
@@ -193,7 +190,6 @@ const loadLulumiExtensions = (win, manifests) => {
193190
manifests.forEach(loadExtension);
194191

195192
const extensionInfoArray = manifests.map(manifestToExtensionInfo);
196-
// win.devToolsWebContents.executeJavaScript(`DevToolsAPI.addExtensions(${JSON.stringify(extensionInfoArray)})`);
197193
};
198194

199195
app.on('web-contents-created', (event, webContents) => {
@@ -228,7 +224,7 @@ const lulumiExtensionHandler = (request, callback) => {
228224

229225
fs.readFile(path.join(manifest.srcDirectory, parsed.path), (err, content) => {
230226
if (err) {
231-
return callback(-6); // FILE_NOT_FOUND
227+
return callback(-6); // FILE_NOT_FOUND
232228
} else {
233229
return callback(content);
234230
}
@@ -246,7 +242,6 @@ app.on('session-created', (sess) => {
246242
// the persistent path of "Lulumi Extensions" preference file
247243
let loadedExtensionsPath = null;
248244

249-
/*
250245
app.on('will-quit', () => {
251246
try {
252247
const loadedExtensions = objectValues(manifestMap).map((manifest) => {
@@ -266,77 +261,62 @@ app.on('will-quit', () => {
266261
// Ignore error
267262
}
268263
});
269-
*/
270264

271265
// we can not use protocol or BrowserWindow until app is ready
272266
app.once('ready', () => {
273267
// load persisted extensions
274268
loadedExtensionsPath = process.env.NODE_ENV === 'development'
275-
? path.resolve('./extensions')
276-
: path.join(config.lulumiAppPath, 'extensions');
269+
? path.join(config.devUserData, 'lulumi-extensions')
270+
: path.join(app.getPath('userData'), 'lulumi-extensions');
277271
try {
278-
const loadedExtensions
279-
= fs.readdirSync(loadedExtensionsPath).filter((file) => file.startsWith('.') === false).filter((file) => fs.lstatSync(path.join(loadedExtensionsPath, file)).isDirectory());
272+
const loadedExtensions = JSON.parse(fs.readFileSync(loadedExtensionsPath));
280273
if (Array.isArray(loadedExtensions)) {
281-
for (const extension of loadedExtensions) {
282-
// Start background pages and set content scripts.
283-
const manifest = getManifestFromPath(path.join(loadedExtensionsPath, extension));
274+
for (const srcDirectory of loadedExtensions) {
275+
// start background pages and set content scripts
276+
const manifest = getManifestFromPath(srcDirectory);
284277
loadExtension(manifest);
285278
}
286279
}
287280
} catch (error) {
288-
// Ignore error
281+
// ignore error
289282
}
290283

291284
// the public API to add/remove extensions
292-
/*
293-
BrowserWindow.addDevToolsExtension = function (srcDirectory) {
294-
const manifest = getManifestFromPath(srcDirectory)
285+
BrowserWindow.addExtension = (srcDirectory) => {
286+
const manifest = getManifestFromPath(srcDirectory);
295287
if (manifest) {
296-
loadExtension(manifest)
297-
for (const webContents of getAllWebContents()) {
288+
loadExtension(manifest);
289+
for (const webContents of webContents.getAllWebContents()) {
298290
if (isWindowOrWebView(webContents)) {
299-
loadDevToolsExtensions(webContents, [manifest])
291+
loadLulumiExtensions(webContents, [manifest]);
300292
}
301293
}
302-
return manifest.name
294+
return manifest.name;
303295
}
304296
}
305297

306-
BrowserWindow.removeDevToolsExtension = function (name) {
307-
const manifest = manifestNameMap[name]
308-
if (!manifest) return
298+
BrowserWindow.removeExtension = (name) => {
299+
const manifest = manifestNameMap[name];
300+
if (!manifest) {
301+
return;
302+
}
309303

310-
removeBackgroundPages(manifest)
311-
removeContentScripts(manifest)
312-
delete manifestMap[manifest.extensionId]
313-
delete manifestNameMap[name]
304+
removeBackgroundPages(manifest);
305+
removeContentScripts(manifest);
306+
delete manifestMap[manifest.extensionId];
307+
delete manifestNameMap[name];
314308
}
315309

316-
BrowserWindow.getDevToolsExtensions = function () {
317-
const extensions = {}
310+
BrowserWindow.getExtensions = () => {
311+
const extensions = {};
318312
Object.keys(manifestNameMap).forEach(function (name) {
319-
const manifest = manifestNameMap[name]
320-
extensions[name] = {name: manifest.name, version: manifest.version}
313+
const manifest = manifestNameMap[name];
314+
extensions[name] = {name: manifest.name, version: manifest.version};
321315
})
322-
return extensions
316+
return extensions;
323317
}
324-
*/
325318
});
326319

327-
export function addExtension (srcDirectory) {
328-
const manifest = getManifestFromPath(srcDirectory);
329-
if (manifest) {
330-
loadExtension(manifest);
331-
for (const webContents of webContents.getAllWebContents()) {
332-
if (isWindowOrWebView(webContents)) {
333-
loadLulumiExtensions(webContents, [manifest]);
334-
}
335-
}
336-
return manifest.name;
337-
}
338-
};
339-
340320
export {
341321
manifestMap,
342322
manifestNameMap,

‎app/src/api/extensions/listeners.js

+35-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,44 @@
1-
import { BrowserWindow, ipcMain, webContents } from 'electron';
1+
import { BrowserWindow, dialog, ipcMain, webContents } from 'electron';
2+
3+
const isDarwin = process.platform === 'darwin';
24

35
ipcMain.on('open-dev-tools', (event, webContentsId) => {
46
if (webContentsId) {
57
webContents.fromId(webContentsId).openDevTools();
68
}
79
});
10+
ipcMain.on('add-extension', (event) => {
11+
if (isDarwin) { // use "sheet" dialog when we are on macOS
12+
const window = BrowserWindow.fromWebContents(event.sender)
13+
dialog.showOpenDialog(window, {
14+
properties: ['openDirectory'],
15+
}, (dirs) => {
16+
if (dirs) {
17+
// an array of diretory paths chosen by the user will be returned, but we only want one path
18+
BrowserWindow.addExtension(dirs[0]);
19+
event.sender.send('add-extension-result', dirs[0]);
20+
}
21+
});
22+
} else {
23+
dialog.showOpenDialog({
24+
properties: ['openDirectory'],
25+
}, (dirs) => {
26+
if (dirs) {
27+
// an array of diretory paths chosen by the user will be returned, but we only want one path
28+
BrowserWindow.addExtension(dirs[0]);
29+
event.sender.send('add-extension-result', dirs[0]);
30+
}
31+
});
32+
}
33+
});
34+
ipcMain.on('remove-extension', (event, name) => {
35+
try {
36+
BrowserWindow.removeExtension(name);
37+
event.sender.send('remove-extension-result', 'OK');
38+
} catch (removeError) {
39+
event.sender.send('remove-extension-result', removeError);
40+
}
41+
});
842

943
ipcMain.on('lulumi-env-app-name', (event) => {
1044
BrowserWindow.getAllWindows()[0]

‎app/src/guest/renderer/components/AboutMainView/Extensions.vue

+34-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
el-row(type="flex", align="middle")
44
el-col(:span="12")
55
h1 Extensions
6+
el-col(:span="6", :offset="3")
7+
el-button(type="info", @click="addExtension") Add
68
el-row
79
el-col(:span="24")
810
ul(class="extensions-list")
911
li(v-for="extension in Object.keys(extensions)", :key="extension", class="extensions-list__item")
12+
el-button(:plain="true", type="danger", size="small", icon="circle-cross", @click="removeExtension(extension)")
1013
a(class="extensions-list__item-name extensions-list__item-link", @click.prevent="openDevTools(extensions[extension].webContentsId)")
1114
img(:src="loadIcon(extension)", style="width: 32px; margin-left: -30px; padding-right: 15px;")
12-
| {{ extension }}
15+
| {{ loadName(extension) }}
1316
div
1417
| {{ "Path: " }}
1518
span(class="extensions-list__item-path") {{ loadPath(extension) }}
@@ -23,6 +26,12 @@
2326
},
2427
},
2528
methods: {
29+
loadName(extensionId) {
30+
// eslint-disable-next-line no-undef
31+
const id = window.renderProcessPreferences
32+
.findIndex(element => element.extensionId === extensionId);
33+
return window.renderProcessPreferences[id].name;
34+
},
2635
loadIcon(extensionId) {
2736
// eslint-disable-next-line no-undef
2837
const id = window.renderProcessPreferences
@@ -39,6 +48,30 @@
3948
// eslint-disable-next-line no-undef
4049
ipcRenderer.send('open-dev-tools', webContentsId);
4150
},
51+
addExtension() {
52+
// eslint-disable-next-line no-undef
53+
ipcRenderer.once('add-extension-result', () => {
54+
window.location.reload();
55+
});
56+
// eslint-disable-next-line no-undef
57+
ipcRenderer.send('add-extension');
58+
},
59+
removeExtension(extensionId) {
60+
// eslint-disable-next-line no-undef
61+
const id = window.renderProcessPreferences
62+
.findIndex(element => element.extensionId === extensionId);
63+
// eslint-disable-next-line no-undef
64+
ipcRenderer.once('remove-extension-result', (event, result) => {
65+
if (result === 'OK') {
66+
window.location.reload();
67+
} else {
68+
// eslint-disable-next-line no-alert
69+
alert(result);
70+
}
71+
});
72+
// eslint-disable-next-line no-undef
73+
ipcRenderer.send('remove-extension', window.renderProcessPreferences[id].name);
74+
},
4275
},
4376
};
4477
</script>

‎app/src/main/index.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,8 @@ let mainWindow;
1313

1414
let shuttingDown = false;
1515
const storagePath = process.env.NODE_ENV === 'development'
16-
? path.join(app.getPath('temp'), '.lulumi-test-app-state')
16+
? path.join(config.devUserData, 'lulumi-app-state')
1717
: path.join(app.getPath('userData'), 'app-state');
18-
if (process.env.NODE_ENV === 'development') {
19-
// eslint-disable-next-line no-console
20-
console.log(storagePath);
21-
}
2218
let appStateSaveHandler = null;
2319

2420
const isDarwin = process.platform === 'darwin';

‎app/src/renderer/js/constants/config.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ let lulumiAppPath = process.env.NODE_ENV === 'development'
44
? `${__dirname}/../../../../`
55
: `${__dirname}/../`;
66
lulumiAppPath = path.resolve(lulumiAppPath);
7+
const lulumiRootPath = path.resolve(`${lulumiAppPath}/../`);
78

89
const searchEngine = [
910
{
@@ -39,5 +40,7 @@ export default {
3940
lulumiPagesPath: `${lulumiAppPath}/pages/`,
4041
lulumiPDFJSPath: `${lulumiAppPath}/pdfjs/`,
4142
lulumiAppPath,
42-
lulumiRev: '8b59339691b7fc405890ffb514f3c1e357b4c478',
43+
lulumiRootPath,
44+
devUserData: `${lulumiRootPath}/userData/`,
45+
lulumiRev: '9862b77491f241ef4e31152893a882b6eb262dd0',
4346
};

‎userData/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)
Please sign in to comment.