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"); }
// Instances a single text element containing a string. bool Factory::InstanceElementText(Element* parent, const String& text) { SystemInterface* system_interface = GetSystemInterface(); // Do any necessary translation. If any substitutions were made then new XML may have been introduced, so we'll // have to run the data through the XML parser again. String translated_data; if (system_interface != NULL && (system_interface->TranslateString(translated_data, text) > 0 || translated_data.Find("<") != String::npos)) { StreamMemory* stream = new StreamMemory(translated_data.Length() + 32); stream->Write("<body>", 6); stream->Write(translated_data); stream->Write("</body>", 7); stream->Seek(0, SEEK_SET); InstanceElementStream(parent, stream); stream->RemoveReference(); } else { // Check if this text node contains only white-space; if so, we don't want to construct it. bool only_white_space = true; for (size_t i = 0; i < translated_data.Length(); ++i) { if (!StringUtilities::IsWhitespace(translated_data[i])) { only_white_space = false; break; } } if (only_white_space) return true; // Attempt to instance the element. XMLAttributes attributes; Element* element = Factory::InstanceElement(parent, "#text", "#text", attributes); if (!element) { Log::Message(Log::LT_ERROR, "Failed to instance text element '%s', instancer returned NULL.", translated_data.CString()); return false; } // Assign the element its text value. ElementText* text_element = dynamic_cast< ElementText* >(element); if (text_element == NULL) { Log::Message(Log::LT_ERROR, "Failed to instance text element '%s'. Found type '%s', was expecting a derivative of ElementText.", translated_data.CString(), typeid(element).name()); element->RemoveReference(); return false; } text_element->SetText(translated_data); // Add to active node. parent->AppendChild(element); element->RemoveReference(); } return true; }