Template* TemplateCache::LoadTemplate(const String& name) { // Check if the template is already loaded Templates::iterator itr = instance->templates.find(name); if (itr != instance->templates.end()) return (*itr).second; // Nope, we better load it Template* new_template = NULL; StreamFile* stream = new StreamFile(); if (stream->Open(name)) { new_template = new Template(); if (!new_template->Load(stream)) { Log::Message(Log::LT_ERROR, "Failed to load template %s.", name.CString()); delete new_template; new_template = NULL; } else if (new_template->GetName().Empty()) { Log::Message(Log::LT_ERROR, "Failed to load template %s, template is missing its name.", name.CString()); delete new_template; new_template = NULL; } else { instance->templates[name] = new_template; instance->template_ids[new_template->GetName()] = new_template; } } else { Log::Message(Log::LT_ERROR, "Failed to open template file %s.", name.CString()); } stream->RemoveReference(); return new_template; }
void ElementDocument::ProcessHeader(const DocumentHeader* document_header) { // Store the source address that we came from source_url = document_header->source; // Construct a new header and copy the template details across DocumentHeader header; header.MergePaths(header.template_resources, document_header->template_resources, document_header->source); // Merge in any templates, note a merge may cause more templates to merge for (size_t i = 0; i < header.template_resources.size(); i++) { Template* merge_template = TemplateCache::LoadTemplate(URL(header.template_resources[i]).GetURL()); if (merge_template) header.MergeHeader(*merge_template->GetHeader()); else Log::Message(Log::LT_WARNING, "Template %s not found", header.template_resources[i].CString()); } // Merge the document's header last, as it is the most overriding. header.MergeHeader(*document_header); // Set the title to the document title. title = document_header->title; // If a style-sheet (or sheets) has been specified for this element, then we load them and set the combined sheet // on the element; all of its children will inherit it by default. StyleSheet* style_sheet = NULL; if (header.rcss_external.size() > 0) style_sheet = StyleSheetFactory::GetStyleSheet(header.rcss_external); // Combine any inline sheets. if (header.rcss_inline.size() > 0) { for (size_t i = 0;i < header.rcss_inline.size(); i++) { StyleSheet* new_sheet = new StyleSheet(); StreamMemory* stream = new StreamMemory((const byte*) header.rcss_inline[i].CString(), header.rcss_inline[i].Length()); stream->SetSourceURL(document_header->source); if (new_sheet->LoadStyleSheet(stream)) { if (style_sheet) { StyleSheet* combined_sheet = style_sheet->CombineStyleSheet(new_sheet); style_sheet->RemoveReference(); new_sheet->RemoveReference(); style_sheet = combined_sheet; } else style_sheet = new_sheet; } else new_sheet->RemoveReference(); stream->RemoveReference(); } } // If a style sheet is available, set it on the document and release it. if (style_sheet) { SetStyleSheet(style_sheet); style_sheet->RemoveReference(); } // Load external scripts. for (size_t i = 0; i < header.scripts_external.size(); i++) { StreamFile* stream = new StreamFile(); if (stream->Open(header.scripts_external[i])) LoadScript(stream, header.scripts_external[i]); stream->RemoveReference(); } // Load internal scripts. for (size_t i = 0; i < header.scripts_inline.size(); i++) { StreamMemory* stream = new StreamMemory((const byte*) header.scripts_inline[i].CString(), header.scripts_inline[i].Length()); LoadScript(stream, ""); stream->RemoveReference(); } // Hide this document. SetProperty(VISIBILITY, "hidden"); }