PageSourceSearch

https://www.abc.es/contentfactory/post/wp-content/uploads/sites/4/2020/09/skrollr.stylesheets.js

js abc.es collected 2026-10-01 06:52:10 UTC 7,927 bytes, 258 lines download raw bytes

vendor: 7,927 bytes, lines 1-258
1/*!
2 * skrollr stylesheets.
3 * Parses stylesheets and searches for skrollr keyframe declarations.
4 * Converts them to data-attributes.
5 * Doesn't expose any globals.
6 */
7(function(window, document, undefined) {
8	'use strict';
9
10	var content;
11	var contents = [];
12
13	//Finds the declaration of an animation block.
14	var rxAnimation = /@-skrollr-keyframes\s+([\w-]+)/g;
15
16	//Finds the block of keyframes inside an animation block.
17	//http://regexpal.com/ saves your ass with stuff like this.
18	var rxKeyframes = /\s*\{\s*((?:[^{]+\{[^}]*\}\s*)+?)\s*\}/g;
19
20	//Gets a single keyframe and the properties inside.
21	var rxSingleKeyframe = /([\w\-]+)\s*\{([^}]+)\}/g;
22
23	//Optional keyframe name prefix to work around SASS (>3.4) issues
24	var keyframeNameOptionalPrefix = 'skrollr-';
25
26	//Finds usages of the animation.
27	var rxAnimationUsage = /-skrollr-animation-name\s*:\s*([\w-]+)/g;
28
29	//Finds usages of attribute setters.
30	var rxAttributeSetter = /-skrollr-(anchor-target|smooth-scrolling|emit-events|menu-offset)\s*:\s*['"]([^'"]+)['"]/g;
31
32	var fetchRemote = function(url) {
33		var xhr = new XMLHttpRequest();
34
35		/*
36		 * Yes, these are SYNCHRONOUS requests.
37		 * Simply because skrollr stylesheets should run while the page is loaded.
38		 * Get over it.
39		 */
40		try {
41			xhr.open('GET', url, false);
42			xhr.send(null);
43		} catch (e) {
44			//Fallback to XDomainRequest if available
45			if (window.XDomainRequest) {
46				xhr = new XDomainRequest();
47				xhr.open('GET', url, false);
48				xhr.send(null);
49			}
50		}
51
52		return xhr.responseText;
53	};
54
55	//"main"
56	var kickstart = function(stylesheets) {
57		//Iterate over all stylesheets, embedded and remote.
58		for(var stylesheetIndex = 0; stylesheetIndex < stylesheets.length; stylesheetIndex++) {
59			var sheet = stylesheets[stylesheetIndex];
60
61			if(sheet.tagName === 'LINK') {
62				if(sheet.getAttribute('data-skrollr-stylesheet') === null) {
63					continue;
64				}
65
66				//Test media attribute if matchMedia available.
67				if(window.matchMedia) {
68					var media = sheet.getAttribute('media');
69
70					if(media && !matchMedia(media).matches) {
71						continue;
72					}
73				}
74
75				//Remote stylesheet, fetch it (synchrnonous).
76				content = fetchRemote(sheet.href);
77			} else {
78				//Embedded stylesheet, grab the node content.
79				content = sheet.textContent || sheet.innerText || sheet.innerHTML;
80			}
81
82			if(content) {
83				contents.push(content);
84			}
85		}
86
87		//We take the stylesheets in reverse order.
88		//This is needed to ensure correct order of stylesheets and inline styles.
89		contents.reverse();
90
91		var animations = {};
92		var selectors = [];
93		var attributes = [];
94
95		//Now parse all stylesheets.
96		for(var contentIndex = 0; contentIndex < contents.length; contentIndex++) {
97			content = contents[contentIndex];
98
99			parseAnimationDeclarations(content, animations);
100			parseAnimationUsage(content, selectors);
101			parseAttributeSetters(content, attributes);
102		}
103
104		applyKeyframeAttributes(animations, selectors);
105		applyAttributeSetters(attributes);
106	};
107
108	//Finds animation declarations and puts them into the output map.
109	var parseAnimationDeclarations = function(input, output) {
110		rxAnimation.lastIndex = 0;
111
112		var animation;
113		var rawKeyframes;
114		var keyframe;
115		var curAnimation;
116
117		while((animation = rxAnimation.exec(input)) !== null) {
118			//Grab the keyframes inside this animation.
119			rxKeyframes.lastIndex = rxAnimation.lastIndex;
120			rawKeyframes = rxKeyframes.exec(input);
121
122			//Grab the single keyframes with their CSS properties.
123			rxSingleKeyframe.lastIndex = 0;
124
125			//Save the animation in an object using it's name as key.
126			curAnimation = output[animation[1]] = {};
127
128			while((keyframe = rxSingleKeyframe.exec(rawKeyframes[1])) !== null) {
129				//Put all keyframes inside the animation using the keyframe (like botttom-top, or 100) as key
130				//and the properties as value (just the raw string, newline stripped).
131				curAnimation[keyframe[1]] = keyframe[2].replace(/[\n\r\t]/g, '');
132			}
133		}
134	};
135
136	//Extracts the selector of the given block by walking backwards to the start of the block.
137	var extractSelector = function(input, startIndex) {
138		var begin;
139		var end = startIndex;
140
141		//First find the curly bracket that opens this block.
142		while(end-- && input.charAt(end) !== '{') {}
143
144		//The end is now fixed to the right of the selector.
145		//Now start there to find the begin of the selector.
146		begin = end;
147
148		//Now walk farther backwards until we grabbed the whole selector.
149		//This either ends at beginning of string or at end of next block.
150		while(begin-- && input.charAt(begin - 1) !== '}') {}
151
152		//Return the cleaned selector.
153		return input.substring(begin, end).replace(/[\n\r\t]/g, '');
154	};
155
156	//Finds usage of animations and puts the selectors into the output array.
157	var parseAnimationUsage = function(input, output) {
158		var match;
159		var selector;
160
161		rxAnimationUsage.lastIndex = 0;
162
163		while((match = rxAnimationUsage.exec(input)) !== null) {
164			//Extract the selector of the block we found the animation in.
165			selector = extractSelector(input, rxAnimationUsage.lastIndex);
166
167			//Associate this selector with the animation name.
168			output.push([selector, match[1]]);
169		}
170	};
171
172	//Finds usage of attribute setters and puts the selector and attribute data into the output array.
173	var parseAttributeSetters = function(input, output) {
174		var match;
175		var selector;
176
177		rxAttributeSetter.lastIndex = 0;
178
179		while((match = rxAttributeSetter.exec(input)) !== null) {
180			//Extract the selector of the block we found the animation in.
181			selector = extractSelector(input, rxAttributeSetter.lastIndex);
182
183			//Associate this selector with the attribute name and value.
184			output.push([selector, match[1], match[2]]);
185		}
186	};
187
188	//Applies the keyframes (as data-attributes) to the elements.
189	var applyKeyframeAttributes = function(animations, selectors) {
190		var elements;
191		var keyframes;
192		var keyframeName;
193		var cleanKeyframeName;
194		var elementIndex;
195		var attributeName;
196		var attributeValue;
197		var curElement;
198
199		for(var selectorIndex = 0; selectorIndex < selectors.length; selectorIndex++) {
200			elements = document.querySelectorAll(selectors[selectorIndex][0]);
201
202			if(!elements) {
203				continue;
204			}
205
206			keyframes = animations[selectors[selectorIndex][1]];
207
208			for(keyframeName in keyframes) {
209				if(keyframeName.indexOf(keyframeNameOptionalPrefix) === 0) {
210					cleanKeyframeName = keyframeName.substring(keyframeNameOptionalPrefix.length);
211				} else {
212					cleanKeyframeName = keyframeName;
213				}
214
215				for(elementIndex = 0; elementIndex < elements.length; elementIndex++) {
216					curElement = elements[elementIndex];
217					attributeName = 'data-' + cleanKeyframeName;
218					attributeValue = keyframes[keyframeName];
219
220					//If the element already has this keyframe inline, give the inline one precedence by putting it on the right side.
221					//The inline one may actually be the result of the keyframes from another stylesheet.
222					//Since we reversed the order of the stylesheets, everything comes together correctly here.
223					if(curElement.hasAttribute(attributeName)) {
224						attributeValue += curElement.getAttribute(attributeName);
225					}
226
227					curElement.setAttribute(attributeName, attributeValue);
228				}
229			}
230		}
231	};
232
233	//Applies the keyframes (as data-attributes) to the elements.
234	var applyAttributeSetters = function(selectors) {
235		var curSelector;
236		var elements;
237		var attributeName;
238		var attributeValue;
239		var elementIndex;
240
241		for(var selectorIndex = 0; selectorIndex < selectors.length; selectorIndex++) {
242			curSelector = selectors[selectorIndex];
243			elements = document.querySelectorAll(curSelector[0]);
244			attributeName = 'data-' + curSelector[1];
245			attributeValue = curSelector[2];
246
247			if(!elements) {
248				continue;
249			}
250
251			for(elementIndex = 0; elementIndex < elements.length; elementIndex++) {
252				elements[elementIndex].setAttribute(attributeName, attributeValue);
253			}
254		}
255	};
256
257	kickstart(document.querySelectorAll('link, style'));
258}(window, document));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.