e9e4f07b28286e94a7086b6c35e7881c101999dd
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Resources / Private / TypeScript / Icons.ts
1 /*
2  * This file is part of the TYPO3 CMS project.
3  *
4  * It is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License, either version 2
6  * of the License, or any later version.
7  *
8  * For the full copyright and license information, please read the
9  * LICENSE.txt file that was distributed with this source code.
10  *
11  * The TYPO3 project - inspiring people to share!
12  */
13
14 import * as $ from 'jquery';
15
16 enum Sizes {
17   small = 'small',
18   default = 'default',
19   large = 'large',
20   overlay = 'overlay'
21 }
22
23 enum States {
24   default = 'default',
25   disabled = 'disabled'
26 }
27
28 enum MarkupIdentifiers {
29   default = 'default',
30   inline = 'inline'
31 }
32
33 interface Cache {
34   [key: string]: JQueryPromise<any>;
35 }
36
37 /**
38  * Module: TYPO3/CMS/Backend/Icons
39  * Uses the icon API of the core to fetch icons via AJAX.
40  */
41 class Icons {
42   public readonly sizes: any = Sizes;
43   public readonly states: any = States;
44   public readonly markupIdentifiers: any = MarkupIdentifiers;
45   private readonly cache: Cache = {};
46
47   /**
48    * Get the icon by its identifier
49    *
50    * @param {string} identifier
51    * @param {Sizes} size
52    * @param {string} overlayIdentifier
53    * @param {string} state
54    * @param {MarkupIdentifiers} markupIdentifier
55    * @returns {JQueryPromise<any>}
56    */
57   public getIcon(identifier: string,
58                  size: Sizes,
59                  overlayIdentifier?: string,
60                  state?: string,
61                  markupIdentifier?: MarkupIdentifiers): JQueryPromise<any> {
62     return $.when(this.fetch(identifier, size, overlayIdentifier, state, markupIdentifier));
63   }
64
65   /**
66    * Performs the AJAX request to fetch the icon
67    *
68    * @param {string} identifier
69    * @param {Sizes} size
70    * @param {string} overlayIdentifier
71    * @param {string} state
72    * @param {MarkupIdentifiers} markupIdentifier
73    * @returns {JQueryPromise<any>}
74    */
75   public fetch(identifier: string,
76                size: Sizes,
77                overlayIdentifier: string,
78                state: string,
79                markupIdentifier: MarkupIdentifiers): JQueryPromise<any> {
80     /**
81      * Icon keys:
82      *
83      * 0: identifier
84      * 1: size
85      * 2: overlayIdentifier
86      * 3: state
87      * 4: markupIdentifier
88      */
89     size = size || Sizes.default;
90     state = state || States.default;
91     markupIdentifier = markupIdentifier || MarkupIdentifiers.default;
92
93     const icon = [identifier, size, overlayIdentifier, state, markupIdentifier];
94     const cacheIdentifier = icon.join('_');
95
96     if (!this.isCached(cacheIdentifier)) {
97       this.putInCache(cacheIdentifier, $.ajax({
98         url: TYPO3.settings.ajaxUrls.icons,
99         dataType: 'html',
100         data: {
101           icon: JSON.stringify(icon)
102         },
103         success: (markup: string) => {
104           return markup;
105         }
106       }).promise());
107     }
108     return this.getFromCache(cacheIdentifier).done();
109   }
110
111   /**
112    * Check whether icon was fetched already
113    *
114    * @param {string} cacheIdentifier
115    * @returns {boolean}
116    */
117   private isCached(cacheIdentifier: string): boolean {
118     return typeof this.cache[cacheIdentifier] !== 'undefined';
119   }
120
121   /**
122    * Get icon from cache
123    *
124    * @param {string} cacheIdentifier
125    * @returns {JQueryPromise<any>}
126    */
127   private getFromCache(cacheIdentifier: string): JQueryPromise<any> {
128     return this.cache[cacheIdentifier];
129   }
130
131   /**
132    * Put icon into cache
133    *
134    * @param {string} cacheIdentifier
135    * @param {JQueryPromise<any>} markup
136    */
137   private putInCache(cacheIdentifier: string, markup: JQueryPromise<any>): void {
138     this.cache[cacheIdentifier] = markup;
139   }
140 }
141
142 let iconsObject: Icons;
143 try {
144   // fetch from opening window
145   if (window.opener && window.opener.TYPO3 && window.opener.TYPO3.Icons) {
146     iconsObject = window.opener.TYPO3.Icons;
147   }
148
149   // fetch from parent
150   if (parent && parent.window.TYPO3 && parent.window.TYPO3.Icons) {
151     iconsObject = parent.window.TYPO3.Icons;
152   }
153
154   // fetch object from outer frame
155   if (top && top.TYPO3.Icons) {
156     iconsObject = top.TYPO3.Icons;
157   }
158 } catch (e) {
159   // This only happens if the opener, parent or top is some other url (eg a local file)
160   // which loaded the current window. Then the browser's cross domain policy jumps in
161   // and raises an exception.
162   // For this case we are safe and we can create our global object below.
163 }
164
165 if (!iconsObject) {
166   iconsObject = new Icons();
167   TYPO3.Icons = iconsObject;
168 }
169
170 export = iconsObject;