转载自:http://www.chromium.org/developers/webui

Chrome的WebUI是那种,在Chrome中输入 "chrome://xxxx"就能打开一个URL页面的对象。

创建一个Chrome WebUI接口非常的简单,只需要改动数个文件。

创建WebUI页面

webui的资源,放在资源目录下:src/chrome/browser/resources. 当创建WebUI资源时,参考Web Development Style Guide。例如,我们创建一个HelloWorld的页面

src/chrome/browser/resources/hello_world.html


<!DOCTYPE HTML>

<html i18n-values="dir:textdirection">
<head>
 <meta charset="utf-8">
 <title i18n-content="helloWorldTitle"></title>

 <link rel="stylesheet" href="hello_world.css">

<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/load_time_data.js"></script>
<script src="chrome://resources/js/util.js"></script>
 
 <script src="strings.js"></script>
 <script src="hello_world.js"></script>
</head>
 
 
 
<body i18n-values=".style.fontFamily:fontfamily;.style.fontSize:fontsize">
  <h1 i18n-content="helloWorldTitle"></h1>
  <p id="welcome-message"></p>

<script src="chrome://resources/js/i18n_template2.js"></script>

</body>
 
</html>


src/chrome/browser/resources/hello_world.css:
 
p {
  white-space: pre-wrap;
}
 

src/chrome/browser/resources/hello_world.js:
 
cr.define('hello_world', function() {
  'use strict';

  /**
   * Be polite and insert translated hello world strings for the user on loading.
   */
  function initialize() {

    $('welcome-message').textContent = loadTimeData.getStringF('welcomeMessage',
        loadTimeData.getString('userName'));

  }

  // Return an object with all of the exports.
  return {
    initialize: initialize,
  };
});

document.addEventListener('DOMContentLoaded', hello_world.initialize);

资源信息应该添加到Chrome使用的
src/chrome/browser/browser_resources.grd文件中。
src/chrome/browser/browser_resources.grd:

 
+ <include name="IDR_HELLO_WORLD_HTML" file="resources\hello_world.html" type="BINDATA" />
+ <include name="IDR_HELLO_WORLD_CSS" file="resources\hello_world.css" type="BINDATA" />
+ <include name="IDR_HELLO_WORLD_JS" file="resources\hello_world.js" type="BINDATA" />

添加URL标识到新的Chrome URL中

URL标识被保存在
src/chrome/common/url_constants.*文件中。
src/chrome/common/url_constants.h:
 
+ extern const char kChromeUIHelloWorldURL[];
...
+ extern const char kChromeUIHelloWorldHost[];


src/chrome/common/url_constants.cc:
 
+ const char kChromeUIHelloWorldURL[] = "chrome://hello-world/";
...
+ const char kChromeUIHelloWorldHost[] = "hello-world";

添加本地字符串

我们需要为新的资源添加新的本地化字符串。比如一个欢迎信息

src/chrome/app/generated_resources.grd:
 
+ <message name="IDS_HELLO_WORLD_TITLE" desc="A happy message saying hello to the world">
+   Hello World!
+ </message>

+ <message name="IDS_HELLO_WORLD_WELCOME_TEXT" desc="Message welcoming the user to the hello world page">
+   Welcome to this fancy Hello World page <ph name="WELCOME_NAME">$1<ex>Chromium User</ex></ph>!
+ </message>

添加处理chrome://hello-world/请求的WebUI类


下面我们增加一个新的类来处理新的资源。通常情况下,它是ChromeWebUI的一个子类(WebUI对话框则从HtmlDialogUI继承)

src/chrome/browser/ui/webui/hello_world_ui.h:
 
#ifndef CHROME_BROWSER_UI_WEBUI_HELLO_WORLD_UI_H_
#define CHROME_BROWSER_UI_WEBUI_HELLO_WORLD_UI_H_
#pragma once

#include "content/public/browser/web_ui_controller.h"

// The WebUI for chrome://hello-world
class HelloWorldUI : public content::WebUIController {
 public:
  explicit HelloWorldUI(content::WebUI* web_ui);
  virtual ~HelloWorldUI();
 private:
 
  DISALLOW_COPY_AND_ASSIGN(HelloWorldUI);
};

#endif  // CHROME_BROWSER_UI_WEBUI_HELLO_WORLD_UI_H_


src/chrome/browser/ui/webui/hello_world_ui.cc:
 
 
#include "chrome/browser/ui/webui/hello_world_ui.h"

#include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/web_ui_data_source.h"

#include "grit/browser_resources.h"

#include "grit/generated_resources.h"

