Gui refactoring - part 5 (#3403)

* refactor mi_gui_services to getter

* zif_html->set_title (for debug of postponed parts)

* add set_title to all postponed parts

* gui optional rollback on error

* forgotten gui_services call

* docs

* remove gui_page redirect #3404

* forgotten html~set_title in hotkey class

also renamed render_js_part into render_scripts for unification and reuse register_deferred_script - this is why I lost it int the first place

Co-authored-by: Lars Hvam <larshp@hotmail.com>
This commit is contained in:
Alexander Tsybulsky 2020-05-24 11:42:06 +03:00 committed by GitHub
parent f431d30140
commit 5c4c0b882e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 271 additions and 207 deletions

View File

@ -9,22 +9,27 @@ This doc covers page creation, html rendering and event handling.
## TL;DR
- To create a new page in abapGit you subclass `ZCL_ABAPGIT_GUI_PAGE` and redefine `RENDER_CONTENT` method
- Use `ZCL_ABAPGIT_HTML` to collect HTML content
- To create a new page in abapGit you subclass `ZCL_ABAPGIT_GUI_PAGE` and redefine `RENDER_CONTENT` method *(also consider separating components that implement `ZIF_ABAPGIT_GUI_RENDERABLE` directly, this will probably become the primary approach in future)*
- Use `ZCL_ABAPGIT_HTML` to collect HTML content - method `add` accepts strings, string_tables and instances of `ZCL_ABAPGIT_HTML`
- Use `ZCL_ABAPGIT_HTML=>ICON` to render icons
- Use `ZCL_ABAPGIT_HTML=>A` to render anchors, don't render them manually `<a>...</a>`
- Please, please, care about usability, content readability and style in general :pray: ;)
- Check `ZCL_ABAPGIT_GUI_CHUNK_LIB` for some existing html chunks like `render_error`
- To register postponed html parts, scripts and hotkeys - access corresponding methods via `gui_services` method of `zcl_abapgit_gui_component`
## GUI components
abapGit UI is based on HTML and `CL_GUI_HTML_VIEWER`. Main parts are:
- ZCL_ABAPGIT_GUI - the class which initializes `CL_GUI_HTML_VIEWER` and manages page stack
- ZCL_ABAPGIT_GUI_ASSET_MANAGER - manages static assets like images, css, js code and fonts
- ZCL_ABAPGIT_HTML - helper for HTML accumulation and rendering
- ZCL_ABAPGIT_GUI_ROUTER - abapGit specific global event handling, main to route between the pages or run globally defined actions like repo installation
- ZCL_ABAPGIT_GUI_PAGE - base class for pages. It renders typical html headers and abapGit related java scripts. So in most cases you probably just want to subclass it and render just the content
- *ZCL_ABAPGIT_GUI* - the class which initializes `CL_GUI_HTML_VIEWER` and manages page stack
- *ZCL_ABAPGIT_GUI_ASSET_MANAGER* - manages static assets like images, css, js code and fonts
- *ZCL_ABAPGIT_HTML* - helper for HTML accumulation and rendering
- *ZCL_ABAPGIT_GUI_ROUTER* - abapGit specific global event handling, main to route between the pages or run globally defined actions like repo installation
- *ZCL_ABAPGIT_GUI_PAGE* - base class for pages. It renders typical html headers and abapGit related java scripts. ~~So in most cases you probably just want to subclass it and render just the content~~
- *ZCL_ABAPGIT_GUI_COMPONENT* - base class for gui components. Gives access to `gui_services` to register postponed html parts, scripts and hotkeys. Usually, it is a good idea to subclass from it, if you want to use these features.
- *ZIF_ABAPGIT_GUI_RENDERABLE* - interface which a renderable component must expose to be able to interact with `ZCL_ABAPGIT_GUI`
- *ZIF_ABAPGIT_GUI_EVENT_HANDLER* - interface which a component must expose to be able to register itself as a event handler in `ZCL_ABAPGIT_GUI`
- *ZIF_ABAPGIT_GUI_HOTKEYS* - interface which a component must expose to be able to register hotkey actions
## Rendering content
@ -65,16 +70,40 @@ ENDMETHOD.
- `IV_CLASS` - additional css class, if needed
- `IV_STYLE` - additional direct styles to use (generally discouraged, please use css classes instead)
- `IV_ID` - id of the anchor (may be needed for JS code)
- **SET_TITLE** - the method is used for debug purposes for postponed html parts. As it is not visible which class registered a part, so title can be used to specify the origin.
## Renderables
Sub-classing `ZCL_ABAPGIT_GUI_PAGE` is not the only way to render the content. You may want to separate some visual component which is not a page e.g. `ZCL_ABAPGIT_GUI_VIEW_REPO` is a class like that. In essence you have to implement `ZIF_ABAPGIT_GUI_RENDERABLE` and it's method - `render`. Then you can reuse it or even pass directly to GUI class as a page to render.
It makes sense to also subclass your component from `ZCL_ABAPGIT_GUI_COMPONENT`. This class has a protected `gui_services` method returning the singleton instance of `ZIF_ABAPGIT_GUI_SERVICES`. The gui services are good for:
- registering self as an event handler (`register_event_handler`). Importantly, later registered event handlers have higher priority (processing is done from bottom to top)
- accessing hotkey services (`get_hotkeys_ctl`) - to register own hotkeys for the page (hotkeys are combines from the whole component stack)
- registering postponed html parts (`get_html_parts`)
## Postponed HTML parts
Components may have postponed parts, e.g. scripts or hidden forms. These chunks may need to be rendered in another location of the page (e.g. scripts are rendered at the end). There is a mechanism to enable it:
```abap
" ... somewhere within render
gui_services( )->get_html_parts( )->add_part(
iv_collection = c_html_parts-scripts
ii_part = render_my_scripts( ) ).
```
where `render_my_scripts( )` must return an instance of `ZCL_ABAPGIT_HTML`.
Currently 2 collections are supported out of the box - scripts and hidden_forms (see definition of `zcl_abapgit_gui_component`). Scripts rendered after the page body. Hidden forms right before end of the body. But this does not limit you to these categories only - you may register own collections to exchange postponed parts between components supported by you. Collection is just a named list of `ZCL_ABAPGIT_HTML` instances.
## Router and event handlers
To process sapevents in abap the component (page) must implement `ZIF_ABAPGIT_GUI_EVENT_HANDLER=>on_event`. It has the same importing params as `sapevent` handler of `cl_gui_html_viewer`, please refer SAP official documentation for param meaning and detail. For the exporting params see below.
Events can be processed on 2 levels - in page **or** in the router. If an event occures, the GUI checks if the current page implements `ZIF_ABAPGIT_GUI_EVENT_HANDLER` and if so calls it. If the event was not handled by the page (see below how this is indicated) the event is passed to the router.
Events can be processed on 2 levels - in page/component **or** in the router. On new event:
- the GUI goes through event handlers stack - list of components that registered themselves as event handlers during rendering via `gui_services`
- the processing is done from the last registered handler to the first one (stack top to bottom)
- the first event handler that returns "handled" status breaks the cycle (see below how this is indicated)
- if the event was not handled by the handlers in the stack the event would be passed to the router
Router (`ZCL_ABAPGIT_GUI_ROUTER`) is the class which handle global abapGit commands like opening specific pages and actions like repo installation/deletion.
@ -88,3 +117,36 @@ In order to indicate the result of event handling an `on_event` implementation m
- `new_page_w_bookmark` - `ei_page` and put a bookmark - allows to use `go_back_to_bookmark` action that will skip all the page stack till the first bookmark
- `new_page_replacing` - `ei_page` and replace the current page in stack (so that F3 returns to the parent of the current page)
- `go_back_to_bookmark` - go back and skip all the page stack till the first bookmark (works with `new_page_w_bookmark`)
## Hotkey
TODO ...
In a nutshell:
```abap
" somewhere within render
gui_services( )->get_hotkeys_ctl( )->register_hotkeys( me ).
```
The component must implement `zif_abapgit_gui_hotkeys` and return list of keys, their human readable meaning and corresponding event to invoke.
```abap
METHOD zif_abapgit_gui_hotkeys~get_hotkey_actions.
DATA ls_hotkey_action LIKE LINE OF rt_hotkey_actions.
ls_hotkey_action-ui_component = 'Stage'. " <<< This is to define origin of hotkeys
ls_hotkey_action-description = |Patch|. " <<< Human readable description
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-go_patch. " <<< abapgit-wide action to open patch page
ls_hotkey_action-hotkey = |p|. " <<< Key
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-description = |Diff|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-go_diff.
ls_hotkey_action-hotkey = |d|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ENDMETHOD.
```

