Skip to content

Commit

Permalink
Scripts and RCSS are now loaded in declared order, regardless of whet…
Browse files Browse the repository at this point in the history
…her they are inline or external (#144)
  • Loading branch information
actboy168 authored Nov 11, 2020
1 parent ccc82a0 commit b8ef1e0
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 71 deletions.
14 changes: 10 additions & 4 deletions Include/RmlUi/Core/ElementDocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,17 @@ class RMLUICORE_API ElementDocument : public Element
/// @return True if the document is hogging focus.
bool IsModal() const;

/// Load a script into the document. Note that the base implementation does nothing, scripting language addons hook
/// Load a inline script into the document. Note that the base implementation does nothing, scripting language addons hook
/// this method.
/// @param[in] stream Stream of code to process.
/// @param[in] source_name Name of the the script the source comes from, useful for debug information.
virtual void LoadScript(Stream* stream, const String& source_name);
/// @param[in] content The script content.
/// @param[in] source_path Path of the script the source comes from, useful for debug information.
/// @param[in] source_line Line of the script the source comes from, useful for debug information.
virtual void LoadInlineScript(const String& content, const String& source_path, int source_line);

/// Load a external script into the document. Note that the base implementation does nothing, scripting language addons hook
/// this method.
/// @param[in] source_path The script file path.
virtual void LoadExternalScript(const String& source_path);

/// Updates the document, including its layout. Users must call this manually before requesting information such as
/// size or position of an element if any element in the document was recently changed, unless Context::Update has
Expand Down
14 changes: 7 additions & 7 deletions Source/Core/DocumentHeader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,10 @@ void DocumentHeader::MergeHeader(const DocumentHeader& header)
if (source.empty())
source = header.source;

// Combine internal data
rcss_inline.insert(rcss_inline.end(), header.rcss_inline.begin(), header.rcss_inline.end());
rcss_inline_line_numbers.insert(rcss_inline_line_numbers.end(), header.rcss_inline_line_numbers.begin(), header.rcss_inline_line_numbers.end());
scripts_inline.insert(scripts_inline.end(), header.scripts_inline.begin(), header.scripts_inline.end());

// Combine external data, keeping relative paths
MergePaths(template_resources, header.template_resources, header.source);
MergePaths(rcss_external, header.rcss_external, header.source);
MergePaths(scripts_external, header.scripts_external, header.source);
MergeResources(rcss, header.rcss);
MergeResources(scripts, header.scripts);
}

void DocumentHeader::MergePaths(StringList& target, const StringList& source, const String& source_path)
Expand All @@ -65,4 +60,9 @@ void DocumentHeader::MergePaths(StringList& target, const StringList& source, co
}
}

void DocumentHeader::MergeResources(ResourceList& target, const ResourceList& source)
{
target.insert(target.end(), source.begin(), source.end());
}

} // namespace Rml
24 changes: 15 additions & 9 deletions Source/Core/DocumentHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,29 @@ class DocumentHeader
/// A list of template resources that can used while parsing the document
StringList template_resources;

/// Inline RCSS definitions
StringList rcss_inline;
LineNumberList rcss_inline_line_numbers;
/// External RCSS definitions that should be loaded
StringList rcss_external;
struct Resource {
String path; // Content path for inline resources, source path for external resources.
String content; // Only set for inline resources.
bool is_inline = false;
int line = 0; // Only set for inline resources.
};
using ResourceList = Vector<Resource>;

/// Inline script source
StringList scripts_inline;
/// External scripts that should be loaded
StringList scripts_external;
/// RCSS definitions
ResourceList rcss;

/// script source
ResourceList scripts;

/// Merges the specified header with this one
/// @param header Header to merge
void MergeHeader(const DocumentHeader& header);

/// Merges paths from one string list to another, preserving the base_path
void MergePaths(StringList& target, const StringList& source, const String& base_path);

/// Merges resources
void MergeResources(ResourceList& target, const ResourceList& source);
};

} // namespace Rml
Expand Down
80 changes: 51 additions & 29 deletions Source/Core/ElementDocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,28 +96,45 @@ void ElementDocument::ProcessHeader(const DocumentHeader* document_header)
// 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.
SharedPtr<StyleSheet> new_style_sheet;
if (header.rcss_external.size() > 0)
new_style_sheet = StyleSheetFactory::GetStyleSheet(header.rcss_external);

