chromium设置UI的实现

在打开chromium的设置时,chromium会导向一个chrome://settings/的页面,这种UI的实现方式跟其它的UI实现方式有一些区别的,它本质上是一个html页面,能通过javascript与浏览器中的C++代码通信,这种实现称为WebUI,类似的页面可以参考chrome://about/中列出来的页面。类似设置页面这种UI,本身并没有特别复杂的功能,只负责一些数据显示和存储工作,而html+javscript与平台无关,使用起来比较方便,避免使用特定平台的UI库来实现用户UI。

在阅读下文之前,也可以选阅读文章以下文章,使得对WebUI的过程不会生疏。

http://www.chromium.org/developers/webui

通常WebUI的实现需要以下几部分:

  • 一个对应的html页面,页面中包含基本的元素,可以通过javascript为其填充数据,这就是显示界面的html文件。
  • js脚本文件,与后台C++代码的通信由js完成,后台传递过来的数据也通过js进行显示。
  • 一个继承自content::WebUIController的类,它负责与js进行通信。

以下是设置页面的实现说明,它会比官网中例子复杂一些。

1、设置页面使用的url在src/chrome/common/url_constants.h和src/chrome/common/url_constants.cc中定义。

url_constants.h
extern const char kChromeUISettingsURL[];
url_constants.cc
const char kChromeUISettingsURL[] = "chrome://settings/";

在chrome://settings/中,设置部分只是一个frame,它的实现其实就是chrome://settings-frame/settings,在url_constants.cc中定义了这个名称。

const char kChromeUISettingsFrameHost[] = "settings-frame";
2、在src/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc中,根据kChromeUISettingsFrameHost会实例化OptionsUI。

WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, Profile* profile, const GURL& url) {
  .......
  if (url.host() == chrome::kChromeUISettingsFrameHost)
    return &NewWebUI<options::OptionsUI>;
  ......
}

3、在src\chrome\browser\resources\options_resources.grd中定义了设置页面相关的两个文件IDR_OPTIONS_BUNDLE_JS和IDR_OPTIONS_HTML。这两个文件位于src\chrome\browser\resources\options目录下。

<?xml version="1.0" encoding="UTF-8"?>
<grit latest_public_release="0" current_release="1">
  <outputs>
    <output filename="grit/options_resources.h" type="rc_header">
      <emit emit_type='prepend'></emit>
    </output>
    <output filename="options_resources.pak" type="data_package" />
  </outputs>
  <release seq="1">
    <structures>
      <structure name="IDR_OPTIONS_BUNDLE_JS" file="options/options_bundle.js" flattenhtml="true" type="chrome_html" />
      <structure name="IDR_OPTIONS_HTML" file="options/options.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" />
    </structures>
  </release>
</grit>

4、chrome://settings-frame/settings的html页面和js文件在OptionsUI的构造函数中获取,这里读取的就是上一步骤中的两个文件。

OptionsUI::OptionsUI(content::WebUI* web_ui)
    : WebUIController(web_ui),
      WebContentsObserver(web_ui->GetWebContents()),
      initialized_handlers_(false) {
  ......
  OptionsUIHTMLSource* html_source =
      new OptionsUIHTMLSource(localized_strings);
  // Set up the chrome://settings-frame/ source.
  Profile* profile = Profile::FromWebUI(web_ui);
  content::URLDataSource::Add(profile, html_source);
  ......
}

5、WebUI中有两个重要的函数

virtual void AddMessageHandler(WebUIMessageHandler* handler) = 0;
virtual void RegisterMessageCallback(const std::string& message,
                                       const MessageCallback& callback) = 0;
WebUI::AddMessageHandler函数会调用WebUIMessageHandler的RegisterMessages函数。

OptionsPageUIHandler继承WebUIMessageHandler,它有很多子类,分别负责处理特定的消息,并实现该消息的处理函数。

WebUIMessageHandler::RegisterMessages函数会把OptionsPageUIHandler对应的消息处理函数注册到web_ui_中,而这个注册过程则是调用WebUI::RegisterMessageCallback函数实现的。

在OptionsUI的构造函数中会调用AddOptionsPageUIHander()把OptionsUI使用的OptionsPageUIHander通过WebUI::AddMessageHandler函数进行注册。

以下是OptionsUI的类图。


6、以网络内容设置为例,说明设置页面的消息传递过程。


options.html中有以下代码

<div id="main-content">
  <div id="mainview">
    <div id="mainview-content">
      <div id="page-container">
        <!-- Please keep the main pages in desired order of display.  This will
             allow search results to display in the desired order. -->
        <include src="search_box.html">
        <include src="search_page.html">
        <include src="browser_options.html">
      </div>
    </div>
  </div>
</div>
进入browser_options.html,找到网络内容对应的HTML代码段,在选择字体大小后,对应的id是defaultFontSize

  <section id="web-content-section">
    <h3 i18n-content="advancedSectionTitleContent"></h3>
    <div>
      <div class="settings-row">
        <label class="web-content-select-label">
          <span i18n-content="defaultFontSizeLabel"></span>
          <select id="defaultFontSize">
            <option value="9" i18n-content="fontSizeLabelVerySmall">
            </option>
            <option value="12" i18n-content="fontSizeLabelSmall"></option>
            <option value="16" i18n-content="fontSizeLabelMedium"></option>
            <option value="20" i18n-content="fontSizeLabelLarge"></option>
            <option value="24" i18n-content="fontSizeLabelVeryLarge">
            </option>
          </select>
        </label>
        <span id="font-size-indicator"
            class="controlled-setting-indicator"></span>
        <button id="fontSettingsCustomizeFontsButton"
            i18n-content="fontSettingsCustomizeFontsButton"></button>
      </div>
      <div class="settings-row">
        <label class="web-content-select-label">
          <span i18n-content="defaultZoomFactorLabel"></span>
          <select id="defaultZoomFactor" dataType="double"></select>
        </label>
      </div>
    </div>
  </section>
在browser_options.js文件中找到defaultFontSize的处理函数,它会往把选择后的font size通过发送消息defaultFontSizeAction到BrowserOptionsHandler进行处理。

      $('fontSettingsCustomizeFontsButton').onclick = function(event) {
        OptionsPage.navigateToPage('fonts');
        chrome.send('coreOptionsUserMetricsAction', ['Options_FontSettings']);
      };
      $('defaultFontSize').onchange = function(event) {
        var value = event.target.options[event.target.selectedIndex].value;
        Preferences.setIntegerPref(
             'webkit.webprefs.default_fixed_font_size',
             value - OptionsPage.SIZE_DIFFERENCE_FIXED_STANDARD, true);
        chrome.send('defaultFontSizeAction', [String(value)]);
      };
      $('defaultZoomFactor').onchange = function(event) {
        chrome.send('defaultZoomFactorAction',
            [String(event.target.options[event.target.selectedIndex].value)]);
      };
在browser_options_handler.cc中找到defaultFontSizeAction对应的处理函数BrowserOptionsHandler::HandleDefaultFontSize,完成消息的处理。
void BrowserOptionsHandler::RegisterMessages() {
  ......
  web_ui()->RegisterMessageCallback(
      "defaultFontSizeAction",
      base::Bind(&BrowserOptionsHandler::HandleDefaultFontSize,
                 base::Unretained(this)));
  ......
}  






  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值