先复习一下! 在第一节中,我们提到: app.ts(srcvscodeelectron-mainapp.ts)的openFirstWindow方法中, 有个WindowsMainService
代码语言:javascript复制const windowsMainService = this.windowsMainService = accessor.get(IWindowsMainService); // TODO@Joao: unfold this
//...
windowsMainService.open({
context,
cli: args,
forceNewWindow: args['new-window'] || (!hasCliArgs && args['unity-launch']),
diffMode: args.diff,
noRecentEntry,
waitMarkerFileURI,
initialStartup: true
});
这个WindowsMainService (接口文件:srcvsplatformwindowselectron-mainwindows.ts) (实例文件:srcvscodeelectron-mainwindows.ts) 接口和实例的关系,是在这里做成的(407行):
代码语言:javascript复制services.set(IWindowsMainService, new SyncDescriptor(WindowsManager, [machineId, this.userEnv]));
实例的open方法最关键的一句话是:
代码语言:javascript复制const usedWindows = this.doOpen(openConfig, workspacesToOpen, foldersToOpen, emptyToRestore, emptyToOpen, fileInputs, foldersToAdd);
在doOpen方法里调用了:this.openInBrowserWindow,并把这个窗口保存到usedWindows里去了; (如果已经有打开的窗口,那么就用现成的窗口打开新的内容)
代码语言:javascript复制usedWindows.push(this.openInBrowserWindow({
userEnv: openConfig.userEnv,
cli: openConfig.cli,
initialStartup: openConfig.initialStartup,
fileInputs: fileInputsForWindow,
remoteAuthority,
forceNewWindow: true,
forceNewTabbedWindow: openConfig.forceNewTabbedWindow,
emptyWindowBackupInfo
}));
我们接下来去看看openInBrowserWindow做了什么 其中最关键的一句:
代码语言:javascript复制window = this.instantiationService.createInstance(CodeWindow, {
state,
extensionDevelopmentPath: configuration.extensionDevelopmentPath,
isExtensionTestHost: !!configuration.extensionTestsPath
});
CodeWindow的构造函数里,调用了createBrowserWindow方法,在这个方法里创建了我们的Electron的BrowserWindow (srcvscodeelectron-mainwindow.ts)
代码语言:javascript复制this._win = new BrowserWindow(options);
好!窗口创建出来了,那么窗口中的内容呢?按道理来说应该加载一个页面用于展现UI的呀? 复习结束,下面是新的内容 我们接着去看openInBrowserWindow方法的后面的内容,发现有这么一句:
代码语言:javascript复制 if (window.isReady) {
this.lifecycleService.unload(window, UnloadReason.LOAD).then(veto => {
if (!veto) {
this.doOpenInBrowserWindow(window!, configuration, options);
}
});
} else {
this.doOpenInBrowserWindow(window, configuration, options);
}
在doOpenInBrowserWindow里,调用了
代码语言:javascript复制window.load(configuration);
OK!我们再回到CodeWindow的类型里去,看看load方法做了什么 我们看到了这一句:
代码语言:javascript复制this._win.loadURL(this.getUrl(configuration));
他们在getUrl方法里做了一堆跟URL一点关系也没有的事情 比如说:设置窗口的缩放级别,设置全屏、设置窗口ID之类的 做完这些无关的事情,有跳进了另一个函数:
代码语言:javascript复制let configUrl = this.doGetUrl(config);
return configUrl;
在这个doGetUrl里只有一句话:
代码语言:javascript复制return `${require.toUrl('vs/code/electron-browser/workbench/workbench.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;
这个require.toUrl方法采用通用的模块ID路径转化规则,将模块ID字符解析成URL路径; 注意:file:///协议开头的URL路径; 至此,这个窗口总算显示出了一个画面! 这个页面body里并没有任何东西;只加载了一个js文件
代码语言:javascript复制<script src="workbench.js"></script>
后面我们再继续聊这个js文件的逻辑!