转载自: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="strings.js"></script>
<script src="hello_world.js"></script>
<h1 i18n-content="helloWorldTitle"></h1>
<p id="welcome-message"></p>
</body>
</html>
p {
white-space: pre-wrap;
}
cr.define('hello_world', function() {
'use strict';
/**
* Be polite and insert translated hello world strings for the user on loading.
*/
function initialize() {
}
// Return an object with all of the exports.
return {
initialize: initialize,
};
});
document.addEventListener('DOMContentLoaded', hello_world.initialize);
+ <include name="IDR_HELLO_WORLD_HTML" file="resourceshello_world.html" type="BINDATA" />
+ <include name="IDR_HELLO_WORLD_CSS" file="resourceshello_world.css" type="BINDATA" />
+ <include name="IDR_HELLO_WORLD_JS" file="resourceshello_world.js" type="BINDATA" />
添加URL标识到新的Chrome URL中
+ extern const char kChromeUIHelloWorldURL[];
...
+ extern const char kChromeUIHelloWorldHost[];
+ const char kChromeUIHelloWorldURL[] = "chrome://hello-world/";
...
+ const char kChromeUIHelloWorldHost[] = "hello-world";
添加本地字符串
+ <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继承)
#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();
DISALLOW_COPY_AND_ASSIGN(HelloWorldUI);
};
#endif //
CHROME_BROWSER_UI_WEBUI_HELLO_WORLD_UI_H_
#include "chrome/browser/ui/webui/hello_world_ui.h"
#include "chrome/browser/profiles/profile.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文件中
'sources': [
...
+ 'browser/ui/webui/hello_world_ui.cc',
+ 'browser/ui/webui/hello_world_ui.h',
添加WebUI请求到Chrome WebUI工厂
WebUI的工厂负责响应并创建你的请求
+ #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引擎的两个整数相加(因为我们知道,它内部是使用浮点数的)。我们可以增加回调句柄来处理我们的整数运算。
#include "chrome/browser/ui/webui/chrome_web_ui.h"
+
+ namespace base {
+ } // namespace base
...
// Set up the chrome://hello-world source.
ChromeWebUIDataSource* html_source =
new ChromeWebUIDataSource(chrome::kChromeUIHelloWorldHost);
+
+ // Register callback handler.
+ RegisterMessageCallback("addNumbers",
// Localized strings.
...
virtual ~HelloWorldUI();
+
+ private:
+ // Add two numbers together using integer arithmetic.
+ void AddNumbers(const base::ListValue* args);
DISALLOW_COPY_AND_ASSIGN(HelloWorldUI);
};
#include "chrome/browser/ui/webui/hello_world_ui.h"
+
+ #include "base/values.h"
#include "chrome/browser/profiles/profile.h"
...
}
+
+ 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);
+ }
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
- #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
#ifndef CHROME_BROWSER_UI_WEBUI_HELLO_WORLD_H_
#define
CHROME_BROWSER_UI_WEBUI_HELLO_WORLD_H_
#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_
#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来返回。例子如下:
- 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);
};
- HelloWorldDialog::HelloWorldDialog() {
+ : message_(message) {
}
- return std::string();
+ return message_;
}
+ document.getElementsByTagName('p')[0].textContent = chrome.dialogArguments;
}
实际上,你可以传递一个结构体给你的WebUI。你可以通过base::JSONWriter来产生一个JSON字符串,在javascript端通过JSON.parse(chrome.dialogArguments)获得这个参数。
例子待序.....