Improve css preprocessing (#2765)

* improve assetman get_text_asset

* move css_processor to ui_core, reuse get_text_asse

* fix %26 refactor UTs

* zcl_abapgit_gui_html_processor

* if fix

* replace core logic

* comment finetuning

* linter fixes

* more linter fixes

* fix UTs, based on review
This commit is contained in:
Alexander Tsybulsky 2019-07-02 06:53:43 +03:00 committed by Lars Hvam
parent 1f52d8b2c7
commit df0aca8272
16 changed files with 583 additions and 163 deletions

View File

@ -20,6 +20,10 @@ CLASS zcl_abapgit_gui DEFINITION
go_home TYPE string VALUE 'go_home',
END OF c_action.
INTERFACES zif_abapgit_gui_services.
ALIASES:
cache_asset FOR zif_abapgit_gui_services~cache_asset.
METHODS go_home
RAISING
zcx_abapgit_exception.
@ -52,6 +56,7 @@ CLASS zcl_abapgit_gui DEFINITION
io_component TYPE REF TO object OPTIONAL
ii_asset_man TYPE REF TO zif_abapgit_gui_asset_manager OPTIONAL
ii_error_handler TYPE REF TO zif_abapgit_gui_error_handler OPTIONAL
ii_html_processor TYPE REF TO zif_abapgit_gui_html_processor OPTIONAL
RAISING
zcx_abapgit_exception.
@ -71,6 +76,7 @@ CLASS zcl_abapgit_gui DEFINITION
mi_router TYPE REF TO zif_abapgit_gui_event_handler,
mi_asset_man TYPE REF TO zif_abapgit_gui_asset_manager,
mi_error_handler TYPE REF TO zif_abapgit_gui_error_handler,
mi_html_processor TYPE REF TO zif_abapgit_gui_html_processor,
mo_html_viewer TYPE REF TO cl_gui_html_viewer.
METHODS startup
@ -83,16 +89,6 @@ CLASS zcl_abapgit_gui DEFINITION
RETURNING
VALUE(rv_url) TYPE w3url.
METHODS cache_asset
IMPORTING
iv_text TYPE string OPTIONAL
iv_xdata TYPE xstring OPTIONAL
iv_url TYPE w3url OPTIONAL
iv_type TYPE c
iv_subtype TYPE c
RETURNING
VALUE(rv_url) TYPE w3url.
METHODS render
RAISING
zcx_abapgit_exception.
@ -121,7 +117,7 @@ ENDCLASS.
CLASS zcl_abapgit_gui IMPLEMENTATION.
CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION.
METHOD back.
@ -156,45 +152,6 @@ CLASS zcl_abapgit_gui IMPLEMENTATION.
ENDMETHOD.
METHOD cache_asset.
DATA: lv_xstr TYPE xstring,
lt_xdata TYPE lvc_t_mime,
lv_size TYPE int4.
ASSERT iv_text IS SUPPLIED OR iv_xdata IS SUPPLIED.
IF iv_text IS SUPPLIED. " String input
lv_xstr = zcl_abapgit_convert=>string_to_xstring( iv_text ).
ELSE. " Raw input
lv_xstr = iv_xdata.
ENDIF.
zcl_abapgit_convert=>xstring_to_bintab(
EXPORTING
iv_xstr = lv_xstr
IMPORTING
ev_size = lv_size
et_bintab = lt_xdata ).
mo_html_viewer->load_data(
EXPORTING
type = iv_type
subtype = iv_subtype
size = lv_size
url = iv_url
IMPORTING
assigned_url = rv_url
CHANGING
data_table = lt_xdata
EXCEPTIONS
OTHERS = 1 ) ##NO_TEXT.
ASSERT sy-subrc = 0. " Image data error
ENDMETHOD.
METHOD cache_html.
rv_url = cache_asset(
@ -236,6 +193,7 @@ CLASS zcl_abapgit_gui IMPLEMENTATION.
mi_asset_man = ii_asset_man.
mi_error_handler = ii_error_handler.
mi_html_processor = ii_html_processor. " Maybe improve to middlewares stack ??
startup( ).
ENDMETHOD.
@ -371,6 +329,7 @@ CLASS zcl_abapgit_gui IMPLEMENTATION.
METHOD render.
DATA: lv_url TYPE w3url,
lv_html TYPE string,
li_html TYPE REF TO zif_abapgit_html,
lo_css_processor TYPE REF TO zcl_abapgit_gui_css_processor.
@ -378,27 +337,16 @@ CLASS zcl_abapgit_gui IMPLEMENTATION.
zcx_abapgit_exception=>raise( 'GUI error: no current page' ).
ENDIF.
CREATE OBJECT lo_css_processor
EXPORTING
ii_asset_manager = mi_asset_man.
lo_css_processor->add_file( 'css/theme-default.css' ).
CASE zcl_abapgit_persist_settings=>get_instance( )->read( )->get_ui_theme( ).
WHEN zcl_abapgit_settings=>c_ui_theme-dark.
"TODO
WHEN zcl_abapgit_settings=>c_ui_theme-belize.
lo_css_processor->add_file( 'css/theme-belize-blue.css' ).
ENDCASE.
cache_asset( iv_text = lo_css_processor->process( )
iv_url = 'css/theme.css'
iv_type = 'text'
iv_subtype = 'css' ).
li_html = mi_cur_page->render( ).
lv_url = cache_html( li_html->render( iv_no_indent_jscss = abap_true ) ).
lv_html = li_html->render( iv_no_indent_jscss = abap_true ).
IF mi_html_processor IS BOUND.
lv_html = mi_html_processor->process(
iv_html = lv_html
ii_gui_services = me ).
ENDIF.
lv_url = cache_html( lv_html ).
mo_html_viewer->show_url( lv_url ).
ENDMETHOD.
@ -435,4 +383,43 @@ CLASS zcl_abapgit_gui IMPLEMENTATION.
SET HANDLER me->on_event FOR mo_html_viewer.
ENDMETHOD.
METHOD cache_asset.
DATA: lv_xstr TYPE xstring,
lt_xdata TYPE lvc_t_mime,
lv_size TYPE int4.
ASSERT iv_text IS SUPPLIED OR iv_xdata IS SUPPLIED.
IF iv_text IS SUPPLIED. " String input
lv_xstr = zcl_abapgit_convert=>string_to_xstring( iv_text ).
ELSE. " Raw input
lv_xstr = iv_xdata.
ENDIF.
zcl_abapgit_convert=>xstring_to_bintab(
EXPORTING
iv_xstr = lv_xstr
IMPORTING
ev_size = lv_size
et_bintab = lt_xdata ).
mo_html_viewer->load_data(
EXPORTING
type = iv_type
subtype = iv_subtype
size = lv_size
url = iv_url
IMPORTING
assigned_url = rv_url
CHANGING
data_table = lt_xdata
EXCEPTIONS
OTHERS = 1 ) ##NO_TEXT.
ASSERT sy-subrc = 0. " Image data error
ENDMETHOD.
ENDCLASS.

View File

@ -45,7 +45,7 @@ ENDCLASS.
CLASS zcl_abapgit_gui_asset_manager IMPLEMENTATION.
CLASS ZCL_ABAPGIT_GUI_ASSET_MANAGER IMPLEMENTATION.
METHOD get_mime_asset.
@ -158,6 +158,14 @@ CLASS zcl_abapgit_gui_asset_manager IMPLEMENTATION.
DATA ls_asset TYPE zif_abapgit_gui_asset_manager~ty_web_asset.
ls_asset = me->zif_abapgit_gui_asset_manager~get_asset( iv_url ).
IF ls_asset-type <> 'text'.
zcx_abapgit_exception=>raise( |Not a text asset: { iv_url }| ).
ENDIF.
IF iv_assert_subtype IS NOT INITIAL AND ls_asset-subtype <> iv_assert_subtype.
zcx_abapgit_exception=>raise( |Wrong subtype ({ iv_assert_subtype }): { iv_url }| ).
ENDIF.
rv_asset = zcl_abapgit_convert=>xstring_to_string_utf8( ls_asset-content ).
ENDMETHOD.

View File

@ -31,9 +31,7 @@ CLASS ltcl_abapgit_gui_asset_manager IMPLEMENTATION.
cl_abap_unit_assert=>assert_equals( act = ls_asset-type exp = 'text' ).
cl_abap_unit_assert=>assert_equals( act = ls_asset-subtype exp = 'css' ).
cl_abap_unit_assert=>assert_equals(
act = cl_bcs_convert=>xstring_to_string(
iv_xstr = ls_asset-content
iv_cp = '4110' )
act = zcl_abapgit_convert=>xstring_to_string_utf8( ls_asset-content )
exp = 'ABC' ).
ENDMETHOD.
@ -52,6 +50,33 @@ CLASS ltcl_abapgit_gui_asset_manager IMPLEMENTATION.
act = lo_assetman->zif_abapgit_gui_asset_manager~get_text_asset( 'css/common.css' )
exp = 'ABC' ).
cl_abap_unit_assert=>assert_equals(
act = lo_assetman->zif_abapgit_gui_asset_manager~get_text_asset(
iv_url = 'css/common.css'
iv_assert_subtype = 'css' )
exp = 'ABC' ).
TRY .
lo_assetman->zif_abapgit_gui_asset_manager~get_text_asset(
iv_url = 'css/common.css'
iv_assert_subtype = 'xyz' ).
cl_abap_unit_assert=>fail( ).
CATCH zcx_abapgit_exception.
" no futher check
ENDTRY.
lo_assetman->register_asset(
iv_url = 'css/common.xyz'
iv_type = 'nottext/bin'
iv_inline = 'XYZ' ).
TRY .
lo_assetman->zif_abapgit_gui_asset_manager~get_text_asset( 'css/common.xyz' ).
cl_abap_unit_assert=>fail( ).
CATCH zcx_abapgit_exception.
" no futher check
ENDTRY.
ENDMETHOD.
METHOD get_mime_asset.

View File

@ -1,4 +1,3 @@
"! CSS preprocessor
CLASS zcl_abapgit_gui_css_processor DEFINITION
PUBLIC
FINAL
@ -6,10 +5,17 @@ CLASS zcl_abapgit_gui_css_processor DEFINITION
PUBLIC SECTION.
METHODS:
constructor IMPORTING ii_asset_manager TYPE REF TO zif_abapgit_gui_asset_manager,
add_file IMPORTING iv_url TYPE string,
process RETURNING VALUE(rv_result) TYPE string
RAISING zcx_abapgit_exception.
constructor
IMPORTING
ii_asset_manager TYPE REF TO zif_abapgit_gui_asset_manager,
add_file
IMPORTING
iv_url TYPE string,
process
RETURNING
VALUE(rv_result) TYPE string
RAISING zcx_abapgit_exception.
PROTECTED SECTION.
PRIVATE SECTION.
TYPES:
@ -18,30 +24,70 @@ CLASS zcl_abapgit_gui_css_processor DEFINITION
value TYPE string,
END OF gty_css_var,
gty_css_var_tab TYPE SORTED TABLE OF gty_css_var WITH UNIQUE KEY name.
METHODS:
get_css_vars_in_string IMPORTING iv_string TYPE string
RETURNING VALUE(rt_variables) TYPE gty_css_var_tab,
resolve_var_recursively IMPORTING iv_variable_name TYPE string
CHANGING ct_variables TYPE gty_css_var_tab
RAISING zcx_abapgit_exception.
get_css_vars_in_string
IMPORTING
iv_string TYPE string
RETURNING
VALUE(rt_variables) TYPE gty_css_var_tab,
resolve_var_recursively
IMPORTING
iv_variable_name TYPE string
CHANGING
ct_variables TYPE gty_css_var_tab
RAISING
zcx_abapgit_exception.
DATA:
mi_asset_manager TYPE REF TO zif_abapgit_gui_asset_manager,
mt_files TYPE STANDARD TABLE OF string.
mt_files TYPE string_table.
ENDCLASS.
CLASS zcl_abapgit_gui_css_processor IMPLEMENTATION.
METHOD constructor.
mi_asset_manager = ii_asset_manager.
ENDMETHOD.
CLASS ZCL_ABAPGIT_GUI_CSS_PROCESSOR IMPLEMENTATION.
METHOD add_file.
APPEND iv_url TO mt_files.
ENDMETHOD.
METHOD constructor.
mi_asset_manager = ii_asset_manager.
ENDMETHOD.
METHOD get_css_vars_in_string.
CONSTANTS: lc_root_pattern TYPE string VALUE `:root\s*\{([^\}]*)\}`,
lc_variable_pattern TYPE string VALUE `\-\-([\w\d-]+)\s*:\s*([^\n\r;]*);`.
DATA: lv_root TYPE string,
lo_matcher TYPE REF TO cl_abap_matcher,
lo_regex TYPE REF TO cl_abap_regex,
ls_variable LIKE LINE OF rt_variables.
" Only the :root element may define variables for now
FIND FIRST OCCURRENCE OF REGEX lc_root_pattern IN iv_string SUBMATCHES lv_root.
IF sy-subrc = 0 AND lv_root IS NOT INITIAL.
CREATE OBJECT lo_regex
EXPORTING
pattern = lc_variable_pattern.
lo_matcher = lo_regex->create_matcher( text = lv_root ).
WHILE lo_matcher->find_next( ) = abap_true.
ls_variable-name = lo_matcher->get_submatch( 1 ).
ls_variable-value = lo_matcher->get_submatch( 2 ).
INSERT ls_variable INTO TABLE rt_variables.
IF sy-subrc <> 0.
MODIFY TABLE rt_variables FROM ls_variable.
ENDIF.
ENDWHILE.
ENDIF.
ENDMETHOD.
METHOD process.
DATA: ls_asset TYPE zif_abapgit_gui_asset_manager=>ty_web_asset,
DATA:
lt_contents TYPE STANDARD TABLE OF string,
lv_content TYPE string,
lt_css_variables TYPE gty_css_var_tab,
@ -52,9 +98,9 @@ CLASS zcl_abapgit_gui_css_processor IMPLEMENTATION.
" 1. Determine all variables and their values. Later definitions overwrite previous ones.
LOOP AT mt_files ASSIGNING <lv_url>.
ls_asset = mi_asset_manager->get_asset( <lv_url> ).
ASSERT ls_asset-type = 'text' AND ls_asset-subtype = 'css'.
lv_content = zcl_abapgit_convert=>xstring_to_string_utf8( ls_asset-content ).
lv_content = mi_asset_manager->get_text_asset(
iv_url = <lv_url>
iv_assert_subtype = 'css' ).
lt_css_vars_in_file = get_css_vars_in_string( lv_content ).
@ -86,32 +132,6 @@ CLASS zcl_abapgit_gui_css_processor IMPLEMENTATION.
rv_result = concat_lines_of( table = lt_contents sep = cl_abap_char_utilities=>newline ).
ENDMETHOD.
METHOD get_css_vars_in_string.
CONSTANTS: lc_root_pattern TYPE string VALUE `:root\s*\{([^\}]*)\}`,
lc_variable_pattern TYPE string VALUE `\-\-([\w\d-]+)\s*:\s*([^\n\r;]*);`.
DATA: lv_root TYPE string,
lo_matcher TYPE REF TO cl_abap_matcher,
lo_regex TYPE REF TO cl_abap_regex,
ls_variable LIKE LINE OF rt_variables.
" Only the :root element may define variables for now
FIND FIRST OCCURRENCE OF REGEX lc_root_pattern IN iv_string SUBMATCHES lv_root.
IF sy-subrc = 0 AND lv_root IS NOT INITIAL.
CREATE OBJECT lo_regex
EXPORTING
pattern = lc_variable_pattern.
lo_matcher = lo_regex->create_matcher( text = lv_root ).
WHILE lo_matcher->find_next( ) = abap_true.
ls_variable-name = lo_matcher->get_submatch( 1 ).
ls_variable-value = lo_matcher->get_submatch( 2 ).
INSERT ls_variable INTO TABLE rt_variables.
IF sy-subrc <> 0.
MODIFY TABLE rt_variables FROM ls_variable.
ENDIF.
ENDWHILE.
ENDIF.
ENDMETHOD.
METHOD resolve_var_recursively.
CONSTANTS: lc_variable_usage_pattern TYPE string VALUE `var\(\-\-([^\)]*)\)`.

View File

@ -1,32 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltcl_asset_manager_double DEFINITION FOR TESTING.
PUBLIC SECTION.
INTERFACES:
zif_abapgit_gui_asset_manager.
DATA:
mt_assets TYPE zif_abapgit_gui_asset_manager=>tt_web_assets.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ltcl_asset_manager_double IMPLEMENTATION.
METHOD zif_abapgit_gui_asset_manager~get_all_assets.
cl_abap_unit_assert=>fail( ).
ENDMETHOD.
METHOD zif_abapgit_gui_asset_manager~get_asset.
READ TABLE mt_assets WITH KEY url = iv_url INTO rs_asset.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Asset not found' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_gui_asset_manager~get_text_asset.
cl_abap_unit_assert=>fail( ).
ENDMETHOD.
ENDCLASS.
CLASS ltcl_test_base DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT ABSTRACT.
PUBLIC SECTION.
PROTECTED SECTION.
@ -34,7 +5,7 @@ CLASS ltcl_test_base DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT A
add_file IMPORTING iv_url TYPE string
iv_content TYPE string OPTIONAL.
DATA:
mo_asset_manager TYPE REF TO ltcl_asset_manager_double,
mo_asset_manager TYPE REF TO zcl_abapgit_gui_asset_manager,
mo_cut TYPE REF TO zcl_abapgit_gui_css_processor.
PRIVATE SECTION.
METHODS:
@ -57,12 +28,10 @@ CLASS ltcl_test_base IMPLEMENTATION.
METHOD add_file.
DATA: ls_asset TYPE zif_abapgit_gui_asset_manager=>ty_web_asset.
ls_asset-url = iv_url.
ls_asset-type = 'text'.
ls_asset-subtype = 'css'.
ls_asset-content = zcl_abapgit_convert=>string_to_xstring_utf8( iv_content ).
APPEND ls_asset TO mo_asset_manager->mt_assets.
mo_asset_manager->register_asset(
iv_url = iv_url
iv_type = 'text/css'
iv_inline = iv_content ).
ENDMETHOD.
ENDCLASS.
@ -105,8 +74,8 @@ CLASS ltcl_single_file IMPLEMENTATION.
mo_cut->add_file( 'does/exist.css' ).
TRY.
mo_cut->process( ).
cl_abap_unit_assert=>fail( ). " Assetman fails on empty content
CATCH zcx_abapgit_exception.
cl_abap_unit_assert=>fail( ).
ENDTRY.
ENDMETHOD.

View File

@ -0,0 +1,152 @@
CLASS zcl_abapgit_gui_html_processor DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CONSTANTS c_css_build_name TYPE string VALUE 'css/bundle.css'.
CONSTANTS c_comment_start TYPE string VALUE `<!-- by AG HTML preprocessor `.
CONSTANTS c_comment_end TYPE string VALUE `-->`.
INTERFACES zif_abapgit_gui_html_processor .
METHODS constructor
IMPORTING
ii_asset_man TYPE REF TO zif_abapgit_gui_asset_manager.
METHODS preserve_css
IMPORTING
!iv_css_url TYPE string .
PROTECTED SECTION.
PRIVATE SECTION.
DATA mt_preserve_css TYPE string_table.
DATA mi_asset_man TYPE REF TO zif_abapgit_gui_asset_manager.
METHODS patch_html
IMPORTING
iv_html TYPE string
EXPORTING
ev_html TYPE string
et_css_urls TYPE string_table
RAISING
zcx_abapgit_exception.
METHODS is_preserved
IMPORTING
!iv_css_url TYPE string
RETURNING
VALUE(rv_yes) TYPE abap_bool.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_HTML_PROCESSOR IMPLEMENTATION.
METHOD constructor.
mi_asset_man = ii_asset_man.
ENDMETHOD.
METHOD is_preserved.
READ TABLE mt_preserve_css TRANSPORTING NO FIELDS WITH KEY table_line = iv_css_url.
rv_yes = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD patch_html.
CONSTANTS lc_css_re TYPE string VALUE `<link\s+rel="stylesheet"\s+type="text/css"\s+href="(\S+)">`.
DATA lv_head_end TYPE i.
DATA lo_css_re TYPE REF TO cl_abap_regex.
DATA lo_matcher TYPE REF TO cl_abap_matcher.
DATA lv_css_path TYPE string.
DATA lv_off TYPE i.
DATA lv_len TYPE i.
DATA lv_cur TYPE i.
DATA lc_css_build TYPE string VALUE '<link rel="stylesheet" type="text/css" href="$BUILD_NAME">'.
REPLACE FIRST OCCURRENCE OF '$BUILD_NAME' IN lc_css_build WITH c_css_build_name. " Mmmm
CLEAR: ev_html, et_css_urls.
lv_head_end = find( val = iv_html regex = |{ cl_abap_char_utilities=>newline }?\\s*</head>| case = abap_false ).
IF lv_head_end <= 0.
zcx_abapgit_exception=>raise( 'HTML preprocessor: </head> not found' ).
ENDIF.
CREATE OBJECT lo_css_re
EXPORTING
ignore_case = abap_true
pattern = lc_css_re.
lo_matcher = lo_css_re->create_matcher( text = substring( val = iv_html len = lv_head_end ) ).
WHILE lo_matcher->find_next( ) = abap_true.
lv_css_path = lo_matcher->get_submatch( 1 ).
IF abap_false = is_preserved( lv_css_path ).
lv_off = lo_matcher->get_offset( ).
lv_len = lo_matcher->get_length( ).
ev_html = ev_html && substring( val = iv_html off = lv_cur len = lv_off - lv_cur ).
ev_html = ev_html && c_comment_start && substring( val = iv_html off = lv_off len = lv_len ) && c_comment_end.
lv_cur = lv_off + lv_len.
APPEND lv_css_path TO et_css_urls.
ENDIF.
ENDWHILE.
ev_html = ev_html && substring( val = iv_html off = lv_cur len = lv_head_end - lv_cur ).
IF lines( et_css_urls ) > 0.
ev_html = ev_html
&& cl_abap_char_utilities=>newline && ` ` " Assume 4 space indent, maybe improve and detect ?
&& c_comment_start && c_comment_end
&& lc_css_build.
ENDIF.
ev_html = ev_html && substring( val = iv_html off = lv_head_end ).
ENDMETHOD.
METHOD preserve_css.
APPEND iv_css_url TO mt_preserve_css.
ENDMETHOD.
METHOD zif_abapgit_gui_html_processor~process.
DATA lo_css_processor TYPE REF TO zcl_abapgit_gui_css_processor.
DATA lt_css_urls TYPE string_table.
DATA lv_css_build TYPE string.
FIELD-SYMBOLS <lv_url> LIKE LINE OF lt_css_urls.
patch_html(
EXPORTING
iv_html = iv_html
IMPORTING
ev_html = rv_html
et_css_urls = lt_css_urls ).
IF lines( lt_css_urls ) > 0.
CREATE OBJECT lo_css_processor
EXPORTING
ii_asset_manager = mi_asset_man.
LOOP AT lt_css_urls ASSIGNING <lv_url>.
lo_css_processor->add_file( <lv_url> ).
ENDLOOP.
lv_css_build = lo_css_processor->process( ).
ii_gui_services->cache_asset(
iv_url = |{ c_css_build_name }|
iv_type = 'text'
iv_subtype = 'css'
iv_text = lv_css_build ).
ENDIF.
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,174 @@
CLASS lcl_gui_mock DEFINITION.
PUBLIC SECTION.
TYPES:
BEGIN OF ty_cache_signature,
url TYPE string,
type TYPE string,
data TYPE string,
END OF ty_cache_signature.
DATA ms_last_cache_signature TYPE ty_cache_signature.
INTERFACES zif_abapgit_gui_services.
ENDCLASS.
CLASS lcl_gui_mock IMPLEMENTATION.
METHOD zif_abapgit_gui_services~cache_asset.
ms_last_cache_signature-url = iv_url.
ms_last_cache_signature-type = iv_type && '/' && iv_subtype.
ms_last_cache_signature-data = iv_text.
ENDMETHOD.
ENDCLASS.
CLASS ltcl_html_processor_test DEFINITION
FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS
FINAL.
PRIVATE SECTION.
DATA mv_source TYPE string.
DATA mo_cut TYPE REF TO zcl_abapgit_gui_html_processor.
DATA mo_gui_mock TYPE REF TO lcl_gui_mock.
METHODS render_html
IMPORTING
iv_src TYPE string
RETURNING
VALUE(rv_html) TYPE string.
METHODS setup.
METHODS process_typical FOR TESTING RAISING zcx_abapgit_exception.
METHODS process_with_preserve FOR TESTING RAISING zcx_abapgit_exception.
METHODS process_no_css FOR TESTING RAISING zcx_abapgit_exception.
METHODS process_fails FOR TESTING RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS ltcl_html_processor_test IMPLEMENTATION.
METHOD render_html.
rv_html = iv_src.
REPLACE ALL OCCURRENCES OF '\n' IN rv_html WITH cl_abap_char_utilities=>newline.
ENDMETHOD.
METHOD setup.
DATA lo_asset_man TYPE REF TO zcl_abapgit_gui_asset_manager.
CREATE OBJECT lo_asset_man.
lo_asset_man->register_asset( iv_url = 'css/style1.css' iv_type = 'text/css' iv_inline = 'dummy1' ).
lo_asset_man->register_asset( iv_url = 'css/style2.css' iv_type = 'text/css' iv_inline = 'dummy2' ).
lo_asset_man->register_asset( iv_url = 'css/style3.css' iv_type = 'text/css' iv_inline = 'dummy3' ).
CREATE OBJECT mo_cut
EXPORTING
ii_asset_man = lo_asset_man.
CREATE OBJECT mo_gui_mock.
mv_source = render_html(
`<html>\n` &&
` <head>\n` &&
` <title>abapGit</title>\n` &&
` <LINK rel="stylesheet" type="text/css" href="css/style1.css">\n` && " +case & extra space
` <link rel="stylesheet" type="text/css" href="css/style2.css">\n` &&
` <link rel="stylesheet" type="text/css" href="css/style3.css">\n` &&
` <script type="text/javascript" src="js/common.js"></script>\n` &&
` </head>\n` &&
` <body>hello</body>\n` &&
`</html>\n` ).
ENDMETHOD.
METHOD process_typical.
DATA lv_act TYPE string.
lv_act = mo_cut->zif_abapgit_gui_html_processor~process(
iv_html = mv_source
ii_gui_services = mo_gui_mock ).
cl_abap_unit_assert=>assert_equals(
act = lv_act
exp = render_html(
`<html>\n` &&
` <head>\n` &&
` <title>abapGit</title>\n` &&
` <!-- by AG HTML preprocessor <LINK rel="stylesheet" type="text/css" href="css/style1.css">-->\n` &&
` <!-- by AG HTML preprocessor <link rel="stylesheet" type="text/css" href="css/style2.css">-->\n` &&
` <!-- by AG HTML preprocessor <link rel="stylesheet" type="text/css" href="css/style3.css">-->\n` &&
` <script type="text/javascript" src="js/common.js"></script>\n` &&
` <!-- by AG HTML preprocessor --><link rel="stylesheet" type="text/css" href="css/bundle.css">\n` &&
` </head>\n` &&
` <body>hello</body>\n` &&
`</html>\n`
) ).
" GUI call checks
cl_abap_unit_assert=>assert_equals(
act = mo_gui_mock->ms_last_cache_signature-url
exp = 'css/bundle.css' ).
cl_abap_unit_assert=>assert_equals(
act = mo_gui_mock->ms_last_cache_signature-type
exp = 'text/css' ).
cl_abap_unit_assert=>assert_equals(
act = mo_gui_mock->ms_last_cache_signature-data
exp = render_html( 'dummy1\ndummy2\ndummy3' ) ).
ENDMETHOD.
METHOD process_with_preserve.
DATA lv_act TYPE string.
mo_cut->preserve_css( 'css/style2.css' ).
lv_act = mo_cut->zif_abapgit_gui_html_processor~process(
iv_html = mv_source
ii_gui_services = mo_gui_mock ).
cl_abap_unit_assert=>assert_equals(
act = lv_act
exp = render_html(
`<html>\n` &&
` <head>\n` &&
` <title>abapGit</title>\n` &&
` <!-- by AG HTML preprocessor <LINK rel="stylesheet" type="text/css" href="css/style1.css">-->\n` &&
` <link rel="stylesheet" type="text/css" href="css/style2.css">\n` && " Preserved
` <!-- by AG HTML preprocessor <link rel="stylesheet" type="text/css" href="css/style3.css">-->\n` &&
` <script type="text/javascript" src="js/common.js"></script>\n` &&
` <!-- by AG HTML preprocessor --><link rel="stylesheet" type="text/css" href="css/bundle.css">\n` &&
` </head>\n` &&
` <body>hello</body>\n` &&
`</html>\n`
) ).
ENDMETHOD.
METHOD process_no_css.
DATA lv_act TYPE string.
lv_act = mo_cut->zif_abapgit_gui_html_processor~process(
iv_html = '<html><head></head></html>'
ii_gui_services = mo_gui_mock ).
cl_abap_unit_assert=>assert_equals(
act = lv_act
exp = '<html><head></head></html>' ).
ENDMETHOD.
METHOD process_fails.
TRY .
" BTW this is valid HTML, maybe refactor the code ...
mo_cut->zif_abapgit_gui_html_processor~process(
iv_html = '<html><body></body></html>'
ii_gui_services = mo_gui_mock ).
cl_abap_unit_assert=>fail( ).
CATCH zcx_abapgit_exception ##NO_HANDLER.
ENDTRY.
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_ABAPGIT_GUI_HTML_PROCESSOR</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>abapgit GUI html processor</DESCRIPT>
<STATE>1</STATE>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
<UNICODE>X</UNICODE>
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -28,9 +28,10 @@ INTERFACE zif_abapgit_gui_asset_manager
METHODS get_text_asset
IMPORTING
iv_url TYPE string
iv_url TYPE string
iv_assert_subtype TYPE string OPTIONAL
RETURNING
VALUE(rv_asset) TYPE string
VALUE(rv_asset) TYPE string
RAISING
zcx_abapgit_exception.

View File

@ -0,0 +1,13 @@
INTERFACE zif_abapgit_gui_html_processor
PUBLIC .
METHODS process
IMPORTING
!iv_html TYPE string
!ii_gui_services TYPE REF TO zif_abapgit_gui_services
RETURNING
VALUE(rv_html) TYPE string
RAISING
zcx_abapgit_exception.
ENDINTERFACE.

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOINTERF>
<CLSNAME>ZIF_ABAPGIT_GUI_HTML_PROCESSOR</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>abapgit GUI html preprocessor interface</DESCRIPT>
<EXPOSURE>2</EXPOSURE>
<STATE>1</STATE>
<UNICODE>X</UNICODE>
</VSEOINTERF>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -0,0 +1,17 @@
INTERFACE zif_abapgit_gui_services
PUBLIC .
METHODS cache_asset
IMPORTING
iv_text TYPE string OPTIONAL
iv_xdata TYPE xstring OPTIONAL
iv_url TYPE w3url OPTIONAL
iv_type TYPE c
iv_subtype TYPE c
RETURNING
VALUE(rv_url) TYPE w3url.
" For future refactoring
" Potentially also: back, go_home, go_page, +some access to page stack
ENDINTERFACE.

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOINTERF>
<CLSNAME>ZIF_ABAPGIT_GUI_SERVICES</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>Selected services of abapgit GUI</DESCRIPT>
<EXPOSURE>2</EXPOSURE>
<STATE>1</STATE>
<UNICODE>X</UNICODE>
</VSEOINTERF>
</asx:values>
</asx:abap>
</abapGit>

View File

@ -87,7 +87,7 @@ ENDCLASS.
CLASS zcl_abapgit_gui_page IMPLEMENTATION.
CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION.
METHOD call_browser.
@ -216,10 +216,10 @@ CLASS zcl_abapgit_gui_page IMPLEMENTATION.
ro_html->add( '<title>abapGit</title>' ). "#EC NOTEXT
ro_html->add( '<link rel="stylesheet" type="text/css" href="css/common.css">' ).
ro_html->add( '<link rel="stylesheet" type="text/css" href="css/ag-icons.css">' ).
" theme.css is created at runtime in ZCL_ABAPGIT_GUI->RENDER( )
ro_html->add( '<link rel="stylesheet" type="text/css" href="css/theme.css">' ).
" Themes
ro_html->add( '<link rel="stylesheet" type="text/css" href="css/theme-default.css">' ). " Theme basis
CASE mo_settings->get_ui_theme( ).
WHEN zcl_abapgit_settings=>c_ui_theme-dark.
"TODO
@ -227,7 +227,6 @@ CLASS zcl_abapgit_gui_page IMPLEMENTATION.
ro_html->add( '<link rel="stylesheet" type="text/css" href="css/theme-belize-blue.css">' ).
ENDCASE.
ro_html->add( '<link rel="stylesheet" type="text/css" href="css/ag-icons.css">' ).
ro_html->add( '<script type="text/javascript" src="js/common.js"></script>' ). "#EC NOTEXT
CASE mo_settings->get_icon_scaling( ). " Enforce icon scaling

View File

@ -41,7 +41,7 @@ ENDCLASS.
CLASS zcl_abapgit_ui_factory IMPLEMENTATION.
CLASS ZCL_ABAPGIT_UI_FACTORY IMPLEMENTATION.
METHOD get_frontend_services.
@ -62,15 +62,23 @@ CLASS zcl_abapgit_ui_factory IMPLEMENTATION.
li_asset_man TYPE REF TO zif_abapgit_gui_asset_manager.
DATA lo_error_handler TYPE REF TO lcl_gui_error_handler.
DATA lo_html_preprocessor TYPE REF TO zcl_abapgit_gui_html_processor.
IF go_gui IS INITIAL.
li_asset_man ?= init_asset_manager( ).
CREATE OBJECT lo_html_preprocessor EXPORTING ii_asset_man = li_asset_man.
lo_html_preprocessor->preserve_css( 'css/ag-icons.css' ).
lo_html_preprocessor->preserve_css( 'css/common.css' ).
CREATE OBJECT li_router TYPE zcl_abapgit_gui_router.
CREATE OBJECT lo_error_handler.
CREATE OBJECT go_gui
EXPORTING
io_component = li_router
ii_error_handler = lo_error_handler
ii_html_processor = lo_html_preprocessor
ii_asset_man = li_asset_man.
ENDIF.
ro_gui = go_gui.