PageSourceSearch

https://www.toyota.fi/libs/dam/components/scene7/dynamicmedia/clie…dia.min.4359841c1548e10f7e373b60fc525c75.js

js toyota.fi collected 2026-09-24 19:42:17 UTC 16,790 bytes, 512 lines download raw bytes

1/*
2 * ADOBE CONFIDENTIAL
3 *
4 * Copyright 2016 Adobe Systems Incorporated
5 * All Rights Reserved.
6 *
7 * NOTICE:  All information contained herein is, and remains
8 * the property of Adobe Systems Incorporated and its suppliers,
9 * if any.  The intellectual and technical concepts contained
10 * herein are proprietary to Adobe Systems Incorporated and its
11 * suppliers and may be covered by U.S. and Foreign Patents,
12 * patents in process, and are protected by trade secret or copyright law.
13 * Dissemination of this information or reproduction of this material
14 * is strictly forbidden unless prior written permission is obtained
15 * from Adobe Systems Incorporated.
16 */
17(function () {
18  'use strict';
19
20  var COMP_SELECTOR = '.s7dm-dynamic-media';
21  var VIEWER_JS = {
22    BasicZoomViewer: 'html5/js/BasicZoomViewer.js',
23    FlyoutViewer: 'html5/js/FlyoutViewer.js',
24    MixedMediaViewer: 'html5/js/MixedMediaViewer.js',
25    SpinViewer: 'html5/js/SpinViewer.js',
26    VideoViewer: 'html5/js/VideoViewer.js',
27    ZoomViewer: 'html5/js/ZoomViewer.js',
28    ZoomVerticalViewer: 'html5/js/ZoomVerticalViewer.js',
29    Responsive: 'libs/responsive_image.js',
30  };
31  var responsiveViewerCSS = 's7responsiveViewer'; //defined in responsive.css
32
33 const VideoSize = {
34    Size800 : 800,
35    Size1050 : 1050,
36    Size1080 : 1080,
37  }
38  
39 const VideoBitrate = {
40    Bitrate730 : 730,
41    Bitrate2000 : 2000,
42    Bitrate3000 : 3000,
43  }
44  
45  const VideoBreakpoints = {
46    MaxSmall : 767,
47    MaxTablet : 1199,
48  }
49
50  $(document).ready(function () {
51    //do nothing if there is no component due to no asset yet or DM disabled
52    if ($(COMP_SELECTOR).length > 0) {
53      var viewers = new S7dmUtils.Viewer();
54      var viewerRootPath = $(COMP_SELECTOR).data('viewer-path');
55      var viewerType = $(COMP_SELECTOR).data('viewer-type');
56      var pageLocale = $(COMP_SELECTOR).data('page-locale');
57      var s7i18nPath = '/libs/dam/components/scene7/common/clientlibs/i18n.js';
58      if (typeof Granite != 'undefined' && typeof Granite.I18n != 'undefined') {
59        Granite.I18n.setLocale(pageLocale);
60        s7i18nPath = Granite.HTTP.externalize(s7i18nPath);
61      }
62      $('head').append('<script type="text/javascript" src="' + s7i18nPath + '"></script>');
63      var viewerJs = Object.keys(VIEWER_JS).reduce(function (accumulator, type) {
64        if (viewerType.indexOf(type) !== -1) {
65          accumulator[type] = VIEWER_JS[type];
66        }
67        return accumulator;
68      }, {});
69      viewers.load(viewerJs, viewerRootPath).ready({
70        success: initViewers,
71        fail: failViewerLoader,
72      });
73    }
74  });
75
76  const format = ({ videoPath, size, bitRate, contentserver}) => {
77    return videoPath.replace('{height}', size.toString())
78    .replace('{bitrate}', bitRate.toString())
79    .replace(contentserver, '');
80  }
81
82  const getVideoSource = (videoPath, contentserver) => {
83    const width = window.innerWidth;
84  
85    if (width <= VideoBreakpoints.MaxSmall) {
86      return format({
87        videoPath,
88        size: VideoSize.Size800,
89        bitRate: VideoBitrate.Bitrate730,
90        contentserver,
91      });
92    }
93  
94    if (width <= VideoBreakpoints.MaxTablet) {
95      return format({
96        videoPath,
97        size: VideoSize.Size1050,
98        bitRate: VideoBitrate.Bitrate2000,
99        contentserver,
100      });
101    }
102  
103    return format({
104      videoPath,
105      size: VideoSize.Size1080,
106      bitRate: VideoBitrate.Bitrate3000,
107      contentserver,
108    });
109  };
110
111  /**
112   * Viewer intialization for interactive media component
113   */
114  function initViewers() {
115    var components = $(COMP_SELECTOR);
116    components.each(function () {
117      setupViewer($(this));
118    });
119  }
120
121  /**
122   * Setup viewer based on component
123   * @param component a div component contains viewer config
124   */
125  function setupViewer(component) {
126    const { assetType, viewerType, mode, stagesize: stageSize, encodesPath } = component.data();
127    var compId = component.attr('id');
128    var viewer = S7dmUtils[compId];
129
130    if (typeof viewer != 'undefined' && viewer != null) {
131      if (viewer.containerId === compId) {
132        return;
133      }
134
135      viewer.dispose();
136      S7dmUtils[compId] = null;
137      component.removeClass(responsiveViewerCSS);
138    }
139
140    component.html('');
141
142    if (viewerType) {
143      var viewerParams = buildViewerParams(component);
144      var viewerSettings = { containerId: component.attr('id'), params: viewerParams };
145      if (!(viewerType == 'FlyoutViewer' && stageSize)) {
146        component.addClass(responsiveViewerCSS);
147      }
148      viewer = new s7viewers[viewerType](viewerSettings);
149      if (typeof Granite != 'undefined' && typeof Granite.I18n != 'undefined') {
150        viewer.setLocalizedTexts(getLocalizedText()); //passing localized text to the viewer
151      }
152      S7dmUtils[compId] = viewer;
153
154      viewer.init();
155      var videoViewerElement = $('#' + compId);
156      var videoElement ;
157      
158      const observer = new MutationObserver(mutationList => {
159        mutationList.filter(m => m.type === 'childList').forEach(m => {
160          m.addedNodes.forEach(node => {
161            if (node.tagName === 'VIDEO') {
162              videoElement = videoViewerElement.find('video');
163              //inject alt text on video element
164              videoViewerElement.find('video:not([alt])').attr('alt', videoViewerElement.attr('data-alt'));
165              //inject lazy loading on video element
166              videoElement.addClass('lazyload');
167              videoElement.attr('preload', 'metadata');
168              videoElement.attr('data-encodes', encodesPath ? 'yes' : 'no');
169              //inject autoplay on video if applicable
170              if (videoViewerElement.attr('data-autoplay') !== undefined) {
171                videoElement.attr('autoplay', true);
172                videoElement[0].muted = true;
173              }
174              videoElement.attr('data-should-always-play', true);
175              //inject loop on video if applicable
176              videoElement.attr('loop', videoViewerElement.attr('data-loop'));
177              if (!videoElement.find('track').length) {
178                //inject subtitles after source
179                var subtitleSource = videoViewerElement.attr('data-subtitlePath');
180                var locale = videoViewerElement.attr('data-page-locale');
181                if (subtitleSource) {
182                  $('<track src="' + subtitleSource + '" kind="subtitles" srclang="' + locale + '" default>').insertAfter(
183                    videoViewerElement.find('video source')
184                  );
185                }
186              }
187            }
188          });
189        });
190      });
191      observer.observe(videoViewerElement[0], { childList: true, subtree: true }); 
192    } else if (assetType === 'image') {
193      if (component.data('breakpoints') || mode == 'smartcrop') {
194        buildResponsiveImage(component);
195      } else {
196        buildImage(component);
197      }
198    }
199  }
200
201  /**
202   * Build Image and anchor when there is no viewer constructor defined for IMAGE ONLY
203   * @param component a div component contains viewer config
204   */
205  function buildImage(component) {
206    var stageSize = component.data('stagesize'),
207      linkURL = component.data('linkurl'),
208      linkTarget = component.data('linktarget'),
209      title = component.data('title'),
210      altText = component.data('alt'),
211      imagePreset = component.data('imagepreset'),
212      imageServer = component.data('imageserver'),
213      modifiers = component.data('urlmodifiers');
214
215    var imgSetup = {
216      src: imageServer + component.data('asset-path'),
217    };
218    if (imagePreset) {
219      imgSetup['src'] += '?$' + imagePreset + '$';
220    }
221    if (modifiers) {
222      imgSetup['src'] += (imagePreset ? '&' : '?') + modifiers;
223    }
224
225    if (stageSize) {
226      var stageSizeParts = stageSize.split(',');
227      imgSetup['width'] = stageSizeParts[0];
228      if (stageSizeParts.length > 1) {
229        imgSetup['height'] = stageSizeParts[1];
230      }
231    }
232
233    var imgComp = $('<img>', imgSetup);
234    //if there is link, wrap it around image
235    if (linkURL) {
236      var anchorSetup = {
237        href: linkURL,
238        target: linkTarget,
239      };
240      if (altText) {
241        anchorSetup['alt'] = altText;
242        anchorSetup['title'] = altText; // default to alt text
243        imgComp.attr('alt', altText);
244      }
245      if (title) {
246        anchorSetup['title'] = title;
247      }
248      var anchor = $('<a>', anchorSetup);
249      anchor.append(imgComp);
250      component.append(anchor);
251    } else {
252      //Add alt text if it's set
253      if (altText) {
254        imgComp.attr('alt', altText);
255      }
256      component.append(imgComp);
257    }
258  }
259
260  /**
261   * Build responsive image
262   * @param component container
263   */
264  function buildResponsiveImage(component) {
265    var imagePreset = component.data('imagepreset'),
266      imageServer = component.data('imageserver'),
267      linkURL = component.data('linkurl'),
268      linkTarget = component.data('linktarget'),
269      title = component.data('title'),
270      altText = component.data('alt');
271    var modifiers = component.data('urlmodifiers');
272    var respCon = $('<div>', { class: 's7responsiveContainer ' + component.data('aspectratio') });
273    var respImgId = component.attr('id') + '_resp';
274    var respImgSetup = {
275      id: respImgId,
276      src: imageServer + component.data('asset-path') + '?qlt=10',
277      'data-src': imageServer + component.data('asset-path'),
278      class: 'img-fluid',
279      'data-mode': component.data('mode'),
280      'data-breakpoints': component.data('breakpoints'),
281    };
282    if (imagePreset) {
283      respImgSetup['data-src'] += '?$' + imagePreset + '$';
284    }
285    if (modifiers) {
286      respImgSetup['data-src'] += (imagePreset ? '&' : '?') + modifiers;
287    }
288    var respImg = $('<img>', respImgSetup);
289    //if there is link, wrap it around image
290    if (linkURL) {
291      var anchorSetup = {
292        href: linkURL,
293        target: linkTarget,
294      };
295      if (altText) {
296        anchorSetup['alt'] = altText;
297        anchorSetup['title'] = altText; // default to alt text
298        respImg.attr('alt', altText);
299      }
300      if (title) {
301        anchorSetup['title'] = title;
302      }
303      var anchor = $('<a>
303', anchorSetup);
304      anchor.append(respImg);
305      respCon.append(anchor);
306    } else {
307      if (altText) {
308        respImg.attr('alt', altText);
309      }
310      respCon.append(respImg);
311    }
312    component.append(respCon);
313    var isEditor = document.cookie.indexOf('wcmmode=edit') !== -1;
314
315    //Handle lazy loading of Dynamic Image
316    $(respImg).attr('loaded', false);
317
318    var lazyloadImage = function () {
319      var $image = $('#' + respImgId);
320      var alreadyLoaded = $image.attr('loaded');
321      if (isEditor || visibleDynamicElement(respImgId, alreadyLoaded)) {
322        $image.attr('loaded', true);
323        s7responsiveImage(document.getElementById(respImgId));
324      }
325    };
326
327    lazyloadImage();
328
329    window.addEventListener('scroll', function () {
330      lazyloadImage();
331    });
332
333    $(document).on('click', '.nav-link', function () {
334      if ($('#cmp-top-navigation')) {
335        lazyloadImage();
336      }
337    });
338
339    //Handle lazy loading of Dynamic Images that are not visible by default (e.g. accordion items)
340    var respondToVisibility = function respondToVisibility(element, callback) {
341     var options = {
342       root: document.documentElement
343     };
344     var observer = new IntersectionObserver(function (entries) {
345       entries.forEach(function (entry) {
346         callback(entry.intersectionRatio > 0);
347       });
348     }, options);
349
350     observer.observe(element);
351   };
352
353    respondToVisibility(document.getElementById(respImgId), function (visible) {
354     if (visible) {
355       lazyloadImage();
356     }
357   });
358  }
359
360  /**
361   * @param component a div element with viewer setup
362   * @return viewer parameters in JSON
363   */
364  function buildViewerParams(component) {
365    var assetPath = component.data('asset-path'),
366      assetType = component.data('asset-type'),
367      viewerType = component.data('viewer-type'),
368      imageserver = component.data('imageserver'),
369      videoserver = component.data('videoserver'),
370      contentserver = component.data('contenturl'),
371      config = component.data('config'),
372      wcmdisabled = component.data('wcmdisabled'),
373      stageSize = component.data('stagesize'),
374      viewerModifiers = component.data('viewermodifiers'),
375      isdms7 = component.data('dms7'),
376      encodesPath = component.data('encodes-path'),
377      videoPath = encodesPath ? getVideoSource(encodesPath, contentserver) : assetPath;
378
379    var viewerParams = {
380      asset: videoPath,
381      serverurl: imageserver,
382      contenturl: contentserver,
383    };
384
385    //Add extra viewer modifiers if any
386    if (viewerModifiers) {
387      $.extend(viewerParams, getViewerModifiers(viewerModifiers));
388    }
389
390    var isAuthor = !wcmdisabled && wcmdisabled != '';
391
392    //Add cache=off when WCM is not disabled (author side)
393    if (isAuthor) {
394      viewerParams['asset'] += '?cache=off';
395    }
396    if (stageSize) {
397      viewerParams['stagesize'] = stageSize;
398    }
399    if (viewerType == 'FlyoutViewer') {
400      viewerParams['imagereload'] = '1,breakpoint,100;320;480';
401    }
402    if (assetPath.indexOf('/') != 0) {
403      viewerParams['aemmode'] = '0';
404    }
405
406    //For video, we add videoserverurl
407    if (viewerType.indexOf('Video') >= 0 || viewerType.indexOf('Mixed') >= 0) {
408      viewerParams['videoserverurl'] = videoserver;
409      // force native if
410      // Asset is non-AVS video (apply to both DMS7 and DM Hybrid for playing progressively) OR
411      // (Asset is DMS7 video regardless of AVS or non-AVS AND the page is on author side)
412      if (assetType == 'video' || (typeof isdms7 != 'undefined' && isAuthor)) {
413        viewerParams['playback'] = 'native';
414        viewerParams['progressivebitrate'] = '20000';
415      }
416    }
417    //check for viewer preset setup
418    if (typeof config != 'undefined' && config.length > 0) {
419      viewerParams['config'] = getViewerPresetPath(config);
420    }
421    return viewerParams;
422  }
423
424  /**
425   * Parse viewer preset path for viewer-usable format
426   * @param config viewer preset path stored in the component node
427   * @return viewer-usable format viewer preset path
428   */
429  function getViewerPresetPath(config) {
430    var configParts = config.split('|');
431    return configParts[0];
432  }
433
434  /**
435   * Parse viewer preset path for isCustom Preset flag
436   * @param config viewer preset string
437   * @return flag for custom preset
438   */
439  function isCustomPreset(config) {
440    var configParts = config.split('|');
441    return configParts[2];
442  }
443
444  /**
445   * Fail viewer loader handler
446   */
447  function failViewerLoader() {
448    console.log('S7Viewer is missing');
449  }
450
451  /**
452   * Parse free-form viewer modifiers
453   * @param viewerModifiers string for free-form viewer modifiers
454   * @return JSON representing viewer modifiers
455   */
456  function getViewerModifiers(viewerModifiers) {
457    var modifiers = {};
458    if (viewerModifiers) {
459      var items = viewerModifiers.split('&');
460      for (var i = 0; i < items.length; i++) {
461        //only when there is key=val pair
462        if (items[i].indexOf('=') > 0) {
463          var key = items[i].substring(0, items[i].indexOf('='));
464          var val = items[i].substring(items[i].indexOf('=') + 1);
465          modifiers[key] = val;
466        }
467      }
468    }
469    return modifiers;
470  }
471
472  /**
473   * Get localized text for viewer from s7sdk_i18n.localizedText
474   * @return JSON for localized text
475   */
476  function getLocalizedText() {
477    var localizedText = {};
478    localizedText[Granite.I18n.getLocale()] = formatLocalizedText(s7sdk_i18n.localizedText);
479    localizedText['defaultLocale'] = Granite.I18n.getLocale();
480    return localizedText;
481  }
482
483  /**
484   * Format localized text into a correct viewer format
485   * @param localizedText localized text parsed from s7sdk
486   * @return formatted localized text with correct key for viewer
487   */
488  function formatLocalizedText(localizedText) {
489    var formatTexts = {};
490    for (var compKey in localizedText) {
491      var compObj = localizedText[compKey];
492      for (var symbolKey in compObj) {
493        var modKey = compKey + '.' + symbolKey;
494        var symbolVal = compObj[symbolKey];
495        formatTexts[modKey] = symbolVal;
496      }
497    }
498    return formatTexts;
499  }
500
501  //Check if element is within view
502  function visibleDynamicElement(elementId, alreadyLoaded) {
503    if (alreadyLoaded === 'true') {
504      return false;
505    }
506    var imageOffset = $('#' + elementId).offset().top;
507    var imageOuterHeight = imageOffset + $('#' + elementId).outerHeight();
508    var imageScrollTop = $(window).scrollTop();
509    var imageDistance = imageScrollTop + $(window).height();
510    return imageOuterHeight > imageScrollTop && imageOffset < imageDistance;
511  }
512}.call(this));

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.