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