View File

@ -55,6 +55,7 @@ CLASS zcl_abapgit_gui DEFINITION
ii_asset_man TYPE REF TO zif_abapgit_gui_asset_manager OPTIONAL
ii_hotkey_ctl TYPE REF TO zif_abapgit_gui_hotkey_ctl OPTIONAL
ii_html_processor TYPE REF TO zif_abapgit_gui_html_processor OPTIONAL
iv_rollback_on_error TYPE abap_bool DEFAULT abap_true
RAISING
zcx_abapgit_exception.
@ -70,6 +71,7 @@ CLASS zcl_abapgit_gui DEFINITION
END OF ty_page_stack.
DATA:
mv_rollback_on_error TYPE abap_bool,
mi_cur_page TYPE REF TO zif_abapgit_gui_renderable,
mt_stack TYPE STANDARD TABLE OF ty_page_stack,
mt_event_handlers TYPE STANDARD TABLE OF REF TO zif_abapgit_gui_event_handler,
@ -191,6 +193,7 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION.
CREATE OBJECT mo_html_parts.
mv_rollback_on_error = iv_rollback_on_error.
mi_asset_man = ii_asset_man.
mi_hotkey_ctl = ii_hotkey_ctl.
mi_html_processor = ii_html_processor. " Maybe improve to middlewares stack ??
@ -288,7 +291,6 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION.
CATCH zcx_abapgit_cancel ##NO_HANDLER.
" Do nothing = gc_event_state-no_more_act
CATCH zcx_abapgit_exception INTO lx_exception.
ROLLBACK WORK.
handle_error( lx_exception ).
ENDTRY.
@ -300,6 +302,10 @@ CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION.
DATA: li_gui_error_handler TYPE REF TO zif_abapgit_gui_error_handler,
lx_exception TYPE REF TO cx_root.
IF mv_rollback_on_error = abap_true.
ROLLBACK WORK.
ENDIF.
TRY.
li_gui_error_handler ?= mi_cur_page.

