PluginProbe ʕ •ᴥ•ʔ
10Web Booster – Website speed optimization, Cache & Page Speed optimizer / 2.33.6
10Web Booster – Website speed optimization, Cache & Page Speed optimizer v2.33.6
2.33.6 2.33.5 2.33.0 2.30.5 2.30.7 2.30.9 2.31.10 2.31.8 2.32.11 2.32.21 2.32.3 2.32.4 2.32.7 2.6.31 2.6.40 2.6.42 2.6.7 2.7.37 2.7.44 2.7.47 2.8.18 2.8.19 2.8.32 2.8.34 2.8.35 2.9.23 2.9.24 2.9.25 2.9.27 v2.27.4 trunk 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.17 2.0.18 2.0.21 2.0.22 2.0.25 2.0.26 2.0.27 2.0.3 2.0.7 2.0.9 2.10.46 2.10.65 2.10.66 2.10.68 2.11.41 2.11.42 2.11.43 2.12.15 2.12.21 2.12.22 2.12.23 2.12.26 2.13.37 2.13.40 2.13.41 2.13.42 2.13.44 2.13.45 2.13.47 2.14.49 2.14.50 2.15.18 2.17.21 2.17.23 2.18.17 2.19.44 2.19.45 2.19.46 2.19.49 2.2.12 2.2.15 2.2.16 2.2.18 2.2.8 2.20.31 2.20.32 2.20.33 2.21.11 2.21.12 2.21.16 2.21.25 2.22.32 2.23.13 2.23.15 2.23.16 2.23.18 2.24.12 2.24.14 2.24.18 2.25.14 2.26.6 2.28.10 2.28.13 2.28.14 2.28.7 2.29.1 2.29.2 2.29.3 2.3.0 2.3.1 2.3.2 2.3.3 2.30.18
tenweb-speed-optimizer / includes / external / js / two_merge_google_font_faces.js
tenweb-speed-optimizer / includes / external / js Last commit date
vanilla-lazyload 4 months ago jquery.lazy.av.min.js 4 years ago jquery.lazy.iframe.min.js 4 years ago jquery.lazy.js 3 years ago jquery.lazy.min.js 3 years ago lazyload.min.js 4 years ago loader.js 1 week ago two_delay.js 1 week ago two_elementor_video_to_iframe.js 4 years ago two_lazyload.js 3 years ago two_merge_google_font_faces.js 3 years ago two_worker.js 2 years ago two_yt_vi_lazyload.js 3 years ago two_yt_vi_lazyload.min.js 3 years ago
two_merge_google_font_faces.js
255 lines
1 function two_merge_google_fonts(css_code) {
2 /* https://raw.githubusercontent.com/jotform/css.js/master/css.js */
3 /* jshint unused:false */
4
5 var two_cssjs = function () {
6 this.cssImportStatements = [];
7
8 this.cssRegex = new RegExp("([\\s\\S]*?){([\\s\\S]*?)}", "gi");
9 this.cssKeyframeRegex = "((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})";
10 this.combinedCSSRegex =
11 // eslint-disable-next-line max-len
12 "((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})";
13 //to match css & media queries together
14 this.cssCommentsRegex = "(\\/\\*[\\s\\S]*?\\*\\/)";
15 this.cssImportStatementRegex = new RegExp("@import .*?;", "gi");
16 };
17
18
19 /*
20 Parses given css string, and returns css object
21 keys as selectors and values are css rules
22 eliminates all css comments before parsing
23
24 @param source css string to be parsed
25
26 @return object css
27 */
28 two_cssjs.prototype.parseCSS = function (source) {
29 if (source === undefined) {
30 return [];
31 }
32
33 var css = [];
34 //strip out comments
35
36 //get import statements
37
38 while (true) {
39 var imports = this.cssImportStatementRegex.exec(source);
40 if (imports !== null) {
41 this.cssImportStatements.push(imports[0]);
42 css.push({
43 selector: "@imports",
44 type: "imports",
45 styles: imports[0],
46 });
47 } else {
48 break;
49 }
50 }
51 source = source.replace(this.cssImportStatementRegex, "");
52 //get keyframe statements
53 var keyframesRegex = new RegExp(this.cssKeyframeRegex, "gi");
54 var arr;
55 while (true) {
56 arr = keyframesRegex.exec(source);
57 if (arr === null) {
58 break;
59 }
60 css.push({
61 selector: "@keyframes",
62 type: "keyframes",
63 styles: arr[0],
64 });
65 }
66 source = source.replace(keyframesRegex, "");
67
68 //unified regex
69 var unified = new RegExp(this.combinedCSSRegex, "gi");
70
71 while (true) {
72 arr = unified.exec(source);
73 if (arr === null) {
74 break;
75 }
76 var selector = "";
77 if (arr[2] === undefined) {
78 selector = arr[5].split("\r\n").join("\n").trim();
79 } else {
80 selector = arr[2].split("\r\n").join("\n").trim();
81 }
82
83 /*
84 fetch comments and associate it with current selector
85 */
86 var commentsRegex = new RegExp(this.cssCommentsRegex, "gi");
87 var comments = commentsRegex.exec(selector);
88 if (comments !== null) {
89 selector = selector.replace(commentsRegex, "").trim();
90 }
91
92 // Never have more than a single line break in a row
93 selector = selector.replace(/\n+/, "\n");
94
95 //determine the type
96 if (selector.indexOf("@media") !== -1) {
97 //we have a media query
98 var cssObject = {
99 selector: selector,
100 type: "media",
101 subStyles: this.parseCSS(arr[3] + "\n}"), //recursively parse media query inner css
102 };
103 if (comments !== null) {
104 cssObject.comments = comments[0];
105 }
106 css.push(cssObject);
107 } else {
108 //we have standard css
109 var rules = this.parseRules(arr[6]);
110 var style = {
111 selector: selector,
112 rules: rules,
113 };
114 if (selector === "@font-face") {
115 style.type = "font-face";
116 }
117 if (comments !== null) {
118 style.comments = comments[0];
119 }
120 css.push(style);
121 }
122 }
123
124 return css;
125 };
126
127 /*
128 parses given string containing css directives
129 and returns an array of objects containing ruleName:ruleValue pairs
130
131 @param rules, css directive string example
132 \n\ncolor:white;\n font-size:18px;\n
133 */
134 two_cssjs.prototype.parseRules = function (rules) {
135 //convert all windows style line endings to unix style line endings
136 rules = rules.split("\r\n").join("\n");
137 var ret = [];
138
139 rules = rules.split(";");
140
141 //proccess rules line by line
142 for (var i = 0; i < rules.length; i++) {
143 var line = rules[i];
144
145 //determine if line is a valid css directive, ie color:white;
146 line = line.trim();
147 if (line.indexOf(":") !== -1) {
148 //line contains :
149 line = line.split(":");
150 var cssDirective = line[0].trim();
151 var cssValue = line.slice(1).join(":").trim();
152
153 //more checks
154 if (cssDirective.length < 1 || cssValue.length < 1) {
155 continue; //there is no css directive or value that is of length 1 or 0
156 // PLAIN WRONG WHAT ABOUT margin:0; ?
157 }
158
159 //push rule
160 ret.push({
161 directive: cssDirective,
162 value: cssValue,
163 });
164 } else {
165 //if there is no ':', but what if it was mis splitted value which starts with base64
166 if (line.trim().substr(0, 7) === "base64,") {
167 //hack :)
168 ret[ret.length - 1].value += line.trim();
169 } else {
170 //add rule, even if it is defective
171 if (line.length > 0) {
172 ret.push({
173 directive: "",
174 value: line,
175 defective: true,
176 });
177 }
178 }
179 }
180 }
181
182 return ret; //we are done!
183 };
184
185
186 let face_values = [
187 "ascent-override",
188 "descent-override",
189 "font-display",
190 "font-family",
191 "font-stretch",
192 "font-style",
193 "font-weight",
194 "font-feature-settings",
195 "font-variation-settings",
196 "line-gap-override",
197 "size-adjust",
198 "src",
199 "unicode-range"
200 ];
201
202 let css = new two_cssjs();
203 let font_faces = {};
204
205 for (let code of css.parseCSS(css_code)) {
206 if (code['type'] !== 'font-face') {
207 continue;
208 }
209
210 let ff = {};
211 for (let rule of code['rules']) {
212 ff[rule['directive']] = rule['value'];
213 }
214
215 let key_ = "";
216 for (let d of face_values) {
217 if (d !== 'font-weight') {
218 key_ += (ff[d]) ? ff[d] : "-";
219 }
220 }
221
222 if (!font_faces[key_]) {
223 font_faces[key_] = [];
224 }
225
226 font_faces[key_].push(ff);
227 }
228
229 let new_css = "";
230 for (let key_ in font_faces) {
231
232 let font_weights = [];
233 let face_css = "";
234 for (let face of font_faces[key_]) {
235 font_weights.push(parseInt(face['font-weight']));
236 if (face_css === "") {
237 for (let d in face) {
238 if (d !== 'font-weight') {
239 face_css += d + ":" + face[d] + ";";
240 }
241 }
242 }
243 }
244
245 if (font_weights.length === 1) {
246 face_css += 'font-weight:' + font_weights[0] + ";";
247 } else {
248 face_css += 'font-weight:' + Math.min(...font_weights) + " " + Math.max(...font_weights) + ";";
249 }
250
251 new_css += "@font-face {" + face_css + "}";
252 }
253
254 return new_css;
255 }