// Combine any inline sheets.
for (size_t i = 0; i < header.rcss_inline.size(); i++)
for (const DocumentHeader::Resource& rcss : header.rcss)
{
UniquePtr<StyleSheet> inline_sheet = MakeUnique<StyleSheet>();
auto stream = MakeUnique<StreamMemory>((const byte*)header.rcss_inline[i].c_str(), header.rcss_inline[i].size());
stream->SetSourceURL(document_header->source);
if (rcss.is_inline)
{
UniquePtr<StyleSheet> inline_sheet = MakeUnique<StyleSheet>();
auto stream = MakeUnique<StreamMemory>((const byte*)rcss.content.c_str(), rcss.content.size());
stream->SetSourceURL(rcss.path);

if (inline_sheet->LoadStyleSheet(stream.get(), rcss.line))
{
if (new_style_sheet)
{
SharedPtr<StyleSheet> combined_sheet = new_style_sheet->CombineStyleSheet(*inline_sheet);
new_style_sheet = combined_sheet;
}
else
new_style_sheet = std::move(inline_sheet);
}

if (inline_sheet->LoadStyleSheet(stream.get(), header.rcss_inline_line_numbers[i]))
stream.reset();
}
else
{
if (new_style_sheet)
SharedPtr<StyleSheet> sub_sheet = StyleSheetFactory::GetStyleSheet(rcss.path);
if (sub_sheet)
{
SharedPtr<StyleSheet> combined_sheet = new_style_sheet->CombineStyleSheet(*inline_sheet);
new_style_sheet = combined_sheet;
if (new_style_sheet)
{
SharedPtr<StyleSheet> combined_sheet = new_style_sheet->CombineStyleSheet(*sub_sheet);
new_style_sheet = std::move(combined_sheet);
}
else
new_style_sheet = sub_sheet;
}
else
new_style_sheet = std::move(inline_sheet);
Log::Message(Log::LT_ERROR, "Failed to load style sheet %s.", rcss.path.c_str());
}

stream.reset();
}

// If a style sheet is available, set it on the document and release it.
Expand All @@ -126,19 +143,17 @@ void ElementDocument::ProcessHeader(const DocumentHeader* document_header)
SetStyleSheet(std::move(new_style_sheet));
}

// Load external scripts.
for (size_t i = 0; i < header.scripts_external.size(); i++)
// Load scripts.
for (const DocumentHeader::Resource& script : header.scripts)
{
auto stream = MakeUnique<StreamFile>();
if (stream->Open(header.scripts_external[i]))
LoadScript(stream.get(), header.scripts_external[i]);
}

// Load internal scripts.
for (size_t i = 0; i < header.scripts_inline.size(); i++)
{
auto stream = MakeUnique<StreamMemory>((const byte*) header.scripts_inline[i].c_str(), header.scripts_inline[i].size());
LoadScript(stream.get(), "");
if (script.is_inline)
{
LoadInlineScript(script.content, script.path, script.line);
}
else
{
LoadExternalScript(script.path);
}
}

// Hide this document.
Expand Down Expand Up @@ -341,11 +356,18 @@ bool ElementDocument::IsModal() const
return modal && IsVisible();
}

// Default load script implementation
void ElementDocument::LoadScript(Stream* RMLUI_UNUSED_PARAMETER(stream), const String& RMLUI_UNUSED_PARAMETER(source_name))
// Default load inline script implementation
void ElementDocument::LoadInlineScript(const String& RMLUI_UNUSED_PARAMETER(content), const String& RMLUI_UNUSED_PARAMETER(source_path), int RMLUI_UNUSED_PARAMETER(line))
{
RMLUI_UNUSED(content);
RMLUI_UNUSED(source_path);
RMLUI_UNUSED(line);
}

// Default load external script implementation
void ElementDocument::LoadExternalScript(const String& RMLUI_UNUSED_PARAMETER(source_path))
{
RMLUI_UNUSED(stream);
RMLUI_UNUSED(source_name);
RMLUI_UNUSED(source_path);
}

// Updates the document, including its layout
Expand Down
36 changes: 31 additions & 5 deletions Source/Core/XMLNodeHandlerHead.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,31 @@