View File

@ -72,145 +72,7 @@ ENDCLASS.
CLASS zcl_abapgit_html IMPLEMENTATION.
METHOD add_icon.
add( icon( iv_name = iv_name
iv_class = iv_class
iv_hint = iv_hint
iv_onclick = iv_onclick ) ).
ENDMETHOD.
METHOD checkbox.
DATA: lv_checked TYPE string.
IF iv_checked = abap_true.
lv_checked = |checked|.
ENDIF.
rv_html = |<input type="checkbox" id="{ iv_id }" { lv_checked }>|.
ENDMETHOD.
METHOD class_constructor.
CREATE OBJECT go_single_tags_re
EXPORTING
pattern = '<(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|LINK|META|PARAM|SOURCE|!)'
ignore_case = abap_false.
ENDMETHOD.
METHOD indent_line.
DATA: ls_study TYPE ty_study_result,
lv_x_str TYPE string.
ls_study = study_line(
is_context = cs_context
iv_line = cv_line ).
" First closing tag - shift back exceptionally
IF ( ls_study-script_close = abap_true
OR ls_study-style_close = abap_true
OR ls_study-curly_close = abap_true
OR ls_study-tag_close = abap_true )
AND cs_context-indent > 0.
lv_x_str = repeat( val = ` ` occ = ( cs_context-indent - 1 ) * c_indent_size ).
cv_line = lv_x_str && cv_line.
ELSE.
cv_line = cs_context-indent_str && cv_line.
ENDIF.
" Context status update
CASE abap_true.
WHEN ls_study-script_open.
cs_context-within_js = abap_true.
cs_context-within_style = abap_false.
WHEN ls_study-style_open.
cs_context-within_js = abap_false.
cs_context-within_style = abap_true.
WHEN ls_study-script_close OR ls_study-style_close.
cs_context-within_js = abap_false.
cs_context-within_style = abap_false.
ls_study-closings = ls_study-closings + 1.
ENDCASE.
" More-less logic chosen due to possible double tags in a line '<a><b>'
IF ls_study-openings <> ls_study-closings.
IF ls_study-openings > ls_study-closings.
cs_context-indent = cs_context-indent + 1.
ELSEIF cs_context-indent > 0. " AND ls_study-openings < ls_study-closings
cs_context-indent = cs_context-indent - 1.
ENDIF.
cs_context-indent_str = repeat( val = ` ` occ = cs_context-indent * c_indent_size ).
ENDIF.
ENDMETHOD.
METHOD study_line.
DATA: lv_line TYPE string,
lv_len TYPE i.
lv_line = to_upper( shift_left( val = iv_line sub = ` ` ) ).
lv_len = strlen( lv_line ).
" Some assumptions for simplification and speed
" - style & scripts tag should be opened/closed in a separate line
" - style & scripts opening and closing in one line is possible but only once
" TODO & Issues
" - What if the string IS a well formed html already not just single line ?
IF is_context-within_js = abap_true OR is_context-within_style = abap_true.
IF is_context-within_js = abap_true AND lv_len >= 8 AND lv_line(8) = '</SCRIPT'.
rs_result-script_close = abap_true.
ELSEIF is_context-within_style = abap_true AND lv_len >= 7 AND lv_line(7) = '</STYLE'.
rs_result-style_close = abap_true.
ENDIF.
IF is_context-no_indent_jscss = abap_false.
IF lv_len >= 1 AND lv_line(1) = '}'.
rs_result-curly_close = abap_true.
ENDIF.
FIND ALL OCCURRENCES OF '{' IN lv_line MATCH COUNT rs_result-openings.
FIND ALL OCCURRENCES OF '}' IN lv_line MATCH COUNT rs_result-closings.
ENDIF.
ELSE.
IF lv_len >= 7 AND lv_line(7) = '<SCRIPT'.
FIND FIRST OCCURRENCE OF '</SCRIPT' IN lv_line.
IF sy-subrc > 0. " Not found
rs_result-script_open = abap_true.
ENDIF.
ENDIF.
IF lv_len >= 6 AND lv_line(6) = '<STYLE'.
FIND FIRST OCCURRENCE OF '</STYLE' IN lv_line.
IF sy-subrc > 0. " Not found
rs_result-style_open = abap_true.
ENDIF.
ENDIF.
IF lv_len >= 2 AND lv_line(2) = '</'.
rs_result-tag_close = abap_true.
ENDIF.
FIND ALL OCCURRENCES OF '<' IN lv_line MATCH COUNT rs_result-openings.
FIND ALL OCCURRENCES OF '</' IN lv_line MATCH COUNT rs_result-closings.
FIND ALL OCCURRENCES OF REGEX go_single_tags_re IN lv_line MATCH COUNT rs_result-singles.
rs_result-openings = rs_result-openings - rs_result-closings - rs_result-singles.
ENDIF.
ENDMETHOD.
CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION.
METHOD a.
@ -316,14 +178,37 @@ CLASS zcl_abapgit_html IMPLEMENTATION.
ENDMETHOD.
METHOD zif_abapgit_html~add_checkbox.
METHOD add_icon.
add( checkbox( iv_id = iv_id
iv_checked = iv_checked ) ).
add( icon( iv_name = iv_name
iv_class = iv_class
iv_hint = iv_hint
iv_onclick = iv_onclick ) ).
ENDMETHOD.
METHOD checkbox.
DATA: lv_checked TYPE string.
IF iv_checked = abap_true.
lv_checked = |checked|.
ENDIF.
rv_html = |<input type="checkbox" id="{ iv_id }" { lv_checked }>|.
ENDMETHOD.
METHOD class_constructor.
CREATE OBJECT go_single_tags_re
EXPORTING
pattern = '<(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|LINK|META|PARAM|SOURCE|!)'
ignore_case = abap_false.
ENDMETHOD.
METHOD icon.
DATA: lv_hint TYPE string,
@ -360,6 +245,54 @@ CLASS zcl_abapgit_html IMPLEMENTATION.
ENDMETHOD.
METHOD indent_line.
DATA: ls_study TYPE ty_study_result,
lv_x_str TYPE string.
ls_study = study_line(
is_context = cs_context
iv_line = cv_line ).
" First closing tag - shift back exceptionally
IF ( ls_study-script_close = abap_true
OR ls_study-style_close = abap_true
OR ls_study-curly_close = abap_true
OR ls_study-tag_close = abap_true )
AND cs_context-indent > 0.
lv_x_str = repeat( val = ` ` occ = ( cs_context-indent - 1 ) * c_indent_size ).
cv_line = lv_x_str && cv_line.
ELSE.
cv_line = cs_context-indent_str && cv_line.
ENDIF.
" Context status update
CASE abap_true.
WHEN ls_study-script_open.
cs_context-within_js = abap_true.
cs_context-within_style = abap_false.
WHEN ls_study-style_open.
cs_context-within_js = abap_false.
cs_context-within_style = abap_true.
WHEN ls_study-script_close OR ls_study-style_close.
cs_context-within_js = abap_false.
cs_context-within_style = abap_false.
ls_study-closings = ls_study-closings + 1.
ENDCASE.
" More-less logic chosen due to possible double tags in a line '<a><b>'
IF ls_study-openings <> ls_study-closings.
IF ls_study-openings > ls_study-closings.
cs_context-indent = cs_context-indent + 1.
ELSEIF cs_context-indent > 0. " AND ls_study-openings < ls_study-closings
cs_context-indent = cs_context-indent - 1.
ENDIF.
cs_context-indent_str = repeat( val = ` ` occ = cs_context-indent * c_indent_size ).
ENDIF.
ENDMETHOD.
METHOD is_empty.
rv_yes = boolc( lines( mt_buffer ) = 0 ).
ENDMETHOD.
@ -383,4 +316,76 @@ CLASS zcl_abapgit_html IMPLEMENTATION.
CONCATENATE LINES OF lt_temp INTO rv_html SEPARATED BY cl_abap_char_utilities=>newline.
ENDMETHOD.
METHOD study_line.
DATA: lv_line TYPE string,
lv_len TYPE i.
lv_line = to_upper( shift_left( val = iv_line sub = ` ` ) ).
lv_len = strlen( lv_line ).
" Some assumptions for simplification and speed
" - style & scripts tag should be opened/closed in a separate line
" - style & scripts opening and closing in one line is possible but only once
" TODO & Issues
" - What if the string IS a well formed html already not just single line ?
IF is_context-within_js = abap_true OR is_context-within_style = abap_true.
IF is_context-within_js = abap_true AND lv_len >= 8 AND lv_line(8) = '</SCRIPT'.
rs_result-script_close = abap_true.
ELSEIF is_context-within_style = abap_true AND lv_len >= 7 AND lv_line(7) = '</STYLE'.
rs_result-style_close = abap_true.
ENDIF.
IF is_context-no_indent_jscss = abap_false.
IF lv_len >= 1 AND lv_line(1) = '}'.
rs_result-curly_close = abap_true.
ENDIF.
FIND ALL OCCURRENCES OF '{' IN lv_line MATCH COUNT rs_result-openings.
FIND ALL OCCURRENCES OF '}' IN lv_line MATCH COUNT rs_result-closings.
ENDIF.
ELSE.
IF lv_len >= 7 AND lv_line(7) = '<SCRIPT'.
FIND FIRST OCCURRENCE OF '</SCRIPT' IN lv_line.
IF sy-subrc > 0. " Not found
rs_result-script_open = abap_true.
ENDIF.
ENDIF.
IF lv_len >= 6 AND lv_line(6) = '<STYLE'.
FIND FIRST OCCURRENCE OF '</STYLE' IN lv_line.
IF sy-subrc > 0. " Not found
rs_result-style_open = abap_true.
ENDIF.
ENDIF.
IF lv_len >= 2 AND lv_line(2) = '</'.
rs_result-tag_close = abap_true.
ENDIF.
FIND ALL OCCURRENCES OF '<' IN lv_line MATCH COUNT rs_result-openings.
FIND ALL OCCURRENCES OF '</' IN lv_line MATCH COUNT rs_result-closings.
FIND ALL OCCURRENCES OF REGEX go_single_tags_re IN lv_line MATCH COUNT rs_result-singles.
rs_result-openings = rs_result-openings - rs_result-closings - rs_result-singles.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_html~add_checkbox.
add( checkbox( iv_id = iv_id
iv_checked = iv_checked ) ).
ENDMETHOD.
METHOD zif_abapgit_html~set_title.
zif_abapgit_html~mv_chunk_title = iv_title.
ENDMETHOD.
ENDCLASS.

