Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes script loading order. #144

Merged
merged 6 commits into from
Nov 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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