HelloWorldUI::HelloWorldUI(content::WebUI* web_ui)
    : content::WebUIController(web_ui) {
  // Set up the chrome://hello-world source.
  
content::WebUIDataSource
* html_source =
      new 
content::WebUIDataSource
(chrome::kChromeUIHelloWorldHost);
  html_source->
SetUseJsonJSFormatV2()
;

  // Localized strings.
  html_source->AddLocalizedString("helloWorldTitle", IDS_HELLO_WORLD_TITLE);
  html_source->AddLocalizedString("welcomeMessage", IDS_HELLO_WORLD_WELCOME_TEXT);

  // As a demonstration of passing a variable for JS to use we pass in the name "Bob".
  html_source->AddString("userName", "Bob");
  html_source->
SetJsonPath
("strings.js");

  // Add required resources.
  html_source->
AddResourcePath
("hello_world.css", IDR_HELLO_WORLD_CSS);
  html_source->
AddResourcePath
("hello_world.js", IDR_HELLO_WORLD_JS);
  html_source->
SetDefaultResource
(IDR_HELLO_WORLD_HTML);

  Profile* profile = Profile::FromWebUI(web_ui);
  content::WebUIDataSource::Add(profile, html_source);

}

HelloWorldUI::~HelloWorldUI() {
}

编译新的类,需要添加到工程的gyp文件中

src/chrome/chrome_browser_ui.gypi:
 
'sources': [
...
+   'browser/ui/webui/hello_world_ui.cc',
+   'browser/ui/webui/hello_world_ui.h',

添加WebUI请求到Chrome WebUI工厂

WebUI的工厂负责响应并创建你的请求

src/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc:
 
+ #include "chrome/browser/ui/webui/hello_world_ui.h"
...
+ if (url.host() == chrome::kChromeUIHelloWorldHost)
+   return &NewWebUI<HelloWorldUI>;

测试

OK!假定没有错误,你可以编译和运行chrome了。并在地址栏输入 chrome:://hello-world/ 你将看到欢迎信息。

增加回调处理句柄

你也许你问新的WebUI页面能够做些什么事情,或者从C++世界获取一些信息。为此,我们使用消息回调句柄。 假设我们不信任javascript引擎的两个整数相加(因为我们知道,它内部是使用浮点数的)。我们可以增加回调句柄来处理我们的整数运算。

src/chrome/browser/ui/webui/hello_world_ui.h:
 
#include "chrome/browser/ui/webui/chrome_web_ui.h"
+
+ namespace base {
+   class ListValue;
+ }  // namespace base

// The WebUI for chrome://hello-world
...
    // Set up the chrome://hello-world source.
    ChromeWebUIDataSource* html_source =
        new ChromeWebUIDataSource(chrome::kChromeUIHelloWorldHost);
+
+   // Register callback handler.
+   RegisterMessageCallback("addNumbers",
+       base::Bind(&HelloWorldUI::AddNumbers,
+                  base::Unretained(this)));


    // Localized strings.

...

    virtual ~HelloWorldUI();
+
+  private:
+   // Add two numbers together using integer arithmetic.
+   void AddNumbers(const base::ListValue* args);

    DISALLOW_COPY_AND_ASSIGN(HelloWorldUI);
  };


src/chrome/browser/ui/webui/hello_world_ui.cc:
 
  #include "chrome/browser/ui/webui/hello_world_ui.h"
+
+ #include "base/values.h"
  #include "chrome/browser/profiles/profile.h"
...
  HelloWorldUI::~HelloWorldUI() {

  }
+
+ void HelloWorldUI::AddNumbers(const base::ListValue* args) {
+   int term1, term2;
+   if (!args->GetInteger(0, &term1) || !args->GetInteger(1, &term2))
+     return;
+   base::FundamentalValue result(term1 + term2);
+   CallJavascriptFunction("hello_world.addResult", result);
+ }


src/chrome/browser/resources/hello_world.js:
 
    function initialize() {
+     chrome.send('addNumbers', [2, 2]);
    }
+
+   function addResult(result) {
+     alert('The result of our C++ arithmetic: 2 + 2 = ' + result);
+   }

    return {
+     addResult: addResult,
      initialize: initialize,
    };

请注意调用是异步的。我们必须等待C++端主带调用javascript的函数才能获取到结果。

创建WebUI对话框

一旦你按照上面的步骤创建了一个WebUI,你需要修改两个地方来创建一个WebUI Dialog。你必须从HtmlDialogUI继承,并创建一个HtmlDialogUIDelegate类。

1. 替换ChromeWebUI为HtmlDialogUIDelegate

src/chrome/browser/ui/webui/hello_world_ui.h:
 
 
- #include "#chrome/browser/ui/webui/chrome_web_ui.h"
+ #include "#chrome/browser/ui/webui/html_dialog_ui.h"