View File

@ -18,6 +18,11 @@ INTERFACE zif_abapgit_html PUBLIC.
TYPES:
tty_table_of TYPE STANDARD TABLE OF REF TO zif_abapgit_html WITH DEFAULT KEY.
DATA mv_chunk_title TYPE string READ-ONLY. " Primarily for debug of posponed html parts
METHODS set_title
IMPORTING
iv_title TYPE string.
METHODS add
IMPORTING
!ig_chunk TYPE any .

View File

@ -11,17 +11,21 @@ CLASS zcl_abapgit_gui_component DEFINITION
hidden_forms TYPE string VALUE 'hidden_forms',
END OF c_html_parts.
METHODS constructor RAISING zcx_abapgit_exception.
PROTECTED SECTION.
DATA mi_gui_services TYPE REF TO zif_abapgit_gui_services.
METHODS register_deferred_script
IMPORTING
ii_part TYPE REF TO zif_abapgit_html
RAISING
zcx_abapgit_exception.
METHODS gui_services
RETURNING
VALUE(ri_gui_services) TYPE REF TO zif_abapgit_gui_services
RAISING
zcx_abapgit_exception.
PRIVATE SECTION.
DATA mi_gui_services TYPE REF TO zif_abapgit_gui_services.
ENDCLASS.
@ -29,14 +33,16 @@ ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_COMPONENT IMPLEMENTATION.
METHOD constructor.
mi_gui_services = zcl_abapgit_ui_factory=>get_gui_services( ).
METHOD gui_services.
IF mi_gui_services IS NOT BOUND.
mi_gui_services = zcl_abapgit_ui_factory=>get_gui_services( ).
ENDIF.
ri_gui_services = mi_gui_services.
ENDMETHOD.
METHOD register_deferred_script.
" TODO refactor to mi_gui_services getter !
zcl_abapgit_ui_factory=>get_gui_services( )->get_html_parts( )->add_part(
gui_services( )->get_html_parts( )->add_part(
iv_collection = c_html_parts-scripts
ii_part = ii_part ).
ENDMETHOD.

View File

@ -15,7 +15,6 @@ CLASS zcl_abapgit_gui_page DEFINITION PUBLIC ABSTRACT
TYPES:
BEGIN OF ty_control,
redirect_url TYPE string,
page_title TYPE string,
page_menu TYPE REF TO zcl_abapgit_html_toolbar,
END OF ty_control.
@ -35,7 +34,9 @@ CLASS zcl_abapgit_gui_page DEFINITION PUBLIC ABSTRACT
METHODS render_deferred_parts
IMPORTING
ii_html TYPE REF TO zif_abapgit_html
iv_part_category TYPE string.
iv_part_category TYPE string
RAISING
zcx_abapgit_exception.
METHODS html_head
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
@ -46,9 +47,6 @@ CLASS zcl_abapgit_gui_page DEFINITION PUBLIC ABSTRACT
METHODS footer
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS redirect
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_link_hints
IMPORTING
io_html TYPE REF TO zcl_abapgit_html
@ -181,20 +179,6 @@ CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION.
ENDMETHOD.
METHOD redirect.
CREATE OBJECT ro_html.
ro_html->add( '<!DOCTYPE html>' ). "#EC NOTEXT
ro_html->add( '<html>' ). "#EC NOTEXT
ro_html->add( '<head>' ). "#EC NOTEXT
ro_html->add( |<meta http-equiv="refresh" content="0; url={ ms_control-redirect_url }">| ). "#EC NOTEXT
ro_html->add( '</head>' ). "#EC NOTEXT
ro_html->add( '</html>' ). "#EC NOTEXT
ENDMETHOD.
METHOD render_command_palettes.
io_html->add( 'var gGoRepoPalette = new CommandPalette(enumerateTocAllRepos, {' ).
@ -215,7 +199,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION.
DATA lt_parts TYPE zif_abapgit_html=>tty_table_of.
DATA li_part LIKE LINE OF lt_parts.
lt_parts = mi_gui_services->get_html_parts( )->get_parts( iv_part_category ).
lt_parts = gui_services( )->get_html_parts( )->get_parts( iv_part_category ).
LOOP AT lt_parts INTO li_part.
ii_html->add( li_part ).
ENDLOOP.
@ -256,7 +240,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION.
DATA lo_hotkeys_component TYPE REF TO zif_abapgit_gui_renderable.
lo_hotkeys_component ?= mi_gui_services->get_hotkeys_ctl( ). " Mmmm ...
lo_hotkeys_component ?= gui_services( )->get_hotkeys_ctl( ). " Mmmm ...
ro_html = lo_hotkeys_component->render( ).
ENDMETHOD.
@ -366,13 +350,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION.
DATA: lo_script TYPE REF TO zcl_abapgit_html.
mi_gui_services->register_event_handler( me ).
" Redirect
IF ms_control-redirect_url IS NOT INITIAL.
ri_html = redirect( ).
RETURN.
ENDIF.
gui_services( )->register_event_handler( me ).
" Real page
CREATE OBJECT ri_html TYPE zcl_abapgit_html.

View File

@ -192,7 +192,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_CODE_INSP IMPLEMENTATION.
RETURN.
ENDIF.
mi_gui_services->get_hotkeys_ctl( )->register_hotkeys( me ).
gui_services( )->get_hotkeys_ctl( )->register_hotkeys( me ).
ro_html->add( '<div class="ci-head">' ).
ro_html->add( |Code inspector check variant: <span class="ci-variant">{ mv_check_variant }</span>| ).

View File

@ -392,6 +392,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_COMMIT IMPLEMENTATION.
CREATE OBJECT ro_html.
ro_html->zif_abapgit_html~set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ).
ro_html->add( 'setInitialFocus("comment");' ).
ENDMETHOD.

