GRIT
Google Resource and Internationalization Tool
Lu Yuan
2014-8-1
heX 遇到的问题
打包
HTML CSS JavaScript Image Data...
档案文件: zip, 7z, tar...
-
解压到硬盘通过本地路径或者自定义协议读取
-
解压到内存通过自定义协议读取
追加至可执行文件中
不太现实!!!
Chromium 是如何解决的
Chromium 中包含大量的 web 资源。
除了任务管理器以外的窗口几乎全部使用 web 前端渲染。
它们在哪?
resources.pak。
Chromium 如何读取资源
1. 准备 GRD 文件 (构建期)
<?xml version="1.0" encoding="UTF-8"?><grit current_release="1" latest_public_release="0">
<outputs>
<output filename="grit/devtools_resources.h" type="rc_header">
<emit emit_type="prepend"/>
</output>
<output filename="grit/devtools_resources_map.cc" type="resource_file_map_source"/>
<output filename="grit/devtools_resources_map.h" type="resource_map_header"/>
<output filename="devtools_resources.pak" type="data_package"/>
</outputs>
<release seq="1">
<includes>
<include file="devtools.html" name="DEVTOOLS_HTML" type="BINDATA"/>
<include file="inspector.js" name="INSPECTOR_JS" type="BINDATA"/>
<include file="ElementsPanel.js" name="ELEMENTSPANEL_JS" type="BINDATA"/>
<include file="ResourcesPanel.js" name="RESOURCESPANEL_JS" type="BINDATA"/>
<include file="NetworkPanel.js" name="NETWORKPANEL_JS" type="BINDATA"/>
<include file="ScriptsPanel.js" name="SCRIPTSPANEL_JS" type="BINDATA"/>
<include file="TimelinePanel.js" name="TIMELINEPANEL_JS" type="BINDATA"/>
<include file="ProfilesPanel.js" name="PROFILESPANEL_JS" type="BINDATA"/>
<include file="AuditsPanel.js" name="AUDITSPANEL_JS" type="BINDATA"/>
<include file="LayersPanel.js" name="LAYERSPANEL_JS" type="BINDATA"/>
<include file="CodeMirrorTextEditor.js" name="CODEMIRRORTEXTEDITOR_JS" type="BINDATA"/>
......
变态!连 GRD 都要脚本生成Chromium 如何读取资源
2. grit 生成 pak, h... (编译期)
- grit 命令传入参数生成目标文件
(包括 resource id)
- 将多个 pak 文件合并
- 将合并后的文件复制到目标目录
'actions': [
{
'action_name': 'devtools_resources',
# This can't use build/grit_action.gypi because the grd file
# is generated at build time, so the trick of using grit_info to get
# the real inputs/outputs at GYP time isn't possible.
'variables': {
'grit_cmd': ['python', '../../../tools/grit/grit.py'],
'grit_grd_file': '<(SHARED_INTERMEDIATE_DIR)/devtools/devtools_resources.grd',
},
'inputs': [
'<(grit_grd_file)',
'<!@pymod_do_main(grit_info --inputs)',
],
'outputs': [
'<(grit_out_dir)/grit/devtools_resources.h',
'<(grit_out_dir)/devtools_resources.pak',
'<(grit_out_dir)/grit/devtools_resources_map.cc',
'<(grit_out_dir)/grit/devtools_resources_map.h',
],
'action': ['<@(grit_cmd)',
'-i', '<(grit_grd_file)', 'build',
'-f', 'GRIT_DIR/../gritsettings/resource_ids',
'-o', '<(grit_out_dir)',
'-D', 'SHARED_INTERMEDIATE_DIR=<(SHARED_INTERMEDIATE_DIR)',
'<@(grit_defines)' ],
'message': 'Generating resources from <(grit_grd_file)',
'msvs_cygwin_shell': 1,
}
],
Chromium 如何读取资源
3. 根据 h 文件从 pak 文件中读取资源内容 (运行期)
- 解析 URL (chrome://xxx/index.html)
- 获取 resource id
- 根据 resource id 读取资源内容 (memory mapping)
- 判断 MIME type
- 设置 stream
- ...
Chromium 如何读取资源
4. 支持模板
<div id="logo">
<div id="company"><img src="hex_logo.png" /></div>
<div id="copyright">Copyright © $$YEAR$$ NetEase Youdao Inc. and other heX contributors.<br/>All rights reserved.<br/><a href="chrome://license">license</a> | <a href="chrome://credits">credits</a></div>
</div>
<table id="inner" cellpadding="0" cellspacing="0" border="0">
<tr>
<td class="label" valign="top">heX</td>
<td class="value">$$HEX$$</td>
</tr>
<tr>
<td class="label" valign="top">Node.js</td>
<td class="value">$$NODE$$</td>
</tr>
<tr>
<td class="label" valign="top">CEF</td>
<td class="value">$$CEF$$</td>
</tr>
<tr>
<td class="label" valign="top">Chromium</td>
<td class="value">$$CHROMIUM$$</td>
...
parser.Add("HEX",
base::StringPrintf("%d.%d.%d-%s",
HEX_VERSION_MAJOR,
HEX_VERSION_MINOR,
HEX_VERSION_BUILD,
HEX_REVISION));
if (hex::CanUseNode()) {
parser.Add("NODE", base::StringPrintf("%s", NODE_VERSION_STRING));
} else {
parser.Add("NODE", base::StringPrintf("%s", "Not found"));
}
Resource id 从何而来
src/tools/gritsettings/resource_ids
{
"SRCDIR": "../..",
"cef/libcef/resources/cef_resources.grd": {
"includes": [27500],
},
"cef/libcef/resources/cef_strings.grd": {
"messages": [28000],
},
"hex/src/resources/hex_resources.grd": {
"includes": [100],
},
"hex/web_resources/web_resources.grd": {
"includes": [50000],
},
"chrome/browser/browser_resources.grd": {
"includes": [500],
"structures": [750],
},
"chrome/browser/resources/component_extension_resources.grd": {
"includes": [1000],
"structures": [1450],
},
"chrome/browser/resources/net_internals_resources.grd": {
"includes": [1500],
},
"ui/webui/resources/webui_resources.grd": {
"includes": [2000],
"structures": [2200],
},
"chrome/common/common_resources.grd": {
"includes": [2500],
},
"chrome/renderer/resources/renderer_resources.grd": {
"includes": [3500],
"structures": [3700],
},
"net/base/net_resources.grd": {
"includes": [4000],
},
"ui/resources/ui_unscaled_resources.grd": {
"includes": [4500],
},
"webkit/glue/resources/webkit_resources.grd": {
"structures": [4700],
},
"webkit/tools/test_shell/test_shell_resources.grd": {
"includes": [5000],
},
"ui/resources/ui_resources.grd": {
"structures": [5500],
},
"ash/resources/ash_resources.grd": {
"includes": [6100],
"structures": [6150],
},
"chrome/app/theme/theme_resources.grd": {
"structures": [6500],
},
"chrome/app/theme/chrome_unscaled_resources.grd": {
"includes": [7500],
},
"chrome_frame/resources/chrome_frame_resources.grd": {
"includes": [8000],
},
"ui/base/strings/app_locale_settings.grd": {
"messages": [9000],
},
"chrome/app/resources/locale_settings.grd": {
"includes": [9500],
"messages": [10000],
},
# These each start with the same resource id because we only use one
# file for each build (chromiumos, google_chromeos, linux, mac, or win).
"chrome/app/resources/locale_settings_chromiumos.grd": {
"messages": [10500],
},
"chrome/app/resources/locale_settings_google_chromeos.grd": {
"messages": [10500],
},
"chrome/app/resources/locale_settings_linux.grd": {
"messages": [10500],
},
"chrome/app/resources/locale_settings_mac.grd": {
"messages": [10500],
},
"chrome/app/resources/locale_settings_win.grd": {
"messages": [10500],
},
"ui/base/strings/ui_strings.grd": {
"messages": [11000],
},
# Chromium strings and Google Chrome strings must start at the same id.
# We only use one file depending on whether we're building Chromium or
# Google Chrome.
"chrome/app/chromium_strings.grd": {
"messages": [11500],
},
"chrome/app/google_chrome_strings.grd": {
"messages": [11500],
},
# Leave lots of space for generated_resources since it has most of our
# strings.
"chrome/app/generated_resources.grd": {
"structures": [12000],
"messages": [12500],
},
# The chrome frame dialogs are also in generated_resources.grd so they
# get included by the translation console. We make sure that the ids
# for structures here are the same as for generated_resources.grd.
"chrome_frame/resources/chrome_frame_dialogs.grd": {
"structures": [12000],
"includes": [12250],
},
"webkit/glue/inspector_strings.grd": {
"messages": [17500],
},
"webkit/glue/webkit_strings.grd": {
"messages": [18000],
},
"chrome_frame/resources/chrome_frame_resources.grd": {
"includes": [19000],
"structures": [19500],
},
"ui/base/native_theme/resources/native_theme_resources.grd": {
"includes": [20000],
},
"chrome/app/policy/policy_templates.grd": {
"structures": [20500],
"messages": [20510],
},
"chrome/browser/autofill/autofill_resources.grd": {
"messages": [21000],
},
"chrome/browser/resources/sync_internals_resources.grd": {
"includes": [21500],
},
"chrome/browser/resources/signin_internals_resources.grd": {
"includes": [21750],
},
# This file is generated during the build.
# devtools_resources.grd can be in two different places depending on whether
# we are in a chromium checkout or a webkit-only checkout.
"<(SHARED_INTERMEDIATE_DIR)/devtools/devtools_resources.grd": {
"includes": [22000],
},
"devtools_resources.grd": {
"includes": [22000],
},
# This file is generated during the build.
"chrome/browser/devtools/frontend/devtools_discovery_page_resources.grd": {
"includes": [22500],
},
"chrome/browser/resources/options_resources.grd": {
"includes": [23000],
},
"chrome/browser/resources/options_resources.grd": {
"structures": [23200],
},
"cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd": {
"messages": [23500],
"includes": [23550],
},
"cloud_print/service/win/service_resources.grd": {
"messages": [23600],
"includes": [23800],
"structures": [23900],
},
"chrome/browser/resources/quota_internals_resources.grd": {
"includes": [24000],
},
"content/content_resources.grd": {
"includes": [25000],
},
"content/shell/shell_resources.grd": {
"includes": [25500],
},
# This file is generated during the build.
"<(SHARED_INTERMEDIATE_DIR)/content/browser/tracing/tracing_resources.grd": {
"includes": [25750],
},
"ash/ash_strings.grd": {
"messages": [26000],
},
"chrome/common/extensions_api_resources.grd": {
"includes": [26500],
},
"third_party/trace-viewer/src/tracing.grd": {
"includes": [27000],
},
"chrome/browser/resources/memory_internals_resources.grd": {
"includes": [27500],
},
"device/bluetooth/bluetooth_strings.grd": {
"messages": [28000],
},
"ui/keyboard/keyboard_resources.grd": {
"includes": [28050],
},
"chrome/browser/resources/translate_internals_resources.grd": {
"includes": [28500],
},
"chrome/browser/resources/sync_file_system_internals_resources.grd": {
"includes": [29000],
},
"components/component_strings.grd": {
"messages": [30000],
},
"third_party/WebKit/public/blink_resources.grd": {
"includes": [30500],
},
# Resource ids starting at 31000 are reserved for projects built on Chromium.
}
Messages 是什么?
i18n
- src/chrome/app/chromium_strings.grd
- src/chrome/app/google_chrome_strings.grd
- src/chrome/app/generated_resources.grd
- resources/generated_resources_zh-CN.xtb
- ...
52 XTBs
GRD ---------------- PAK
heX 的解决方案
- 对 grit 稍作修改增加输出 JSON 资源文件功能
{ "index.html": 50000, "js/main.js": 50001 } - 用 grit 同时生成 JSON 及 PAK 文件
- 启动后注册 chrome 协议的时候解析 JSON
- Request URL 是根据 path 找到 resource id
- 通过 resource id 找到资源内容
- ...
乌玵完
谢谢大家!
GRIT
By luyuan
GRIT
- 3,127