106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Use of this source code is governed by a BSD-style license that can be
306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// found in the LICENSE file.
406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// A helper function for using JsTemplate. See jstemplate_builder.h for more
606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// info.
706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/common/jstemplate_builder.h"
906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/logging.h"
1106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/string_util.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/json_value_serializer.h"
1306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "grit/common_resources.h"
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
1506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochnamespace jstemplate_builder {
1706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochstd::string GetTemplateHtml(const base::StringPiece& html_template,
1906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                            const DictionaryValue* json,
2006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                            const base::StringPiece& template_id) {
2106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string output(html_template.data(), html_template.size());
2206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendJsonHtml(json, &output);
2306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendJsTemplateSourceHtml(&output);
2406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendJsTemplateProcessHtml(template_id, &output);
2506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return output;
2606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
2706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochstd::string GetI18nTemplateHtml(const base::StringPiece& html_template,
2906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                const DictionaryValue* json) {
3006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string output(html_template.data(), html_template.size());
3106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendJsonHtml(json, &output);
3206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendI18nTemplateSourceHtml(&output);
3306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendI18nTemplateProcessHtml(&output);
3406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return output;
3506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
3606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
3706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochstd::string GetTemplatesHtml(const base::StringPiece& html_template,
3806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                             const DictionaryValue* json,
3906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                             const base::StringPiece& template_id) {
4006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string output(html_template.data(), html_template.size());
4106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendI18nTemplateSourceHtml(&output);
4206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendJsTemplateSourceHtml(&output);
4306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendJsonHtml(json, &output);
4406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendI18nTemplateProcessHtml(&output);
4506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AppendJsTemplateProcessHtml(template_id, &output);
4606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return output;
4706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
4806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
4906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochvoid AppendJsonHtml(const DictionaryValue* json, std::string* output) {
5006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Convert the template data to a json string.
5106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  DCHECK(json) << "must include json data structure";
5206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
5306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string jstext;
5406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  JSONStringValueSerializer serializer(&jstext);
5506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  serializer.Serialize(*json);
5606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // </ confuses the HTML parser because it could be a </script> tag.  So we
5706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // replace </ with <\/.  The extra \ will be ignored by the JS engine.
5806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  ReplaceSubstringsAfterOffset(&jstext, 0, "</", "<\\/");
5906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("<script>");
6106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("var templateData = ");
6206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append(jstext);
6306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append(";");
6406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("</script>");
6506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
6606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochvoid AppendJsTemplateSourceHtml(std::string* output) {
6806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // fetch and cache the pointer of the jstemplate resource source text.
6906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const base::StringPiece jstemplate_src(
7006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
7106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch          IDR_JSTEMPLATE_JS));
7206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (jstemplate_src.empty()) {
7406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    NOTREACHED() << "Unable to get jstemplate src";
7506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return;
7606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
7706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("<script>");
7906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append(jstemplate_src.data(), jstemplate_src.size());
8006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("</script>");
8106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
8206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
8306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochvoid AppendJsTemplateProcessHtml(const base::StringPiece& template_id,
8406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                 std::string* output) {
8506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("<script>");
8606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("var tp = document.getElementById('");
8706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append(template_id.data(), template_id.size());
8806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("');");
8906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("jstProcess(new JsEvalContext(templateData), tp);");
9006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("</script>");
9106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
9206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochvoid AppendI18nTemplateSourceHtml(std::string* output) {
9406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // fetch and cache the pointer of the jstemplate resource source text.
9506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const base::StringPiece i18n_template_src(
9606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
9706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch          IDR_I18N_TEMPLATE_JS));
9806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (i18n_template_src.empty()) {
10006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    NOTREACHED() << "Unable to get i18n template src";
10106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return;
10206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
10306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
10406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("<script>");
10506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append(i18n_template_src.data(), i18n_template_src.size());
10606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("</script>");
10706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
10806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
10906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochvoid AppendI18nTemplateProcessHtml(std::string* output) {
11006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("<script>");
11106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("i18nTemplate.process(document, templateData);");
11206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  output->append("</script>");
11306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
11406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
11506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}  // namespace jstemplate_builder
116