Skip to content

Commit

Permalink
Implemented inline injector.
Browse files Browse the repository at this point in the history
  • Loading branch information
5cript committed Oct 19, 2023
1 parent 640f35b commit 650cc4b
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 7 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ else()
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/tools/parcel_adapter)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/tools/patch_emscripten_config)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/tools/inline_parser)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/tools/inline_injector)
include(${CMAKE_CURRENT_LIST_DIR}/cmake/backend/common.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/cmake/backend/emscripten.cmake)
endif()
Expand Down
3 changes: 2 additions & 1 deletion cmake/backend/emscripten.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ function(nui_add_emscripten_target)
${EMCMAKE} cmake
${NUI_ADD_EMSCRIPTEN_TARGET_ARGS_CMAKE_OPTIONS}
-DNUI_INLINE_EXTRACTOR_TARGET_FILE=$<TARGET_FILE:inline-parser>
-DNUI_INLINE_INJECTOR_TARGET_FILE=$<TARGET_FILE:inline-injector>
"${SOURCE_DIR}"
# copy over package.json and fill parcel options that do not exist on it
${BUILD_COMMAND}
Expand All @@ -121,7 +122,7 @@ function(nui_add_emscripten_target)
BUILD_ALWAYS 1
BUILD_BYPRODUCTS "${CMAKE_BINARY_DIR}/module_${NUI_ADD_EMSCRIPTEN_TARGET_ARGS_TARGET}/bin/index.html"
INSTALL_COMMAND ""
DEPENDS inline-parser
DEPENDS inline-parser inline-injector parcel-adapter
)
add_dependencies(${NUI_ADD_EMSCRIPTEN_TARGET_ARGS_TARGET} ${NUI_ADD_EMSCRIPTEN_TARGET_ARGS_TARGET}-emscripten)
add_dependencies(${NUI_ADD_EMSCRIPTEN_TARGET_ARGS_TARGET}-emscripten bin2hpp)
Expand Down
15 changes: 10 additions & 5 deletions cmake/frontend/emscripten.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function(nui_prepare_emscripten_target)
cmake_parse_arguments(
NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS
"NO_INLINE"
"NO_INLINE;NO_INLINE_INJECT"
"TARGET;PREJS;STATIC;UNPACKED_MODE"
"EMSCRIPTEN_LINK_OPTIONS;EMSCRIPTEN_COMPILE_OPTIONS;PARCEL_ARGS"
${ARGN}
Expand All @@ -14,8 +14,16 @@ function(nui_prepare_emscripten_target)

nui_set_target_output_directories(${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_TARGET})

if (NOT NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_UNPACKED_MODE)
set(NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_UNPACKED_MODE off)
endif()

set(INLINER_COMMAND "")
if (NOT NO_INLINE)
nui_enable_inline(TARGET ${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_TARGET})
if (NOT NO_INLINE_INJECT)
set(INLINER_COMMAND COMMAND ${NUI_INLINE_INJECTOR_TARGET_FILE} "${CMAKE_BINARY_DIR}/static/index.html" "${CMAKE_BINARY_DIR}/nui-inline/inline_imports.js" "${CMAKE_BINARY_DIR}/nui-inline/inline_imports.css")
endif()
endif()

add_custom_target(
Expand All @@ -28,16 +36,13 @@ function(nui_prepare_emscripten_target)
${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_TARGET}-parcel
COMMAND ${CMAKE_COMMAND} -E copy_directory "${NUI_SOURCE_DIRECTORY}/nui/js" "${CMAKE_BINARY_DIR}/nui-js"
COMMAND ${CMAKE_COMMAND} -E copy_directory ${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_STATIC} "${CMAKE_BINARY_DIR}/static"
${INLINER_COMMAND}
COMMAND "${CMAKE_BINARY_DIR}/node_modules/.bin/parcel" build --dist-dir "${CMAKE_BINARY_DIR}/bin" ${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_PARCEL_ARGS}
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
BYPRODUCTS "${CMAKE_BINARY_DIR}/bin/index.html"
DEPENDS "${CMAKE_BINARY_DIR}/bin/index.js"
)

if (NOT NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_UNPACKED_MODE)
set(NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_UNPACKED_MODE off)
endif()

if (${NUI_PREPARE_EMSCRIPTEN_TARGET_ARGS_UNPACKED_MODE})
set(SINGLE_FILE_STRING "")
add_custom_target(
Expand Down
24 changes: 23 additions & 1 deletion cmake/inline_extractor.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function(nui_preprocess_inline_js)
endfunction()

function(nui_enable_inline)
set(one_value_args TARGET)
set(one_value_args TARGET UNPACKED_MODE)
set(multi_value_args)
cmake_parse_arguments(nui_enable_inline_ARGS "" "${one_value_args}" "${multi_value_args}" ${ARGN})

Expand Down Expand Up @@ -71,4 +71,26 @@ function(nui_enable_inline)
DEPENDS ${INLINE_IMPORTS_STYLES}
)
add_dependencies(${nui_enable_inline_ARGS_TARGET} nui-inline-${nui_enable_inline_ARGS_TARGET})

if (NOT nui_enable_inline_ARGS_UNPACKED_MODE)
set(nui_enable_inline_ARGS_UNPACKED_MODE off)
endif()

if (NOT ${nui_enable_inline_ARGS_UNPACKED_MODE})
add_custom_command(
OUTPUT
"${CMAKE_BINARY_DIR}/index_inserts.html"
COMMAND ${NUI_INLINE_INJECTOR_TARGET_FILE} "${CMAKE_BINARY_DIR}/module_${nui_enable_inline_ARGS_TARGET}/bin/index.html" ${INLINE_IMPORTS_SCRIPTS} ${INLINE_IMPORTS_STYLES}
DEPENDS
${INLINE_IMPORTS_SCRIPTS}
${INLINE_IMPORTS_STYLES}
"${CMAKE_BINARY_DIR}/module_${nui_enable_inline_ARGS_TARGET}/bin/index.html"
)

add_custom_target(
nui-inline-inject-${nui_enable_inline_ARGS_TARGET}
ALL
DEPENDS "${CMAKE_BINARY_DIR}/index_inserts.html"
)
endif()
endfunction()
11 changes: 11 additions & 0 deletions tools/inline_injector/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.16)