View File

@ -85,6 +85,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DEBUGINFO IMPLEMENTATION.
CREATE OBJECT ro_html.
ro_html->zif_abapgit_html~set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ).
ro_html->add( 'debugOutput("Browser: " + navigator.userAgent + ' &&
'"<br>Frontend time: " + new Date(), "debug_info");' ).

View File

@ -864,6 +864,8 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_DIFF IMPLEMENTATION.
CREATE OBJECT ro_html.
ro_html->zif_abapgit_html~set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ).
ro_html->add( 'restoreScrollPosition();' ).
ro_html->add( 'var gHelper = new DiffHelper({' ).
ro_html->add( | seed: "{ mv_seed }",| ).

View File

@ -45,7 +45,7 @@ ENDCLASS.
CLASS zcl_abapgit_gui_page_main IMPLEMENTATION.
CLASS ZCL_ABAPGIT_GUI_PAGE_MAIN IMPLEMENTATION.
METHOD build_main_menu.
@ -113,7 +113,7 @@ CLASS zcl_abapgit_gui_page_main IMPLEMENTATION.
retrieve_active_repo( ). " Get and validate key of user default repo
CREATE OBJECT ro_html.
mi_gui_services->get_hotkeys_ctl( )->register_hotkeys( me ).
gui_services( )->get_hotkeys_ctl( )->register_hotkeys( me ).
TRY.
lt_repos = zcl_abapgit_repo_srv=>get_instance( )->list( ).

