自己写一个极简浏览器

——基于Chromium的浏览器

可以让chatGPT写一个浏览器 自己写一个浏览器_c#


我的Github地址:

官方:https://github.com/KaiHuaDou/EasyBrowserAdvanced/releases

加速:https://github.com.cnpmjs.org/KaiHuaDou/EasyBrowserAdvanced/releases


目的

我们使用手机、电脑时,遇到的最大问题,大概就是蓝屏和慢。

蓝屏我解决不了(可以找微软),只能解决“慢”

显然,解决”慢“这个问题,只有两种途径:

  1. 解决操作系统问题(Linux?自己写?
  2. 解决软件问题

让大家都用Linux可实施性太弱,所以,我只能解决软件问题。

那么,软件中最常用的,莫过于浏览器。考虑到技术难度不算太高,代码量在15000行左右,我决定——自己写一个浏览器!

我的浏览器特点就是快,非常快!但是速度快,有些功能就得舍弃,不过人们用浏览器,也不过是看看自己Github上有多少颗Star而已,所以这并不是缺点。

那么,浏览器叫什么呢?作为强迫症晚期患者的我,决定给我的浏览器起一个简洁的名字:极简浏览器!


开始了

浏览器这种软件大体可以分为两个部分:核、壳

我们有以下几种办法:

内核

优点

缺点

Trident

Windows内置,无需安装,教程多

性能低下,陈旧过时,各大网站均阻止或屏蔽

Gecko

轻巧易用,性能良好

没有嵌入式Nuget程序包

Chromium

性能极佳,范围广泛,嵌入性强,教程多

不支持HTTP,FTP,FTPS,默认不支持Flash Player

最终我选用了Chromium,也就是Chrome的内核,通过CefSharp作为内核框架进行开发,并且可以在微软官方Nuget包源上找到。


代码

为了维持项目不变成代码垃圾堆,我可下了一番功夫

设计模式

我使用VEA模式,即View->Event->Api模式,界面接收操作,事件处理程序响应,交给Api去处理,返回给事件处理程序,事件更新页面

多进程模型

一个标签页一个进程,由于速度极快,并没有延迟

Api思想

将浏览器模块统一进BrowserCore.cs,这样在访问到下一个页面时,使用的是BrowserCore.Navigate(url);,而不是cwb.Address = url;,同时也可以从其他类来控制主窗口,通过GetInstance()方法,在窗口列表里检测类型为MainWindow是窗口,从而获取实例。

同时加入“不文明语言检测器”,保证访问的网页是文明的。

文件架构
/
│  .gitattributes
│  .gitignore
│  README.md //帮助文件
│  极简浏览器Cef.sln //项目文件
├─packages //Chromium Nuget程序包
│  ├─cef.redist.x64.86.0.24
│  │  └─略
│  ├─cef.redist.x86.86.0.24
│  │  └─略
│  ├─CefSharp.Common.86.0.241  
│  │  └─略   
│  └─CefSharp.Wpf.86.0.241      
│      └─略             
├─Setup //安装程序
│  └─略
└─极简浏览器Cef
    │  App.config
    │  App.xaml
    │  App.xaml.cs
    │  BrowserExtension.cs //MainWindow.xaml.cs的扩展
    │  BrowserHelper.cs //ChromiumWebBrowser的扩展
    │  favicon.ico //图标
    │  MainWindow.xaml
    │  MainWindow.xaml.cs
    │  packages.config
    │  极简浏览器.csproj
    │  极简浏览器.csproj.user
    ├─Api
    │      BrowserCore.cs //浏览器内核管理(包括导航)
    │      CivilizedLanguage.cs //不文明语言检测器
    │      FileApi.cs //历史记录与书签
    │      FilePath.cs //路径文件
    │      HtmlFormatter.cs //HTML格式化
    │      Logger.cs //日志记录器
    │      NewInstance.cs //标签页管理器
    │      StandardApi.cs //其他Api(标准Api)
    │      
    ├─bin
    │  └─略
    ├─Dialog
    │      About.xaml //关于
    │      About.xaml.cs
    │      Help.xaml //帮助
    │      Help.xaml.cs
    │      History.xaml //历史记录与书签
    │      History.xaml.cs
    │      Setting.xaml //设置
    │      Setting.xaml.cs
    │      WebSource.xaml //网页源代码
    │      WebSource.xaml.cs
    ├─lib
    │      pepflashplayer.dll //Flash Player
    ├─Properties //资源文件
    │      AssemblyInfo.cs
    │      Resources.Designer.cs
    │      Resources.resx
    │      Settings.Designer.cs
    │      Settings.settings
    └─resource //图片资源
            Error.png 
            刷新.png //均截图自Chrome 89
            向前.png
            向后.png
            添加.png

详情看上面的注释。

GUI(图形界面)

既然说是“极简”,GUI设计肯定也要遵从极简原则,我将浏览器分为三部分:顶栏,中栏,底栏。

栏位

功能

顶栏

前进、后退、刷新、地址栏(兼搜索)、添加新窗口

中栏

网页展示

底栏

加载状态、菜单

说干就干,一个83行长的XAML就写完了:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:极简浏览器"
        xmlns:c="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf" x:Class="极简浏览器.MainWindow" Title="极简浏览器" Width="600"
        WindowStartupLocation="Manual" WindowState="Normal" Loaded="Window_Loaded" Icon="favicon.ico" Height="500">
    <Window.Resources>
        <ControlTemplate x:Key="FilletTextBox" TargetType="{x:Type TextBox}">
            <Border BorderBrush="Gray" BorderThickness="1" CornerRadius="10">
                <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" />
            </Border>
        </ControlTemplate>
    </Window.Resources>
    <Window.TaskbarItemInfo>
        <TaskbarItemInfo />
    </Window.TaskbarItemInfo>
    <Grid x:Name="MainGrid">
        <Grid.ContextMenu>
            <ContextMenu>
                <MenuItem x:Name="HidestartusBar" Header="隐藏状态栏" Click="StatusBar_ContextMenu_Click" />
            </ContextMenu>
        </Grid.ContextMenu>
        <Grid x:Name="CWBGrid" Margin="0,37,0,35">
        </Grid>
        <Button x:Name="GoBackButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="35" Height="30"
                Click="GoBackButton_Click" Foreground="Black" FontWeight="ExtraBlack" Background="{x:Null}"
                BorderBrush="{x:Null}" FontSize="24" FocusVisualStyle="{x:Null}" BorderThickness="0">
            <Image Source="resource\向前.png"></Image>
        </Button>
        <Button x:Name="GoForwardButton" HorizontalAlignment="Left" Margin="35,0,0,0" VerticalAlignment="Top" Width="35"
                Height="30" Click="GoForwardButton_Click" Foreground="Black" BorderBrush="{x:Null}" FontSize="24"
                BorderThickness="0" FocusVisualStyle="{x:Null}" Background="{x:Null}">
            <Image Source="resource\向后.png"></Image>
        </Button>
        <Button x:Name="RefershButton" HorizontalAlignment="Right" Margin="0,0,36,0" VerticalAlignment="Top" Width="31"
                Height="30" Click="RefreshButton_Click" BorderBrush="{x:Null}" Foreground="{x:Null}"
                Background="{x:Null}" FocusVisualStyle="{Binding ElementName=button3,Path=Style}" BorderThickness="0">
            <Image x:Name="image" Height="30" Width="30" Source="resource\刷新.png" />
        </Button>
        <StatusBar x:Name="startusBar" Height="35" Margin="0,0,144,0" VerticalAlignment="Bottom">
            <Label x:Name="label1" Content="" Height="35" />
            <Label x:Name="label2" Content="此网页不文明!" Height="35" Visibility="Collapsed" Foreground="Red" />
        </StatusBar>
        <Button x:Name="AddNewPageButton" HorizontalAlignment="Right" Margin="0,0,0,0" VerticalAlignment="Top"
                Width="35" FontSize="22" Height="30" Click="AddNewPageButton_Click" Background="{x:Null}"
                Foreground="{x:Null}" BorderBrush="{x:Null}" FocusVisualStyle="{x:Null}" BorderThickness="0">
            <Image x:Name="image1" Margin="0,0,0,0" Source="resource\添加.png" />
        </Button>
        <Menu x:Name="OptionMenu" HorizontalAlignment="Right" Height="35" Margin="0,0,0,0" VerticalAlignment="Bottom"
                Width="144">
            <MenuItem Header="开发者" Height="35" Width="72" BorderThickness="0" FontSize="22">
                <MenuItem  x:Name="DevToolsButton" Header="开发者工具(_D)" HorizontalAlignment="Left" Width="285" FontSize="24" Click="DevToolsButton_Click" />
            </MenuItem>
            <MenuItem Header="更多..." Height="35" Width="72" BorderThickness="0" FontSize="22">
                <MenuItem Header="上一页(_P)" HorizontalAlignment="Left" Width="285" FontSize="24"
                        Click="GoForwardButton_Click" />
                <MenuItem Header="下一页(_N)" HorizontalAlignment="Left" Width="285" FontSize="24"
                        Click="GoBackButton_Click" />
                <MenuItem Header="刷新(_R)" HorizontalAlignment="Left" Width="285" FontSize="24"
                        Click="RefreshButton_Click" />
                <MenuItem Header="添加新页面(_W)" HorizontalAlignment="Left" Width="285" FontSize="24"
                        Click="AddNewPageButton_Click" />
                <MenuItem Header="查看网页源代码(_U)" HorizontalAlignment="Left" Width="285" FontSize="24"
                        Click="ViewSource_Click" Margin="0,0,-22,0" />
                <MenuItem Header="设为书签(_B)" HorizontalAlignment="Left" Width="285" Click="SetBookMark_Click" />
                <MenuItem Header="查看书签(_V)" HorizontalAlignment="Left" Width="285" Click="ViewBookMark_Click" />
                <MenuItem Header="历史记录(_H)" HorizontalAlignment="Left" Width="285" Click="ViewHistory_Click" />
                <MenuItem Header="设置(_S)" HorizontalAlignment="Left" Width="285" FontSize="24" Click="Setting_Click" />
                <MenuItem Header="帮助(_H)" HorizontalAlignment="Left" Width="285" FontSize="24" Click="Help_Click" />
                <MenuItem Header="关于(_A)" HorizontalAlignment="Left" Width="285" FontSize="24" Click="About_Click" />
                <MenuItem Header="置顶(_T)" HorizontalAlignment="Left" Width="285" FontSize="24" IsCheckable="True"
                        Click="Topmost_Checked" />
                <MenuItem Header="在本窗口打开(_C)" HorizontalAlignment="Left" Width="285" FontSize="24" IsCheckable="True"
                        x:Name="OnlyThis" />
                <MenuItem Header="无痕模式(_C)" HorizontalAlignment="Left" Width="285" FontSize="24" IsCheckable="True"
                        x:Name="NoLogs" />
            </MenuItem>
        </Menu>
        <ProgressBar x:Name="LoadProgressBar" Maximum="100" Margin="0,30,0,0" HorizontalAlignment="Stretch"
                VerticalAlignment="Top" Height="7" Background="{x:Null}" BorderThickness="0">
        </ProgressBar>
        <TextBox x:Name="UrlTextBox" Height="30" TextWrapping="NoWrap" Text="" VerticalAlignment="Top" FontSize="20"
                Margin="70,0,70,0" Background="White" KeyDown="Go" Template="{StaticResource FilletTextBox}" />
    </Grid>
</Window>

注:请忽略关联的事件处理程序

可以让chatGPT写一个浏览器 自己写一个浏览器_chrome_02

其他页面当然也毫不例外,在此不再一一展示


结束

经过了 三年 的努力,我的极简浏览器终于写完了,现在在Github上已经更新到3.2.1.11版本了,当然里面也有很多不足之处,希望大家多多指正。