zoukankan      html  css  js  c++  java
  • vscode源码分析【八】加载第一个画面

    第一篇: vscode源码分析【一】从源码运行vscode
    第二篇:vscode源码分析【二】程序的启动逻辑,第一个窗口是如何创建的
    第三篇:vscode源码分析【三】程序的启动逻辑,性能问题的追踪
    第四篇:vscode源码分析【四】程序启动的逻辑,最初创建的服务
    第五篇:vscode源码分析【五】事件分发机制
    第六篇:vscode源码分析【六】服务实例化和单例的实现
    第七篇:vscode源码分析【七】主进程启动消息通信服务
    先复习一下!
    在第一节中,我们提到:
    app.ts(srcvscodeelectron-mainapp.ts)的openFirstWindow方法中,
    有个WindowsMainService

    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行):

    services.set(IWindowsMainService, new SyncDescriptor(WindowsManager, [machineId, this.userEnv]));

    实例的open方法最关键的一句话是:

    const usedWindows = this.doOpen(openConfig, workspacesToOpen, foldersToOpen, emptyToRestore, emptyToOpen, fileInputs, foldersToAdd);

    在doOpen方法里调用了:this.openInBrowserWindow,并把这个窗口保存到usedWindows里去了;
    (如果已经有打开的窗口,那么就用现成的窗口打开新的内容)

    usedWindows.push(this.openInBrowserWindow({
    					userEnv: openConfig.userEnv,
    					cli: openConfig.cli,
    					initialStartup: openConfig.initialStartup,
    					fileInputs: fileInputsForWindow,
    					remoteAuthority,
    					forceNewWindow: true,
    					forceNewTabbedWindow: openConfig.forceNewTabbedWindow,
    					emptyWindowBackupInfo
    				}));

    我们接下来去看看openInBrowserWindow做了什么
    其中最关键的一句:

    window = this.instantiationService.createInstance(CodeWindow, {
    				state,
    				extensionDevelopmentPath: configuration.extensionDevelopmentPath,
    				isExtensionTestHost: !!configuration.extensionTestsPath
    			});

    CodeWindow的构造函数里,调用了createBrowserWindow方法,在这个方法里创建了我们的Electron的BrowserWindow
    (srcvscodeelectron-mainwindow.ts)

    this._win = new BrowserWindow(options);

    好!窗口创建出来了,那么窗口中的内容呢?按道理来说应该加载一个页面用于展现UI的呀?
    复习结束,下面是新的内容
    我们接着去看openInBrowserWindow方法的后面的内容,发现有这么一句:

    		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里,调用了

    window.load(configuration);

    OK!我们再回到CodeWindow的类型里去,看看load方法做了什么
    我们看到了这一句:

    this._win.loadURL(this.getUrl(configuration));

    他们在getUrl方法里做了一堆跟URL一点关系也没有的事情
    比如说:设置窗口的缩放级别,设置全屏、设置窗口ID之类的
    做完这些无关的事情,有跳进了另一个函数:

    let configUrl = this.doGetUrl(config);
    return configUrl;

    在这个doGetUrl里只有一句话:

    return `${require.toUrl('vs/code/electron-browser/workbench/workbench.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;

    这个require.toUrl方法采用通用的模块ID路径转化规则,将模块ID字符解析成URL路径;
    注意:file:///协议开头的URL路径;
    至此,这个窗口总算显示出了一个画面!
    这个页面body里并没有任何东西;只加载了一个js文件

    <script src="workbench.js"></script>

    后面我们再继续聊这个js文件的逻辑!




     

  • 相关阅读:
    Java 过滤器
    理解Java中的弱引用(Weak Reference)
    AOP编程
    利用ThreadLocal管理事务
    Redis设计与实现-附加功能
    Redis设计与实现-主从、哨兵与集群
    Redis设计与实现-客户端服务端与事件
    Redis设计与实现-持久化篇
    Redis设计与实现-内部数据结构篇
    重温软件架构设计-程序员向架构师转型必备
  • 原文地址:https://www.cnblogs.com/liulun/p/11058363.html
Copyright © 2011-2022 走看看