]> git.sur5r.net Git - bacula/bacula/blob - gui/baculum/debian/missing-sources/framework/Web/Javascripts/source/tinymce-405/classes/html/Styles.js
baculum: Add missing-sources directory in debian metadata structure
[bacula/bacula] / gui / baculum / debian / missing-sources / framework / Web / Javascripts / source / tinymce-405 / classes / html / Styles.js
1 /**
2  * Styles.js
3  *
4  * Copyright, Moxiecode Systems AB
5  * Released under LGPL License.
6  *
7  * License: http://www.tinymce.com/license
8  * Contributing: http://www.tinymce.com/contributing
9  */
10
11 /**
12  * This class is used to parse CSS styles it also compresses styles to reduce the output size.
13  *
14  * @example
15  * var Styles = new tinymce.html.Styles({
16  *    url_converter: function(url) {
17  *       return url;
18  *    }
19  * });
20  *
21  * styles = Styles.parse('border: 1px solid red');
22  * styles.color = 'red';
23  *
24  * console.log(new tinymce.html.StyleSerializer().serialize(styles));
25  *
26  * @class tinymce.html.Styles
27  * @version 3.4
28  */
29 define("tinymce/html/Styles", [], function() {
30         return function(settings, schema) {
31                 /*jshint maxlen:255 */
32                 var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,
33                         urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,
34                         styleRegExp = /\s*([^:]+):\s*([^;]+);?/g,
35                         trimRightRegExp = /\s+$/,
36                         undef, i, encodingLookup = {}, encodingItems, invisibleChar = '\uFEFF';
37
38                 settings = settings || {};
39
40                 encodingItems = ('\\" \\\' \\; \\: ; : ' + invisibleChar).split(' ');
41                 for (i = 0; i < encodingItems.length; i++) {
42                         encodingLookup[encodingItems[i]] = invisibleChar + i;
43                         encodingLookup[invisibleChar + i] = encodingItems[i];
44                 }
45
46                 function toHex(match, r, g, b) {
47                         function hex(val) {
48                                 val = parseInt(val, 10).toString(16);
49
50                                 return val.length > 1 ? val : '0' + val; // 0 -> 00
51                         }
52
53                         return '#' + hex(r) + hex(g) + hex(b);
54                 }
55
56                 return {
57                         /**
58                          * Parses the specified RGB color value and returns a hex version of that color.
59                          *
60                          * @method toHex
61                          * @param {String} color RGB string value like rgb(1,2,3)
62                          * @return {String} Hex version of that RGB value like #FF00FF.
63                          */
64                         toHex: function(color) {
65                                 return color.replace(rgbRegExp, toHex);
66                         },
67
68                         /**
69                          * Parses the specified style value into an object collection. This parser will also
70                          * merge and remove any redundant items that browsers might have added. It will also convert non hex
71                          * colors to hex values. Urls inside the styles will also be converted to absolute/relative based on settings.
72                          *
73                          * @method parse
74                          * @param {String} css Style value to parse for example: border:1px solid red;.
75                          * @return {Object} Object representation of that style like {border: '1px solid red'}
76                          */
77                         parse: function(css) {
78                                 var styles = {}, matches, name, value, isEncoded, urlConverter = settings.url_converter, urlConverterScope = settings.url_converter_scope || this;
79
80                                 function compress(prefix, suffix) {
81                                         var top, right, bottom, left;
82
83                                         // Get values and check it it needs compressing
84                                         top = styles[prefix + '-top' + suffix];
85                                         if (!top) {
86                                                 return;
87                                         }
88
89                                         right = styles[prefix + '-right' + suffix];
90                                         if (top != right) {
91                                                 return;
92                                         }
93
94                                         bottom = styles[prefix + '-bottom' + suffix];
95                                         if (right != bottom) {
96                                                 return;
97                                         }
98
99                                         left = styles[prefix + '-left' + suffix];
100                                         if (bottom != left) {
101                                                 return;
102                                         }
103
104                                         // Compress
105                                         styles[prefix + suffix] = left;
106                                         delete styles[prefix + '-top' + suffix];
107                                         delete styles[prefix + '-right' + suffix];
108                                         delete styles[prefix + '-bottom' + suffix];
109                                         delete styles[prefix + '-left' + suffix];
110                                 }
111
112                                 /**
113                                  * Checks if the specific style can be compressed in other words if all border-width are equal.
114                                  */
115                                 function canCompress(key) {
116                                         var value = styles[key], i;
117
118                                         if (!value || value.indexOf(' ') < 0) {
119                                                 return;
120                                         }
121
122                                         value = value.split(' ');
123                                         i = value.length;
124                                         while (i--) {
125                                                 if (value[i] !== value[0]) {
126                                                         return false;
127                                                 }
128                                         }
129
130                                         styles[key] = value[0];
131
132                                         return true;
133                                 }
134
135                                 /**
136                                  * Compresses multiple styles into one style.
137                                  */
138                                 function compress2(target, a, b, c) {
139                                         if (!canCompress(a)) {
140                                                 return;
141                                         }
142
143                                         if (!canCompress(b)) {
144                                                 return;
145                                         }
146
147                                         if (!canCompress(c)) {
148                                                 return;
149                                         }
150
151                                         // Compress
152                                         styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c];
153                                         delete styles[a];
154                                         delete styles[b];
155                                         delete styles[c];
156                                 }
157
158                                 // Encodes the specified string by replacing all \" \' ; : with _<num>
159                                 function encode(str) {
160                                         isEncoded = true;
161
162                                         return encodingLookup[str];
163                                 }
164
165                                 // Decodes the specified string by replacing all _<num> with it's original value \" \' etc
166                                 // It will also decode the \" \' if keep_slashes is set to fale or omitted
167                                 function decode(str, keep_slashes) {
168                                         if (isEncoded) {
169                                                 str = str.replace(/\uFEFF[0-9]/g, function(str) {
170                                                         return encodingLookup[str];
171                                                 });
172                                         }
173
174                                         if (!keep_slashes) {
175                                                 str = str.replace(/\\([\'\";:])/g, "$1");
176                                         }
177
178                                         return str;
179                                 }
180
181                                 function processUrl(match, url, url2, url3, str, str2) {
182                                         str = str || str2;
183
184                                         if (str) {
185                                                 str = decode(str);
186
187                                                 // Force strings into single quote format
188                                                 return "'" + str.replace(/\'/g, "\\'") + "'";
189                                         }
190
191                                         url = decode(url || url2 || url3);
192
193                                         // Convert the URL to relative/absolute depending on config
194                                         if (urlConverter) {
195                                                 url = urlConverter.call(urlConverterScope, url, 'style');
196                                         }
197
198                                         // Output new URL format
199                                         return "url('" + url.replace(/\'/g, "\\'") + "')";
200                                 }
201
202                                 if (css) {
203                                         // Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing
204                                         css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(str) {
205                                                 return str.replace(/[;:]/g, encode);
206                                         });
207
208                                         // Parse styles
209                                         while ((matches = styleRegExp.exec(css))) {
210                                                 name = matches[1].replace(trimRightRegExp, '').toLowerCase();
211                                                 value = matches[2].replace(trimRightRegExp, '');
212
213                                                 if (name && value.length > 0) {
214                                                         // Opera will produce 700 instead of bold in their style values
215                                                         if (name === 'font-weight' && value === '700') {
216                                                                 value = 'bold';
217                                                         } else if (name === 'color' || name === 'background-color') { // Lowercase colors like RED
218                                                                 value = value.toLowerCase();
219                                                         }
220
221                                                         // Convert RGB colors to HEX
222                                                         value = value.replace(rgbRegExp, toHex);
223
224                                                         // Convert URLs and force them into url('value') format
225                                                         value = value.replace(urlOrStrRegExp, processUrl);
226                                                         styles[name] = isEncoded ? decode(value, true) : value;
227                                                 }
228
229                                                 styleRegExp.lastIndex = matches.index + matches[0].length;
230                                         }
231
232                                         // Compress the styles to reduce it's size for example IE will expand styles
233                                         compress("border", "");
234                                         compress("border", "-width");
235                                         compress("border", "-color");
236                                         compress("border", "-style");
237                                         compress("padding", "");
238                                         compress("margin", "");
239                                         compress2('border', 'border-width', 'border-style', 'border-color');
240
241                                         // Remove pointless border, IE produces these
242                                         if (styles.border === 'medium none') {
243                                                 delete styles.border;
244                                         }
245                                 }
246
247                                 return styles;
248                         },
249
250                         /**
251                          * Serializes the specified style object into a string.
252                          *
253                          * @method serialize
254                          * @param {Object} styles Object to serialize as string for example: {border: '1px solid red'}
255                          * @param {String} element_name Optional element name, if specified only the styles that matches the schema will be serialized.
256                          * @return {String} String representation of the style object for example: border: 1px solid red.
257                          */
258                         serialize: function(styles, element_name) {
259                                 var css = '', name, value;
260
261                                 function serializeStyles(name) {
262                                         var styleList, i, l, value;
263
264                                         styleList = schema.styles[name];
265                                         if (styleList) {
266                                                 for (i = 0, l = styleList.length; i < l; i++) {
267                                                         name = styleList[i];
268                                                         value = styles[name];
269
270                                                         if (value !== undef && value.length > 0) {
271                                                                 css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
272                                                         }
273                                                 }
274                                         }
275                                 }
276
277                                 // Serialize styles according to schema
278                                 if (element_name && schema && schema.styles) {
279                                         // Serialize global styles and element specific styles
280                                         serializeStyles('*');
281                                         serializeStyles(element_name);
282                                 } else {
283                                         // Output the styles in the order they are inside the object
284                                         for (name in styles) {
285                                                 value = styles[name];
286
287                                                 if (value !== undef && value.length > 0) {
288                                                         css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
289                                                 }
290                                         }
291                                 }
292
293                                 return css;
294                         }
295                 };
296         };
297 });