ContextHelp.ts 5.25 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * This file is part of the TYPO3 CMS project.
 *
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 * The TYPO3 project - inspiring people to share!
 */

import 'bootstrap';
import * as $ from 'jquery';
import Popover = require('./Popover');

interface HelpData {
  title: string;
  content: string;
}

/**
 * Module: TYPO3/CMS/Backend/ContextHelp
 * API for context help.
 * @exports TYPO3/CMS/Backend/ContextHelp
 */
class ContextHelp {
  private ajaxUrl: string = TYPO3.settings.ajaxUrls.context_help;
  private helpModuleUrl: string;
  private trigger: string = 'click';
  private placement: string = 'auto';
33
  private selector: string = '.help-link';
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

  /**
   * @return {Window}
   */
  private static resolveBackend(): Window {
    if (typeof window.opener !== 'undefined' && window.opener !== null) {
      return window.opener.top;
    } else {
      return top;
    }
  }

  constructor() {
    this.initialize();
  }

  public initialize(): void {
    const backendWindow = ContextHelp.resolveBackend();
    if (typeof backendWindow.TYPO3.settings.ContextHelp !== 'undefined') {
      this.helpModuleUrl = backendWindow.TYPO3.settings.ContextHelp.moduleUrl;
    }

    if (typeof TYPO3.ShortcutMenu === 'undefined' && typeof backendWindow.TYPO3.ShortcutMenu === 'undefined') {
      // @FIXME: if we are in the popup... remove the bookmark / shortcut button
      // @TODO: make it possible to use the bookmark button also in popup mode
      $('.icon-actions-system-shortcut-new').closest('.btn').hide();
    }

    let title = ' ';
    if (typeof backendWindow.TYPO3.lang !== 'undefined') {
      title = backendWindow.TYPO3.lang.csh_tooltip_loading;
    }
    const $element = $(this.selector);
    $element
      .attr('data-loaded', 'false')
      .attr('data-html', 'true')
      .attr('data-original-title', title)
      .attr('data-placement', this.placement)
      .attr('data-trigger', this.trigger);
    Popover.popover($element);

    $(document).on('show.bs.popover', this.selector, (e: Event): void => {
      const $me = $(e.currentTarget);
      const description = $me.data('description');
      if (typeof description !== 'undefined' && description !== '') {
        Popover.setOptions($me, {
          title: $me.data('title'),
81
          content: description,
82
83
84
85
86
87
88
89
90
91
92
93
94
95
        });
      } else if ($me.attr('data-loaded') === 'false' && $me.data('table')) {
        this.loadHelp($me);
      }

      // if help icon is in DocHeader, force open to bottom
      if ($me.closest('.t3js-module-docheader').length) {
        Popover.setOption($me, 'placement', 'bottom');
      }
    }).on('shown.bs.popover', this.selector, (e: Event): void => {
      const $popover = $(e.target).data('bs.popover').$tip;
      if (!$popover.find('.popover-title').is(':visible')) {
        $popover.addClass('no-title');
      }
96
    }).on('click', '.help-has-link', (e: any): void => {
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
      $('.popover').each((index: number, popover: Element): void => {
        const $popover = $(popover);
        if ($popover.has(e.target).length) {
          this.showHelpPopup($popover.data('bs.popover').$element);
        }
      });
    }).on('click', 'body', (e: any): void => {
      $(this.selector).each((index: number, triggerElement: Element): void => {
        const $triggerElement = $(triggerElement);
        // the 'is' for buttons that trigger popups
        // the 'has' for icons within a button that triggers a popup
        if (!$triggerElement.is(e.target)
          && $triggerElement.has(e.target).length === 0
          && $('.popover').has(e.target).length === 0
        ) {
          Popover.hide($triggerElement);
        }
      });
    });
  }

  /**
   * Open the help popup
   *
   * @param {JQuery} $trigger
   */
  private showHelpPopup($trigger: JQuery): any {
    try {
      const cshWindow = window.open(
        this.helpModuleUrl +
127
128
        '&table=' + $trigger.data('table') +
        '&field=' + $trigger.data('field'),
129
        'ContextHelpWindow',
130
        'height=400,width=600,status=0,menubar=0,scrollbars=1',
131
132
133
134
      );
      cshWindow.focus();
      Popover.hide($trigger);
      return cshWindow;
135
    } catch {
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
      // do nothing
    }
  }

  /**
   * Load help data
   *
   * @param {JQuery} $trigger
   */
  private loadHelp($trigger: JQuery): void {
    const table = $trigger.data('table');
    const field = $trigger.data('field');
    // If a table is defined, use ajax call to get the tooltip's content
    if (table) {
      // Load content
      $.getJSON(this.ajaxUrl, {
        params: {
          action: 'getContextHelp',
          table: table,
155
156
          field: field,
        },
157
158
159
160
161
      }).done((data: HelpData): void => {
        const title = data.title || '';
        const content = data.content || '<p></p>';
        Popover.setOptions($trigger, {
          title: title,
162
          content: content,
163
164
165
166
167
168
169
170
171
172
173
174
175
        });
        $trigger
          .attr('data-loaded', 'true')
          .one('hidden.bs.popover', (): void => {
            Popover.show($trigger);
          });
        Popover.hide($trigger);
      });
    }
  }
}

export = new ContextHelp();