1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // A helper function for using JsTemplate. See jstemplate_builder.h for more
6 // info.
7
8 #include "chrome/common/jstemplate_builder.h"
9
10 #include "base/logging.h"
11 #include "base/string_util.h"
12 #include "content/common/json_value_serializer.h"
13 #include "grit/common_resources.h"
14 #include "ui/base/resource/resource_bundle.h"
15
16 namespace jstemplate_builder {
17
GetTemplateHtml(const base::StringPiece & html_template,const DictionaryValue * json,const base::StringPiece & template_id)18 std::string GetTemplateHtml(const base::StringPiece& html_template,
19 const DictionaryValue* json,
20 const base::StringPiece& template_id) {
21 std::string output(html_template.data(), html_template.size());
22 AppendJsonHtml(json, &output);
23 AppendJsTemplateSourceHtml(&output);
24 AppendJsTemplateProcessHtml(template_id, &output);
25 return output;
26 }
27
GetI18nTemplateHtml(const base::StringPiece & html_template,const DictionaryValue * json)28 std::string GetI18nTemplateHtml(const base::StringPiece& html_template,
29 const DictionaryValue* json) {
30 std::string output(html_template.data(), html_template.size());
31 AppendJsonHtml(json, &output);
32 AppendI18nTemplateSourceHtml(&output);
33 AppendI18nTemplateProcessHtml(&output);
34 return output;
35 }
36
GetTemplatesHtml(const base::StringPiece & html_template,const DictionaryValue * json,const base::StringPiece & template_id)37 std::string GetTemplatesHtml(const base::StringPiece& html_template,
38 const DictionaryValue* json,
39 const base::StringPiece& template_id) {
40 std::string output(html_template.data(), html_template.size());
41 AppendI18nTemplateSourceHtml(&output);
42 AppendJsTemplateSourceHtml(&output);
43 AppendJsonHtml(json, &output);
44 AppendI18nTemplateProcessHtml(&output);
45 AppendJsTemplateProcessHtml(template_id, &output);
46 return output;
47 }
48
AppendJsonHtml(const DictionaryValue * json,std::string * output)49 void AppendJsonHtml(const DictionaryValue* json, std::string* output) {
50 // Convert the template data to a json string.
51 DCHECK(json) << "must include json data structure";
52
53 std::string jstext;
54 JSONStringValueSerializer serializer(&jstext);
55 serializer.Serialize(*json);
56 // </ confuses the HTML parser because it could be a </script> tag. So we
57 // replace </ with <\/. The extra \ will be ignored by the JS engine.
58 ReplaceSubstringsAfterOffset(&jstext, 0, "</", "<\\/");
59
60 output->append("<script>");
61 output->append("var templateData = ");
62 output->append(jstext);
63 output->append(";");
64 output->append("</script>");
65 }
66
AppendJsTemplateSourceHtml(std::string * output)67 void AppendJsTemplateSourceHtml(std::string* output) {
68 // fetch and cache the pointer of the jstemplate resource source text.
69 static const base::StringPiece jstemplate_src(
70 ResourceBundle::GetSharedInstance().GetRawDataResource(
71 IDR_JSTEMPLATE_JS));
72
73 if (jstemplate_src.empty()) {
74 NOTREACHED() << "Unable to get jstemplate src";
75 return;
76 }
77
78 output->append("<script>");
79 output->append(jstemplate_src.data(), jstemplate_src.size());
80 output->append("</script>");
81 }
82
AppendJsTemplateProcessHtml(const base::StringPiece & template_id,std::string * output)83 void AppendJsTemplateProcessHtml(const base::StringPiece& template_id,
84 std::string* output) {
85 output->append("<script>");
86 output->append("var tp = document.getElementById('");
87 output->append(template_id.data(), template_id.size());
88 output->append("');");
89 output->append("jstProcess(new JsEvalContext(templateData), tp);");
90 output->append("</script>");
91 }
92
AppendI18nTemplateSourceHtml(std::string * output)93 void AppendI18nTemplateSourceHtml(std::string* output) {
94 // fetch and cache the pointer of the jstemplate resource source text.
95 static const base::StringPiece i18n_template_src(
96 ResourceBundle::GetSharedInstance().GetRawDataResource(
97 IDR_I18N_TEMPLATE_JS));
98
99 if (i18n_template_src.empty()) {
100 NOTREACHED() << "Unable to get i18n template src";
101 return;
102 }
103
104 output->append("<script>");
105 output->append(i18n_template_src.data(), i18n_template_src.size());
106 output->append("</script>");
107 }
108
AppendI18nTemplateProcessHtml(std::string * output)109 void AppendI18nTemplateProcessHtml(std::string* output) {
110 output->append("<script>");
111 output->append("i18nTemplate.process(document, templateData);");
112 output->append("</script>");
113 }
114
115 } // namespace jstemplate_builder
116