View File

@ -580,7 +580,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_PATCH IMPLEMENTATION.
CLEAR: mv_pushed.
ENDIF.
mi_gui_services->get_hotkeys_ctl( )->register_hotkeys( me ).
gui_services( )->get_hotkeys_ctl( )->register_hotkeys( me ).
ro_html = super->render_content( ).
register_deferred_script( render_scripts( ) ).
@ -683,6 +683,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_PATCH IMPLEMENTATION.
CREATE OBJECT ro_html.
ro_html->zif_abapgit_html~set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ).
ro_html->add( 'preparePatch();' ).
ro_html->add( 'registerStagePatch();' ).

View File

@ -278,6 +278,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_REPO_OVER IMPLEMENTATION.
CREATE OBJECT ro_html.
ro_html->zif_abapgit_html~set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ).
ro_html->add( 'setInitialFocus("filter");' ).
ro_html->add( 'var gHelper = new RepoOverViewHelper();' ).

View File

@ -315,8 +315,8 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ro_html->add( '</div>' ).
mi_gui_services->get_hotkeys_ctl( )->register_hotkeys( me ).
mi_gui_services->get_html_parts( )->add_part(
gui_services( )->get_hotkeys_ctl( )->register_hotkeys( me ).
gui_services( )->get_html_parts( )->add_part(
iv_collection = zcl_abapgit_gui_component=>c_html_parts-hidden_forms
ii_part = render_deferred_hidden_events( ) ).
register_deferred_script( render_scripts( ) ).
@ -331,6 +331,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
ls_event-method = 'post'.
ls_event-name = 'stage_commit'.
ro_html = zcl_abapgit_gui_chunk_lib=>render_event_as_form( ls_event ).
ro_html->zif_abapgit_html~set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ).
ENDMETHOD.
@ -506,6 +507,8 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
CREATE OBJECT ro_html.
ro_html->zif_abapgit_html~set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ).
ro_html->add( 'var gStageParams = {' ).
ro_html->add( | seed: "{ mv_seed }",| ). " Unique page id
ro_html->add( | user: "{ to_lower( sy-uname ) }",| ).

