*&---------------------------------------------------------------------* *& Include ZABAPGIT_HTML *&---------------------------------------------------------------------* DEFINE _add. ro_html->add( &1 ) ##NO_TEXT. END-OF-DEFINITION. *----------------------------------------------------------------------* * CLASS lcl_html_helper DEFINITION *----------------------------------------------------------------------* CLASS lcl_html_helper DEFINITION FINAL. PUBLIC SECTION. CONSTANTS: c_indent_size TYPE i VALUE 2. DATA mv_html TYPE string READ-ONLY. DATA mv_indent TYPE i READ-ONLY. DATA mv_within_style TYPE i READ-ONLY. METHODS add IMPORTING iv_chunk TYPE any. METHODS reset. METHODS add_anchor IMPORTING iv_txt TYPE string iv_act TYPE string iv_opt TYPE clike OPTIONAL iv_typ TYPE char1 DEFAULT gc_action_type-sapevent iv_class TYPE string OPTIONAL. PRIVATE SECTION. METHODS _add_str IMPORTING iv_str TYPE csequence. METHODS _add_htm IMPORTING io_html TYPE REF TO lcl_html_helper. ENDCLASS. "lcl_html_helper DEFINITION *----------------------------------------------------------------------* * CLASS lcl_html_helper IMPLEMENTATION *----------------------------------------------------------------------* CLASS lcl_html_helper IMPLEMENTATION. METHOD add. DATA lo_type TYPE REF TO cl_abap_typedescr. DATA lo_html TYPE REF TO lcl_html_helper. lo_type = cl_abap_typedescr=>describe_by_data( iv_chunk ). CASE lo_type->type_kind. WHEN cl_abap_typedescr=>typekind_char OR cl_abap_typedescr=>typekind_string. IF strlen( iv_chunk ) = 0. RETURN. ENDIF. _add_str( iv_chunk ). WHEN cl_abap_typedescr=>typekind_oref. ASSERT iv_chunk IS BOUND. " Dev mistake TRY. lo_html ?= iv_chunk. CATCH cx_sy_move_cast_error. ASSERT 1 = 0. " Dev mistake ENDTRY. _add_htm( lo_html ). WHEN OTHERS. ASSERT 1 = 0. " Dev mistake ENDCASE. ENDMETHOD. " add METHOD reset. CLEAR: me->mv_html, me->mv_indent. ENDMETHOD. "reset METHOD _add_str. CONSTANTS lc_single_tags_re TYPE string " HTML5 singleton tags VALUE '<(area|base|br|col|command|embed|hr|img|input|link|meta|param|source|!)'. DATA lv_tags TYPE i. DATA lv_tags_open TYPE i. DATA lv_tags_close TYPE i. DATA lv_tags_single TYPE i. DATA lv_close_offs TYPE i. DATA lv_shift_back TYPE i. DATA lv_style_tag_open TYPE i. DATA lv_style_tag_close TYPE i. DATA lv_curly TYPE i. FIND FIRST OCCURRENCE OF ' 0. " Found close tag @beginning lv_shift_back = 1. ENDIF. FIND FIRST OCCURRENCE OF '}' IN iv_str MATCH OFFSET lv_close_offs. " Find close } @beginning IF mv_within_style > 0 AND sy-subrc = 0 AND lv_close_offs = 0 AND mv_indent > 0. lv_shift_back = 1. ENDIF. mv_html = mv_html && repeat( val = ` ` occ = ( mv_indent - lv_shift_back ) * c_indent_size ) && iv_str && gc_newline. FIND ALL OCCURRENCES OF '<' IN iv_str MATCH COUNT lv_tags. FIND ALL OCCURRENCES OF '' IN iv_str MATCH COUNT lv_style_tag_close IGNORING CASE. mv_within_style = mv_within_style + lv_style_tag_open - lv_style_tag_close. IF mv_within_style > 0. FIND ALL OCCURRENCES OF '{' IN iv_str MATCH COUNT lv_curly. lv_tags_open = lv_tags_open + lv_curly. FIND ALL OCCURRENCES OF '}' IN iv_str MATCH COUNT lv_curly. lv_tags_close = lv_tags_close + lv_curly. ENDIF. " More-less logic chosen due to possible double tags in a line '' IF lv_tags_open > lv_tags_close. mv_indent = mv_indent + 1. ELSEIF lv_tags_open < lv_tags_close AND mv_indent > 0. mv_indent = mv_indent - 1. ENDIF. ENDMETHOD. "_add_str METHOD _add_htm. DATA lt_strtab TYPE TABLE OF string. DATA lv_str TYPE string. SPLIT io_html->mv_html AT gc_newline INTO TABLE lt_strtab. LOOP AT lt_strtab INTO lv_str. SHIFT lv_str LEFT DELETING LEADING space. _add_str( lv_str ). ENDLOOP. ENDMETHOD. "_add_htm METHOD add_anchor. DATA: lv_class TYPE string, lv_href TYPE string. lv_class = iv_class. IF iv_opt ca gc_html_opt-emphas. lv_class = lv_class && ' emphasis' ##NO_TEXT. ENDIF. IF iv_opt ca gc_html_opt-cancel. lv_class = lv_class && ' attention' ##NO_TEXT. ENDIF. IF iv_opt ca gc_html_opt-crossout. lv_class = lv_class && ' crossout grey' ##NO_TEXT. ENDIF. IF lv_class IS NOT INITIAL. SHIFT lv_class LEFT DELETING LEADING space. lv_class = | class="{ lv_class }"|. ENDIF. IF iv_act IS NOT INITIAL. CASE iv_typ. WHEN gc_action_type-url. lv_href = | href="{ iv_act }"|. WHEN gc_action_type-sapevent. lv_href = | href="sapevent:{ iv_act }"|. WHEN gc_action_type-onclick. lv_href = | onclick="{ iv_act }"|. ENDCASE. ENDIF. _add_str( |{ iv_txt }| ). ENDMETHOD. "add_action ENDCLASS. "lcl_html_helper IMPLEMENTATION *----------------------------------------------------------------------* * CLASS lcl_html_toolbar DEFINITION *----------------------------------------------------------------------* CLASS lcl_html_toolbar DEFINITION FINAL. PUBLIC SECTION. METHODS: add IMPORTING iv_txt TYPE string io_sub TYPE REF TO lcl_html_toolbar OPTIONAL iv_act TYPE string OPTIONAL iv_opt TYPE c OPTIONAL iv_typ TYPE c DEFAULT gc_action_type-sapevent, count RETURNING VALUE(rv_count) TYPE i, render IMPORTING iv_as_droplist_with_label TYPE string OPTIONAL iv_no_separator TYPE abap_bool OPTIONAL iv_vertical TYPE abap_bool OPTIONAL iv_sort TYPE abap_bool OPTIONAL iv_as_angle TYPE abap_bool OPTIONAL RETURNING VALUE(ro_html) TYPE REF TO lcl_html_helper. PRIVATE SECTION. TYPES: BEGIN OF ty_item, txt TYPE string, act TYPE string, sub TYPE REF TO lcl_html_toolbar, opt TYPE char1, typ TYPE char1, END OF ty_item. TYPES tt_items TYPE STANDARD TABLE OF ty_item. DATA mt_items TYPE tt_items. ENDCLASS. "lcl_html_toolbar DEFINITION *----------------------------------------------------------------------* * CLASS lcl_html_toolbar IMPLEMENTATION *----------------------------------------------------------------------* CLASS lcl_html_toolbar IMPLEMENTATION. METHOD count. rv_count = lines( mt_items ). ENDMETHOD. METHOD add. DATA ls_item TYPE ty_item. ASSERT iv_act IS INITIAL AND io_sub IS NOT INITIAL OR iv_act IS NOT INITIAL AND io_sub IS INITIAL. " Only one supplied ls_item-txt = iv_txt. ls_item-act = iv_act. ls_item-sub = io_sub. ls_item-opt = iv_opt. ls_item-typ = iv_typ. APPEND ls_item TO mt_items. ENDMETHOD. "add METHOD render. DATA: lv_class TYPE string, lv_is_drop TYPE abap_bool, lv_last TYPE abap_bool. FIELD-SYMBOLS LIKE LINE OF mt_items. CREATE OBJECT ro_html. lv_is_drop = boolc( iv_as_droplist_with_label IS NOT INITIAL OR iv_as_angle IS NOT INITIAL ). IF lv_is_drop = abap_false. " Normal menu IF iv_vertical = abap_true. lv_class = 'menu_vertical' ##NO_TEXT. ELSE. lv_class = 'menu' ##NO_TEXT. ENDIF. ELSEIF iv_as_angle IS NOT INITIAL. lv_class = 'dropdown dropdown_angle' ##NO_TEXT. ELSE. lv_class = 'dropdown' ##NO_TEXT. ENDIF. ro_html->add( |
| ). IF lv_is_drop = abap_true. " Dropdown IF iv_as_angle = abap_true. ro_html->add( '
' ). ELSE. lv_class = 'dropbtn'. IF iv_no_separator = abap_true. lv_class = lv_class && ' menu_end' ##NO_TEXT. ENDIF. ro_html->add( |{ iv_as_droplist_with_label }| ). ENDIF. ro_html->add( '' ). ENDIF. ro_html->add( '
' ). ENDMETHOD. "render ENDCLASS. "lcl_html_toolbar IMPLEMENTATION