- class HelloWorldUI : public ChromeWebUI {
+ class HelloWorldUI : public HtmlDialogUI {

 

2. 创建一个HtmlDialogUIDelegage

src/chrome/browser/ui/webui/hello_world.h
 
#ifndef CHROME_BROWSER_UI_WEBUI_HELLO_WORLD_H_
#define 
CHROME_BROWSER_UI_WEBUI_HELLO_WORLD_H_
#pragma once

#include "chrome/browser/ui/webui/html_dialog_ui.h"

class HelloWorldDialog : private HtmlDialogUIDelegate {
 public:
  // Shows the Hello World dialog.
  static void ShowDialog();
  virtual ~HelloWorldDialog();

 private:
  // Construct a Hello World dialog
  explicit HelloWorldDialog();

  // Overridden from HtmlDialogUI::Delegate:
  virtual bool IsDialogModal() const OVERRIDE;
  virtual string16 GetDialogTitle() const OVERRIDE;
  virtual GURL GetDialogContentURL() const OVERRIDE;
  virtual void GetWebUIMessageHandlers(
      std::vector<WebUIMessageHandler*>* handlers) const OVERRIDE;
  virtual void GetDialogSize(gfx::Size* size) const OVERRIDE;
  virtual std::string GetDialogArgs() const OVERRIDE;
  virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE;
  virtual void OnCloseContents(
      TabContents* source, bool* out_close_dialog) OVERRIDE;
  virtual bool ShouldShowDialogTitle() const OVERRIDE;

  DISALLOW_COPY_AND_ASSIGN(HelloWorldDialog);
};

#endif  // 
CHROME_BROWSER_UI_WEBUI_HELLO_WORLD_H_


src/chrome/browser/ui/webui/hello_world.cc
 

#include "base/utf_string_conversions.h"
#include "chrome/browser/ui/browser.h"

#include "chrome/browser/ui/browser_list.h"

#include "chrome/browser/ui/webui/hello_world.h"
#include "chrome/common/url_constants.h"

void HelloWorldDialog::ShowDialog() {
  Browser* browser = BrowserList::GetLastActive();
  DCHECK(browser);
  browser->BrowserShowHtmlDialog(new HelloWorldDialog(), NULL);
}

HelloWorldDialog::HelloWorldDialog() {
}

HelloWorldDialog::~HelloWorldDialog() {
}

bool HelloWorldDialog::IsDialogModal() {
  return false;
}

string16 HelloWorldDialog::GetDialogTitle() {
  return UTF8ToUTF16("Hello World");
}

GURL HelloWorldDialog::GetDialogContentURL() const {
  return GURL(chrome::kChromeUIHelloWorldURL);
}

void HelloWorldDialog::GetWebUIMessageHandlers(
    std::vector<WebUIMessageHandler*>* handlers) const {
}

void HelloWorldDialog::GetDialogSize(gfx::Size* size) const {
  size->SetSize(600, 400);
}

std::string HelloWorldDialog::GetDialogArgs() const {
  return std::string();
}

void HelloWorldDialog::OnDialogClosed(const std::string& json_retval) {
  delete this;
}

void HelloWorldDialog::OnCloseContents(TabContents* source,
    bool* out_close_dialog) {
  if (out_close_dialog)
    *out_close_dialog = true;
}

bool HelloWorldDialog::ShouldShowDialogTitle() const {
  return true;
}

你需要通过HelloWroldDialog::ShowDialog来创建一个新的dialog。

传递参数给WebUI

你可能猜到HtmlDialogUIDelegate::GetDialogArgs()函数是用来传递参数给对话框页的。例如,如果我们希望显示一个自定义的消息给用户,这个自定义消息是在创建对话框时传递给它,并由GetDialogArgs返回,并在javascript中通过chrome.dialogArguments来返回。例子如下:

src/chrome/browser/ui/webui/hello_world.h
 
-   static void ShowDialog();
+   static void ShowDialog(std::string message);

+   // The message to be displayed to the user.
+   std::string message_;
+
    DISALLOW_COPY_AND_ASSIGN(HelloWorldDialog);
  };


src/chrome/browser/ui/webui/hello_world.cc
 
- HelloWorldDialog::HelloWorldDialog() {
+ HelloWorldDialog::HelloWorldDialog(std::string message)
+     : message_(message) {
  }


  std::string HelloWorldDialog::GetDialogArgs() const {
-   return std::string();
+   return message_;
  }


src/chrome/browser/resources/hello_world.js:
 
    function initialize() {
+     document.getElementsByTagName('p')[0].textContent = chrome.dialogArguments;
    }

实际上,你可以传递一个结构体给你的WebUI。你可以通过base::JSONWriter来产生一个JSON字符串,在javascript端通过JSON.parse(chrome.dialogArguments)获得这个参数。

例子待序.....


创建Chromium WebUI接口的更多相关文章

  1. 更改VisualStudio默认创建类和接口不加public问题

    由于VisualStudio创建类和接口时,默认的是不加public关键字的,而我们大多数时候创建的类都是public的,于是,为了更好工作觉得改之. 首先找到在VisualStudio安装目录下路径 ...

  2. day114:MoFang:基于支付宝沙箱测试环境完成创建充值订单接口&服务端处理支付结果的同步通知和异步通知

    目录 1.基于支付宝提供的沙箱测试环境开发支付接口 1.后端提供创建充值订单接口 2.前端调用AlipayPlus发起支付 3.注意:自定义APPLoader完成接下来的开发 4.下载支付宝沙箱钱包A ...

  3. Android开发10.1:UI组件适配器AdapterView(创建ListView,Adapter接口)

    @version:Android4.3 API18 @author:liuxinming 概述               AdapterView继承了ViewGroup,它的本质是容器       ...

  4. Zynq-PL中创建AXI Master接口IP及AXI4-Lite总线主从读写时序测试(转)

    转载:原文  http://www.eefocus.com/antaur/blog/17-08/423751_6cc0d.html 0. 引言 通过之前的学习,可以在PL端创建从机模式的AXI接口IP ...

  5. Unity3D学习笔记4——创建Mesh高级接口

    目录 1. 概述 2. 详论 3. 其他 4. 参考 1. 概述 在文章Unity3D学习笔记2--绘制一个带纹理的面中使用代码的方式创建了一个Mesh,不过这套接口在Unity中被称为简单接口.与其 ...

  6. Elasticsearch:创建 API key 接口访问 Elasticsearch

    转载自:https://blog.csdn.net/UbuntuTouch/article/details/107181440 在之前我的文章 "Elastic:使用Postman来访问El ...

  7. 采用CXF+spring+restful创建一个web接口项目

    这篇文章是http://blog.csdn.net/zxnlmj/article/details/28880303下面,加入的基础上的restful特征 1.参加restful必jar包裹 jsr31 ...

  8. Android studio无法创建类和接口问题解决办法。提示 Unable to parse template "Class"

    重新配置了studio 的工作环境, 没问题,后来加需求要新增java类和接口,这就出现问题了,新建的时候,就会报错: Unable to parse template "Interface ...

  9. UVM:8.4.3 用factory 机制创建实例的接口

    1.create_object_by_name,依据类名字创建object,原型: 一般仅仅用第一个: 2.create_object_by_type.依据类型创建一个object,原型: 一般仅仅用 ...

随机推荐

  1. IE下判断IE版本的语句

    <!--[if lte IE 6]> <![endif]--> IE6及其以下版本可见   <!--[if lte IE 7]> <![endif]--> ...

  2. Android Studio中常用设置与快捷键

    常用设置: 1.Tab不用4个空格Code Style->Java->Tabs and Indents->Use tab characterCode Style->Genera ...

  3. linux学习笔记<基本知识普及>

    linux上分区类型 主分区 : 最多自能有4个 扩展分区 :  最多只能有1个 主分区加扩展分区最多只能有4个 不能写入数据,只能包含逻辑分区 逻辑分区 挂载(安装linux系统时若自定义分区,需注 ...

  4. 华为S5300交换机配置基于VLAN的本地端口镜像

    配置思路 1.  将Ethernet0/0/20接口配置为观察端口(监控端口) 2.  将VLAN 1.11.12.13.14配置为镜像VLAN 配置步骤 1.  配置观察端口 <Switch& ...

  5. 关于iOS应用管理之九宫格的坐标计算以及与UIScrollView的结合

    关于九宫格的布局以及坐标的计算,对于大多数的iOS初学者甚至有一定能力的学者来说都是一大难题,在此写者通过自己的开发经验以及多次应用,把自己的所学所得分享给大家,就通过应用管理来进行浅谈一二.     ...

  6. 'Invalid update: invalid number of rows in section xx. The number of rows contained in an existing section after the update (xxx)...

    'Invalid update: invalid number of rows in section 5.  The number of rows contained in an existing s ...

  7. 武汉科技大学ACM :1010: 零起点学算法12——求2个日期之间的天数

    Problem Description 水题 Input 输入2个日期,日期按照年月日,年月日之间用符号-隔开(题目包含多组数据) Output 求出这2个日期之间的天数(不包括自身),每组测试数据一 ...

  8. Oracle数据库之创建表空间与用户

    Oracle数据库之创建表空间与用户 一.创建表空间 基本语法表述: CREATE TABLESPACE tablespace_name [DATAFILE datafile_spec1 [,data ...

  9. js获取url?后的参数

    function GetRequest() { var url = location.search; //获取url中"?"符后的字串 var theRequest = new O ...

  10. Input File 表单上传按钮美化

    HTML <div class="input-file-button"> 上传图片<input type="file" class=" ...