project(inline-injector VERSION 0.1.0)

add_executable(inline-injector main.cpp)
target_compile_features(inline-injector PRIVATE cxx_std_20)

set_target_properties(inline-injector
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tools_bin"
)
86 changes: 86 additions & 0 deletions tools/inline_injector/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <iostream>
#include <fstream>
#include <string>
#include <filesystem>

std::string readFile(const std::filesystem::path& path)
{
std::ifstream file{path, std::ios_base::binary};
if (!file)
{
throw std::runtime_error{"Could not open " + path.string()};
}

file.seekg(0, std::ios::end);
std::string content;
content.resize(file.tellg());
file.seekg(0, std::ios::beg);
file.read(&content[0], content.size());
return content;
}

int main(int argc, char** argv)
{
if (argc != 4)
{
std::cout << "Expected 3 argument: <index.html> <import_scripts> <import_styles>, but got " << argc - 1 << "\n";
return 1;
}

const auto index = std::filesystem::path{argv[1]};
const auto importScripts = std::filesystem::path{argv[2]};
const auto importStyles = std::filesystem::path{argv[3]};

std::string indexHtml;
try
{
indexHtml = readFile(index);
}
catch (const std::exception& e)
{
std::cout << "Error reading file: " << e.what() << "\n";
return 1;
}

// make relative path of import scripts to index file:
const auto relativeImportScriptsFile = std::filesystem::relative(importScripts, index.parent_path());
const auto relativeImportStylesFile = std::filesystem::relative(importStyles, index.parent_path());
const auto binIndex =
std::filesystem::relative(index.parent_path() / ".." / "bin" / "index.js", index.parent_path());

const std::string importScriptsHtml = "\t<script type=\"module\" defer>\n\t\timport \"" +
relativeImportScriptsFile.generic_string() + "\";\n</script>\n";
const std::string importStylesHtml =
"\t<style>\n\t\t@import \"" + relativeImportStylesFile.generic_string() + "\";\n</style>\n";
const std::string importBinIndexHtml =
"\t<script type=\"module\" defer>\n\t\timport \"" + binIndex.generic_string() + "\";\n</script>\n";

// find end of header </head> from behind in indexHtml:
const auto headEnd = indexHtml.rfind("</head>");
if (headEnd == std::string::npos)
{
std::cout << "Could not find </head> in " << index << "\n";
return 1;
}

// insert importScriptsHtml before headEnd:
indexHtml.insert(headEnd, importScriptsHtml);

// insert importStylesHtml before headEnd:
indexHtml.insert(headEnd, importStylesHtml);

// insert importBinIndexHtml before headEnd:
if (indexHtml.find(binIndex.generic_string()) == std::string::npos)
indexHtml.insert(headEnd, importBinIndexHtml);

// write indexHtml back to index file:
std::ofstream file{index, std::ios_base::binary};
if (!file)
{
std::cout << "Could not open " << index << " for writing\n";
return 1;
}

file.write(indexHtml.data(), indexHtml.size());
return 0;
}

0 comments on commit 650cc4b

Please sign in to comment.