namespace Rml {

static String Absolutepath(const String& source, const String& base)
{
String joined_path;
::Rml::GetSystemInterface()->JoinPath(joined_path, StringUtilities::Replace(base, '|', ':'), StringUtilities::Replace(source, '|', ':'));
return StringUtilities::Replace(joined_path, ':', '|');
}

static DocumentHeader::Resource MakeInlineResource(XMLParser* parser, const String& data)
{
DocumentHeader::Resource resource;
resource.is_inline = true;
resource.content = data;
resource.path = parser->GetSourceURL().GetURL();
resource.line = parser->GetLineNumberOpenTag();
return resource;
}

static DocumentHeader::Resource MakeExternalResource(XMLParser* parser, const String& path)
{
DocumentHeader::Resource resource;
resource.is_inline = false;
resource.path = Absolutepath(path, parser->GetSourceURL().GetURL());
return resource;
}

XMLNodeHandlerHead::XMLNodeHandlerHead()
{
}
Expand Down Expand Up @@ -68,7 +93,7 @@ Element* XMLNodeHandlerHead::ElementStart(XMLParser* parser, const String& name,
if (type == "text/rcss" ||
type == "text/css")
{
parser->GetDocumentHeader()->rcss_external.push_back(href);
parser->GetDocumentHeader()->rcss.push_back(MakeExternalResource(parser, href));
}

// If its an template, add to the template fields
Expand All @@ -95,7 +120,7 @@ Element* XMLNodeHandlerHead::ElementStart(XMLParser* parser, const String& name,
String src = Get<String>(attributes, "src", "");
if (src.size() > 0)
{
parser->GetDocumentHeader()->scripts_external.push_back(src);
parser->GetDocumentHeader()->scripts.push_back(MakeExternalResource(parser, src));
}
}

Expand Down Expand Up @@ -134,13 +159,14 @@ bool XMLNodeHandlerHead::ElementData(XMLParser* parser, const String& data, XMLD

// Store an inline script
if (tag == "script" && data.size() > 0)
parser->GetDocumentHeader()->scripts_inline.push_back(data);
{
parser->GetDocumentHeader()->scripts.push_back(MakeInlineResource(parser, data));
}

// Store an inline style
if (tag == "style" && data.size() > 0)
{
parser->GetDocumentHeader()->rcss_inline.push_back(data);
parser->GetDocumentHeader()->rcss_inline_line_numbers.push_back(parser->GetLineNumberOpenTag());
parser->GetDocumentHeader()->rcss.push_back(MakeInlineResource(parser, data));
}

return true;
Expand Down
29 changes: 14 additions & 15 deletions Source/Lua/LuaDocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,21 @@ LuaDocument::LuaDocument(const String& tag) : ElementDocument(tag)
{
}

void LuaDocument::LoadScript(Stream* stream, const String& source_name)
void LuaDocument::LoadInlineScript(const String& context, const String& source_path, int source_line)
{
//if it is loaded from a file
if(!source_name.empty())
{
Interpreter::LoadFile(source_name);
}
else
{
String buffer;
buffer += "--";
buffer += this->GetSourceURL();
buffer += "\n";
stream->Read(buffer,stream->Length()); //just do the whole thing
Interpreter::DoString(buffer, buffer);
}
String buffer;
buffer += "--";
buffer += source_path;
buffer += ":";
buffer += Rml::ToString(source_line);
buffer += "\n";
buffer += context;
Interpreter::DoString(buffer, buffer);
}

void LuaDocument::LoadExternalScript(const String& source_path)
{
Interpreter::LoadFile(source_path);
}

} // namespace Lua
Expand Down
5 changes: 3 additions & 2 deletions Source/Lua/LuaDocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#ifndef RMLUI_LUA_LUADOCUMENT_H
#define RMLUI_LUA_LUADOCUMENT_H
/*
This class is an ElementDocument that overrides the LoadScript function
This class is an ElementDocument that overrides the LoadInlineScript and LoadExternalScript function
*/
#include <RmlUi/Core/ElementDocument.h>

Expand All @@ -40,7 +40,8 @@ class LuaDocument : public ::Rml::ElementDocument
{
public:
LuaDocument(const String& tag);
void LoadScript(Stream* stream, const String& source_name) override;
void LoadInlineScript(const String& content, const String& source_path, int source_line) override;
void LoadExternalScript(const String& source_path) override;
};

} // namespace Lua
Expand Down

0 comments on commit b8ef1e0

Please sign in to comment.