From 5f3498d50f5b0d29b1c8b4f2043202c45ef7e081 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Sun, 17 Apr 2022 15:33:50 +0100 Subject: [PATCH] LibWeb: Add code generator for CSS transform functions This first step just generates the TransformFunction enum, but more will follow. --- .../CodeGenerators/LibWeb/CMakeLists.txt | 1 + .../LibWeb/GenerateCSSTransformFunctions.cpp | 92 +++++++++++++++++++ Userland/Libraries/LibWeb/CMakeLists.txt | 11 +++ .../LibWeb/CSS/TransformFunctions.json | 35 +++++++ 4 files changed, 139 insertions(+) create mode 100644 Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSTransformFunctions.cpp create mode 100644 Userland/Libraries/LibWeb/CSS/TransformFunctions.json diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/CMakeLists.txt b/Meta/Lagom/Tools/CodeGenerators/LibWeb/CMakeLists.txt index 7b3e7904e7..df45d28635 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/CMakeLists.txt +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/CMakeLists.txt @@ -3,6 +3,7 @@ set(SOURCES "") # avoid pulling SOURCES from parent scope lagom_tool(GenerateCSSEnums SOURCES GenerateCSSEnums.cpp LIBS LagomMain) lagom_tool(GenerateCSSMediaFeatureID SOURCES GenerateCSSMediaFeatureID.cpp LIBS LagomMain) lagom_tool(GenerateCSSPropertyID SOURCES GenerateCSSPropertyID.cpp LIBS LagomMain) +lagom_tool(GenerateCSSTransformFunctions SOURCES GenerateCSSTransformFunctions.cpp LIBS LagomMain) lagom_tool(GenerateCSSValueID SOURCES GenerateCSSValueID.cpp LIBS LagomMain) add_subdirectory(WrapperGenerator) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSTransformFunctions.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSTransformFunctions.cpp new file mode 100644 index 0000000000..31f6c16e80 --- /dev/null +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSTransformFunctions.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2022, Sam Atkins + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "GeneratorUtil.h" +#include +#include +#include +#include + +ErrorOr generate_header_file(JsonObject& transforms_data, Core::Stream::File& file); +ErrorOr generate_implementation_file(JsonObject& transforms_data, Core::Stream::File& file); + +ErrorOr serenity_main(Main::Arguments arguments) +{ + StringView generated_header_path; + StringView generated_implementation_path; + StringView identifiers_json_path; + + Core::ArgsParser args_parser; + args_parser.add_option(generated_header_path, "Path to the TransformFunctions header file to generate", "generated-header-path", 'h', "generated-header-path"); + args_parser.add_option(generated_implementation_path, "Path to the TransformFunctions implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path"); + args_parser.add_option(identifiers_json_path, "Path to the JSON file to read from", "json-path", 'j', "json-path"); + args_parser.parse(arguments); + + auto json = TRY(read_entire_file_as_json(identifiers_json_path)); + VERIFY(json.is_object()); + auto transforms_data = json.as_object(); + + auto generated_header_file = TRY(Core::Stream::File::open(generated_header_path, Core::Stream::OpenMode::Write)); + auto generated_implementation_file = TRY(Core::Stream::File::open(generated_implementation_path, Core::Stream::OpenMode::Write)); + + TRY(generate_header_file(transforms_data, *generated_header_file)); + TRY(generate_implementation_file(transforms_data, *generated_implementation_file)); + + return 0; +} + +static String title_casify_transform_function(StringView input) +{ + // Transform function names look like `fooBar`, so we just have to make the first character uppercase. + StringBuilder builder; + builder.append(toupper(input[0])); + builder.append(input.substring_view(1)); + return builder.to_string(); +} + +ErrorOr generate_header_file(JsonObject& transforms_data, Core::Stream::File& file) +{ + StringBuilder builder; + SourceGenerator generator { builder }; + + generator.append(R"~~~( +namespace Web::CSS { + +)~~~"); + + generator.appendln("enum class TransformFunction {"); + transforms_data.for_each_member([&](auto& name, auto&) { + auto member_generator = generator.fork(); + member_generator.set("name:titlecase", title_casify_transform_function(name)); + member_generator.appendln(" @name:titlecase@,"); + }); + generator.appendln("};"); + + generator.appendln("\n}"); + + TRY(file.write(generator.as_string_view().bytes())); + return {}; +} + +ErrorOr generate_implementation_file(JsonObject& transforms_data, Core::Stream::File& file) +{ + StringBuilder builder; + SourceGenerator generator { builder }; + + generator.append(R"~~~( +namespace Web::CSS { +)~~~"); + + transforms_data.for_each_member([&](auto& name, auto& value) { + (void)name; + (void)value; + }); + + generator.appendln("}"); + + TRY(file.write(generator.as_string_view().bytes())); + return {}; +} diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 89c72b2ce0..63797e2515 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -74,6 +74,7 @@ set(SOURCES CSS/Supports.cpp CSS/SyntaxHighlighter/SyntaxHighlighter.cpp CSS/Time.cpp + CSS/TransformFunctions.cpp CSS/ValueID.cpp CSS/ValueID.h Cookie/ParsedCookie.cpp @@ -647,6 +648,16 @@ invoke_generator( arguments -j "${CMAKE_CURRENT_SOURCE_DIR}/CSS/Properties.json" ) +invoke_generator( + "TransformFunctions" + Lagom::GenerateCSSTransformFunctions + "${CMAKE_CURRENT_SOURCE_DIR}/CSS/TransformFunctions.json" + "" + "CSS/TransformFunctions.h" + "CSS/TransformFunctions.cpp" + arguments -j "${CMAKE_CURRENT_SOURCE_DIR}/CSS/TransformFunctions.json" +) + invoke_generator( "ValueID" Lagom::GenerateCSSValueID diff --git a/Userland/Libraries/LibWeb/CSS/TransformFunctions.json b/Userland/Libraries/LibWeb/CSS/TransformFunctions.json new file mode 100644 index 0000000000..711488a357 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/TransformFunctions.json @@ -0,0 +1,35 @@ +{ + "matrix": { + "parameters": "{6}" + }, + "translate": { + "parameters": "{1,2}" + }, + "translateX": { + "parameters": "" + }, + "translateY": { + "parameters": "" + }, + "scale": { + "parameters": "{1,2}" + }, + "scaleX": { + "parameters": "" + }, + "scaleY": { + "parameters": "" + }, + "rotate": { + "parameters": "" + }, + "skew": { + "parameters": "{1,2}" + }, + "skewX": { + "parameters": "" + }, + "skewY": { + "parameters": "" + } +}