Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/**
17
 * An Icon System implementation for FontAwesome.
18
 *
19
 * @module core/icon_system_fontawesome
20
 * @copyright  2017 Damyon Wiese
21
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
 
24
import {call as fetchMany} from './ajax';
25
import LocalStorage from './localstorage';
26
import IconSystem from './icon_system';
27
import * as Mustache from './mustache';
28
import * as Config from './config';
29
import * as Url from './url';
30
 
31
/**
32
 * An set of properties for an icon.
33
 * @typedef {object} IconProperties
34
 * @property {array} attributes
35
 * @private
36
 */
37
 
38
/**
39
 * The FontAwesome icon system.
40
 */
41
export default class IconSystemFontawesome extends IconSystem {
42
    /**
43
     * @var {Map} staticMap A map of icon names to FA Icon.
44
     * @private
45
     */
46
    static staticMap = null;
47
 
48
    /**
49
     * @var {Promise} fetchPromise The promise used when fetching the result
50
     * @private
51
     */
52
    static fetchPromise = null;
53
 
54
    /**
55
     * @var {string} cacheKey The key used to store the icon map in LocalStorage.
56
     * @private
57
     */
58
    static cacheKey = `core_iconsystem/theme/${Config.theme}/core/iconmap-fontawesome`;
59
 
60
    /**
61
     * Prefetch resources so later calls to renderIcon can be resolved synchronously.
62
     *
63
     * @returns {Promise<IconSystemFontawesome>}
64
     */
65
    init() {
66
        if (IconSystemFontawesome.staticMap) {
67
            return Promise.resolve(this);
68
        }
69
 
70
        if (this.getMapFromCache()) {
71
            return Promise.resolve(this);
72
        }
73
 
74
        if (IconSystemFontawesome.fetchPromise) {
75
            return IconSystemFontawesome.fetchPromise;
76
        }
77
 
78
        return this.fetchMapFromServer();
79
    }
80
 
81
    /**
82
     * Get the icon map from LocalStorage.
83
     *
84
     * @private
85
     * @returns {Map}
86
     */
87
    getMapFromCache() {
88
        const map = LocalStorage.get(IconSystemFontawesome.cacheKey);
89
        if (map) {
90
            IconSystemFontawesome.staticMap = new Map(JSON.parse(map));
91
        }
92
        return IconSystemFontawesome.staticMap;
93
    }
94
 
95
    /**
96
     * Fetch the map data from the server.
97
     *
98
     * @private
99
     * @returns {Promise}
100
     */
101
    _fetchMapFromServer() {
102
        return fetchMany([{
103
            methodname: 'core_output_load_fontawesome_icon_system_map',
104
            args: {
105
                themename: Config.theme,
106
            },
107
        }], true, false, false, 0, Config.themerev)[0];
108
    }
109
 
110
    /**
111
     * Fetch the map data from the server.
112
     *
113
     * @returns {Promise<IconSystemFontawesome>}
114
     * @private
115
     */
116
    async fetchMapFromServer() {
117
        IconSystemFontawesome.fetchPromise = (async () => {
118
            const mapData = await this._fetchMapFromServer();
119
 
120
            IconSystemFontawesome.staticMap = new Map(Object.entries(mapData).map(([, value]) => ([
121
                `${value.component}/${value.pix}`,
122
                value.to,
123
            ])));
124
            LocalStorage.set(
125
                IconSystemFontawesome.cacheKey,
126
                JSON.stringify(Array.from(IconSystemFontawesome.staticMap.entries())),
127
            );
128
 
129
            return this;
130
        })();
131
 
132
        return IconSystemFontawesome.fetchPromise;
133
    }
134
 
135
    /**
136
     * Render an icon.
137
     *
138
     * @param {string} key
139
     * @param {string} component
140
     * @param {string} title
141
     * @param {string} template
142
     * @return {string} The rendered HTML content
143
     */
144
    renderIcon(key, component, title, template) {
145
        const iconKey = `${component}/${key}`;
146
        const mappedIcon = IconSystemFontawesome.staticMap.get(iconKey);
147
        const unmappedIcon = this.getUnmappedIcon(mappedIcon, key, component, title);
148
 
149
        const context = {
150
            title,
151
            unmappedIcon,
152
            alt: title,
153
            key: mappedIcon,
154
        };
155
 
156
        if (typeof title === "undefined" || title === '') {
157
            context['aria-hidden'] = true;
158
        }
159
 
160
        return Mustache.render(template, context).trim();
161
    }
162
 
163
    /**
164
     * Get the unmapped icon content, if the icon is not mapped.
165
     *
166
     * @param {IconProperties} mappedIcon
167
     * @param {string} key
168
     * @param {string} component
169
     * @param {string} title
170
     * @returns {IconProperties|null}
171
     * @private
172
     */
173
    getUnmappedIcon(mappedIcon, key, component, title) {
174
        if (mappedIcon) {
175
            return null;
176
        }
177
 
178
        return {
179
            attributes: [
180
                {name: 'src', value: Url.imageUrl(key, component)},
181
                {name: 'alt', value: title},
182
                {name: 'title', value: title}
183
            ],
184
        };
185
    }
186
 
187
    /**
188
     * Get the name of the template to pre-cache for this icon system.
189
     *
190
     * @return {string}
191
     * @method getTemplateName
192
     */
193
    getTemplateName() {
194
        return 'core/pix_icon_fontawesome';
195
    }
196
}