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
16namespace jstemplate_builder {
17
18std::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
28std::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
37std::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
49void 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
67void 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
83void 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
93void 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
109void 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