View File

@ -345,6 +345,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_TAG IMPLEMENTATION.
CREATE OBJECT ro_html.
ro_html->zif_abapgit_html~set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ).
ro_html->add( 'setInitialFocus("name");' ).
ENDMETHOD.

View File

@ -922,7 +922,7 @@ CLASS ZCL_ABAPGIT_GUI_VIEW_REPO IMPLEMENTATION.
FIELD-SYMBOLS <ls_item> LIKE LINE OF lt_repo_items.
mi_gui_services->register_event_handler( me ).
gui_services( )->register_event_handler( me ).
" Reinit, for the case of type change
mo_repo = zcl_abapgit_repo_srv=>get_instance( )->get( mo_repo->get_key( ) ).

View File

@ -1,6 +1,7 @@
CLASS zcl_abapgit_hotkeys DEFINITION
PUBLIC
FINAL
INHERITING FROM zcl_abapgit_gui_component
CREATE PUBLIC .
PUBLIC SECTION.
@ -81,9 +82,10 @@ CLASS zcl_abapgit_hotkeys DEFINITION
RETURNING
VALUE(rt_interface_implementations) TYPE saboo_iimpt
RAISING
zcx_abapgit_exception,
zcx_abapgit_exception.
render_js_part
METHODS
render_scripts
IMPORTING
it_hotkeys TYPE zif_abapgit_gui_hotkeys=>tty_hotkey_with_descr
RETURNING
@ -259,7 +261,7 @@ CLASS ZCL_ABAPGIT_HOTKEYS IMPLEMENTATION.
ENDMETHOD.
METHOD render_js_part.
METHOD render_scripts.
DATA lv_json TYPE string.
DATA lt_hotkeys TYPE zif_abapgit_gui_hotkeys=>tty_hotkey_with_descr.
@ -281,6 +283,7 @@ CLASS ZCL_ABAPGIT_HOTKEYS IMPLEMENTATION.
lv_json = lv_json && `}`.
CREATE OBJECT ro_html.
ro_html->zif_abapgit_html~set_title( cl_abap_typedescr=>describe_by_object_ref( me )->get_relative_name( ) ).
ro_html->add( |setKeyBindings({ lv_json });| ).
ENDMETHOD.
@ -359,18 +362,7 @@ CLASS ZCL_ABAPGIT_HOTKEYS IMPLEMENTATION.
lt_registered_hotkeys = zif_abapgit_gui_hotkey_ctl~get_registered_hotkeys( ).
SORT lt_registered_hotkeys BY ui_component description.
" Note
" normally render method should be able to call mi_gui_services->get_html_parts( )
" thus the class must inherit from zcl_abapgit_gui_component
" but problem is that component constructor calls get_gui which creates gui if it is missing
" and the hotkeys class itself is created during get_gui so it is infinite loop
" solutions:
" A) separate hotkeys into logic and render (which is actually a good way, but it so nicely fit together ...)
" B) convert mi_gui_services to a getter - which I will do but later
zcl_abapgit_ui_factory=>get_gui_services( )->get_html_parts( )->add_part(
iv_collection = zcl_abapgit_gui_component=>c_html_parts-scripts
ii_part = render_js_part( lt_registered_hotkeys ) ).
register_deferred_script( render_scripts( lt_registered_hotkeys ) ).
" Render hotkeys
ri_html->add( '<ul class="hotkeys">' ).