PageSourceSearch

https://m-m-immo.de/wp-content/themes/wordliner-pace-twentyone/js/juxtapose.min.js?ver=6.8.5

js m-m-immo.de collected 2026-10-07 04:57:58 UTC 23,440 bytes, 716 lines download raw bytes

vendor: 17,986 bytes, lines 1-544
1/* juxtapose - v1.2.1 - 2019-04-18
2 * Copyright (c) 2019 Alex Duner and Northwestern University Knight Lab
3 */
4(function(document, window) {
5  var juxtapose = {
6    sliders: [],
7    OPTIMIZATION_ACCEPTED: 1,
8    OPTIMIZATION_WAS_CONSTRAINED: 2
9  };
10  var flickr_key = "d90fc2d1f4acc584e08b8eaea5bf4d6c";
11  var FLICKR_SIZE_PREFERENCES = ["Large", "Medium"];
12  function Graphic(properties, slider) {
13    var self = this;
14    this.image = new Image();
15    this.loaded = false;
16    this.image.onload = function() {
17      self.loaded = true;
18      slider._onLoaded();
19    };
20    this.image.src = properties.src;
21    this.image.alt = properties.alt || "";
22    this.label = properties.label || false;
23    this.credit = properties.credit || false;
24  }
25  function FlickrGraphic(properties, slider) {
26    var self = this;
27    this.image = new Image();
28    this.loaded = false;
29    this.image.onload = function() {
30      self.loaded = true;
31      slider._onLoaded();
32    };
33    this.flickrID = this.getFlickrID(properties.src);
34    this.callFlickrAPI(this.flickrID, self);
35    this.label = properties.label || false;
36    this.credit = properties.credit || false;
37  }
38  FlickrGraphic.prototype = {
39    getFlickrID: function(url) {
40      if (url.match(/flic.kr\/.+/i)) {
41        var encoded = url.split("/").slice(-1)[0];
42        return base58Decode(encoded);
43      }
44      var idx = url.indexOf("flickr.com/photos/");
45      var pos = idx + "flickr.com/photos/".length;
46      var photo_info = url.substr(pos);
47      if (photo_info.indexOf("/") == -1) return null;
48      if (photo_info.indexOf("/") === 0) photo_info = photo_info.substr(1);
49      id = photo_info.split("/")[1];
50      return id;
51    },
52    callFlickrAPI: function(id, self) {
53      var url =
54        "https://api.flickr.com/services/rest/?method=flickr.photos.getSizes" +
55        "&api_key=" +
56        flickr_key +
57        "&photo_id=" +
58        id +
59        "&format=json&nojsoncallback=1";
60      var request = new XMLHttpRequest();
61      request.open("GET", url, true);
62      request.onload = function() {
63        if (request.status >= 200 && request.status < 400) {
64          data = JSON.parse(request.responseText);
65          var flickr_url = self.bestFlickrUrl(data.sizes.size);
66          self.setFlickrImage(flickr_url);
67        } else {
68          console.error("There was an error getting the picture from Flickr");
69        }
70      };
71      request.onerror = function() {
72        console.error("There was an error getting the picture from Flickr");
73      };
74      request.send();
75    },
76    setFlickrImage: function(src) {
77      this.image.src = src;
78    },
79    bestFlickrUrl: function(ary) {
80      var dict = {};
81      for (var i = 0; i < ary.length; i++) {
82        dict[ary[i].label] = ary[i].source;
83      }
84      for (var j = 0; j < FLICKR_SIZE_PREFERENCES.length; j++) {
85        if (FLICKR_SIZE_PREFERENCES[j] in dict) {
86          return dict[FLICKR_SIZE_PREFERENCES[j]];
87        }
88      }
89      return ary[0].source;
90    }
91  };
92  function getNaturalDimensions(DOMelement) {
93    if (DOMelement.naturalWidth && DOMelement.naturalHeight) {
94      return {
95        width: DOMelement.naturalWidth,
96        height: DOMelement.naturalHeight
97      };
98    }
99    var img = new Image();
100    img.src = DOMelement.src;
101    return { width: img.width, height: img.height };
102  }
103  function getImageDimensions(img) {
104    var dimensions = {
105      width: getNaturalDimensions(img).width,
106      height: getNaturalDimensions(img).height,
107      aspect: function() {
108        return this.width / this.height;
109      }
110    };
111    return dimensions;
112  }
113  function addClass(element, c) {
114    if (element.classList) {
115      element.classList.add(c);
116    } else {
117      element.className += " " + c;
118    }
119  }
120  function removeClass(element, c) {
121    element.className = element.className
122      .replace(/(\S+)\s*/g, function(w, match) {
123        if (match === c) {
124          return "";
125        }
126        return w;
127      })
128      .replace(/^\s+/, "");
129  }
130  function setText(element, text) {
131    if (document.body.textContent) {
132      element.textContent = text;
133    } else {
134      element.innerText = text;
135    }
136  }
137  function getComputedWidthAndHeight(element) {
138    if (window.getComputedStyle) {
139      return {
140        width: parseInt(getComputedStyle(element).width, 10),
141        height: parseInt(getComputedStyle(element).height, 10)
142      };
143    } else {
144      w =
145        element.getBoundingClientRect().right -
146        element.getBoundingClientRect().left;
147      h =
148        element.getBoundingClientRect().bottom -
149        element.getBoundingClientRect().top;
150      return { width: parseInt(w, 10) || 0, height: parseInt(h, 10) || 0 };
151    }
152  }
153  function viewport() {
154    var e = window,
155      a = "inner";
156    if (!("innerWidth" in window)) {
157      a = "client";
158      e = document.documentElement || document.body;
159    }
160    return { width: e[a + "Width"], height: e[a + "Height"] };
161  }
162  function getPageX(e) {
163    var pageX;
164    if (e.pageX) {
165      pageX = e.pageX;
166    } else if (e.touches) {
167      pageX = e.touches[0].pageX;
168    } else {
169      pageX =
170        e.clientX +
171        document.body.scrollLeft +
172        document.documentElement.scrollLeft;
173    }
174    return pageX;
175  }
176  function getPageY(e) {
177    var pageY;
178    if (e.pageY) {
179      pageY = e.pageY;
180    } else if (e.touches) {
181      pageY = e.touches[0].pageY;
182    } else {
183      pageY =
184        e.clientY +
185        document.body.scrollTop +
186        document.documentElement.scrollTop;
187    }
188    return pageY;
189  }
190  function checkFlickr(url) {
191    if (url.match(/flic.kr\/.+/i)) {
192      return true;
193    }
194    var idx = url.indexOf("flickr.com/photos/");
195    if (idx == -1) {
196      return false;
197    } else {
198      return true;
199    }
200  }
201  function base58Decode(encoded) {
202    var alphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ",
203      base = alphabet.length;
204    if (typeof encoded !== "string") {
205      throw '"base58Decode" only accepts strings.';
206    }
207    var decoded = 0;
208    while (encoded) {
209      var alphabetPosition = alphabet.indexOf(encoded[0]);
210      if (alphabetPosition < 0) {
211        throw '"base58Decode" can\'t find "' +
212          encoded[0] +
213          '" in the alphabet: "' +
214          alphabet +
215          '"';
216      }
217      var powerOf = encoded.length - 1;
218      decoded += alphabetPosition * Math.pow(base, powerOf);
219      encoded = encoded.substring(1);
220    }
221    return decoded.toString();
222  }
223  function getLeftPercent(slider, input) {
224    if (typeof input === "string" || typeof input === "number") {
225      leftPercent = parseInt(input, 10);
226    } else {
227      var sliderRect = slider.getBoundingClientRect();
228      var offset = {
229        top:
230          sliderRect.top +
231          document.body.scrollTop +
232          document.documentElement.scrollTop,
233        left:
234          sliderRect.left +
235          document.body.scrollLeft +
236          document.documentElement.scrollLeft
237      };
238      var width = slider.offsetWidth;
239      var pageX = getPageX(input);
240      var relativeX = pageX - offset.left;
241      leftPercent = (relativeX / width) * 100;
242    }
243    return leftPercent;
244  }
245  function getTopPercent(slider, input) {
246    if (typeof input === "string" || typeof input === "number") {
247      topPercent = parseInt(input, 10);
248    } else {
249      var sliderRect = slider.getBoundingClientRect();
250      var offset = {
251        top:
252          sliderRect.top +
253          document.body.scrollTop +
254          document.documentElement.scrollTop,
255        left:
256          sliderRect.left +
257          document.body.scrollLeft +
258          document.documentElement.scrollLeft
259      };
260      var width = slider.offsetHeight;
261      var pageY = getPageY(input);
262      var relativeY = pageY - offset.top;
263      topPercent = (relativeY / width) * 100;
264    }
265    return topPercent;
266  }
267  var BOOLEAN_OPTIONS = {
268    animate: true,
269    showLabels: true,
270    showCredits: true,
271    makeResponsive: true
272  };
273  function interpret_boolean(x) {
274    if (typeof x != "string") {
275      return Boolean(x);
276    }
277    return !(x === "false" || x === "");
278  }
279  function JXSlider(selector, images, options) {
280    this.selector = selector;
281    var i;
282    this.options = {
283      animate: true,
284      showLabels: true,
285      showCredits: true,
286      makeResponsive: true,
287      startingPosition: "50%",
288      mode: "horizontal",
289      callback: null
290    };
291    for (i in this.options) {
292      if (i in options) {
293        if (i in BOOLEAN_OPTIONS) {
294          this.options[i] = interpret_boolean(options[i]);
295        } else {
296          this.options[i] = options[i];
297        }
298      }
299    }
300    if (images.length == 2) {
301      if (checkFlickr(images[0].src)) {
302        this.imgBefore = new FlickrGraphic(images[0], this);
303      } else {
304        this.imgBefore = new Graphic(images[0], this);
305      }
306      if (checkFlickr(images[1].src)) {
307        this.imgAfter = new FlickrGraphic(images[1], this);
308      } else {
309        this.imgAfter = new Graphic(images[1], this);
310      }
311    } else {
312      console.warn("The images parameter takes two Image objects.");
313    }
314    if (this.imgBefore.credit || this.imgAfter.credit) {
315      this.options.showCredits = true;
316    } else {
317      this.options.showCredits = false;
318    }
319  }
320  JXSlider.prototype = {
321    updateSlider: function(input, animate) {
322      var leftPercent, rightPercent;
323      if (this.options.mode === "vertical") {
324        leftPercent = getTopPercent(this.slider, input);
325      } else {
326        leftPercent = getLeftPercent(this.slider, input);
327      }
328      leftPercent = leftPercent.toFixed(2) + "%";
329      leftPercentNum = parseFloat(leftPercent);
330      rightPercent = 100 - leftPercentNum + "%";
331      if (leftPercentNum > 0 && leftPercentNum < 100) {
332        removeClass(this.handle, "transition");
333        removeClass(this.rightImage, "transition");
334        removeClass(this.leftImage, "transition");
335        if (this.options.animate && animate) {
336          addClass(this.handle, "transition");
337          addClass(this.leftImage, "transition");
338          addClass(this.rightImage, "transition");
339        }
340        if (this.options.mode === "vertical") {
341          this.handle.style.top = leftPercent;
342          this.leftImage.style.height = leftPercent;
343          this.rightImage.style.height = rightPercent;
344        } else {
345          this.handle.style.left = leftPercent;
346          this.leftImage.style.width = leftPercent;
347          this.rightImage.style.width = rightPercent;
348        }
349        this.sliderPosition = leftPercent;
350      }
351    },
352    getPosition: function() {
353      return this.sliderPosition;
354    },
355    displayLabel: function(element, labelText) {
356      label = document.createElement("div");
357      label.className = "jx-label";
358      label.setAttribute("tabindex", 0);
359      setText(label, labelText);
360      element.appendChild(label);
361    },
362    displayCredits: function() {
363      credit = document.createElement("div");
364      credit.className = "jx-credit";
365      text = "<em>Photo Credits:</em>";
366      if (this.imgBefore.credit) {
367        text += " <em>Before</em> " + this.imgBefore.credit;
368      }
369      if (this.imgAfter.credit) {
370        text += " <em>After</em> " + this.imgAfter.credit;
371      }
372      credit.innerHTML = text;
373      this.wrapper.appendChild(credit);
374    },
375    setStartingPosition: function(s) {
376      this.options.startingPosition = s;
377    },
378    checkImages: function() {
379      if (
380        getImageDimensions(this.imgBefore.image).aspect() ==
381        getImageDimensions(this.imgAfter.image).aspect()
382      ) {
383        return true;
384      } else {
385        return false;
386      }
387    },
388    calculateDims: function(width, height) {
389      var ratio = getImageDimensions(this.imgBefore.image).aspect();
390      if (width) {
391        height = width / ratio;
392      } else if (height) {
393        width = height * ratio;
394      }
395      return { width: width, height: height, ratio: ratio };
396    },
397    responsivizeIframe: function(dims) {
398      if (dims.height < window.innerHeight) {
399        if (dims.ratio >= 1) {
400          this.wrapper.style.paddingTop =
401            parseInt((window.innerHeight - dims.height) / 2) + "px";
402        }
403      } else if (dims.height > window.innerHeight) {
404        dims = this.calculateDims(0, window.innerHeight);
405        this.wrapper.style.paddingLeft =
406          parseInt((window.innerWidth - dims.width) / 2) + "px";
407      }
408      if (this.options.showCredits) {
409        dims.height -= 13;
410      }
411      return dims;
412    },
413    setWrapperDimensions: function() {
414      var wrapperWidth = getComputedWidthAndHeight(this.wrapper).width;
415      var wrapperHeight = getComputedWidthAndHeight(this.wrapper).height;
416      var dims = this.calculateDims(wrapperWidth, wrapperHeight);
417      if (
418        window.location !== window.parent.location &&
419        !this.options.makeResponsive
420      ) {
421        dims = this.responsivizeIframe(dims);
422      }
423      this.wrapper.style.height = parseInt(dims.height) + "px";
424      this.wrapper.style.width = parseInt(dims.width) + "px";
425    },
426    optimizeWrapper: function(maxWidth) {
427      var result = juxtapose.OPTIMIZATION_ACCEPTED;
428      if (
429        this.imgBefore.image.naturalWidth >= maxWidth &&
430        this.imgAfter.image.naturalWidth >= maxWidth
431      ) {
432        this.wrapper.style.width = maxWidth + "px";
433        result = juxtapose.OPTIMIZATION_WAS_CONSTRAINED;
434      } else if (this.imgAfter.image.naturalWidth < maxWidth) {
435        this.wrapper.style.width = this.imgAfter.image.naturalWidth + "px";
436      } else {
437        this.wrapper.style.width = this.imgBefore.image.naturalWidth + "px";
438      }
439      this.setWrapperDimensions();
440      return result;
441    },
442    _onLoaded: function() {
443      if (
444        this.imgBefore &&
445        this.imgBefore.loaded === true &&
446        this.imgAfter &&
447        this.imgAfter.loaded === true
448      ) {
449        this.wrapper = document.querySelector(this.selector);
450        addClass(this.wrapper, "juxtapose");
451        this.wrapper.style.width = getNaturalDimensions(
452          this.imgBefore.image
453        ).width;
454        this.setWrapperDimensions();
455        this.slider = document.createElement("div");
456        this.slider.className = "jx-slider";
457        this.wrapper.appendChild(this.slider);
458        if (this.options.mode != "horizontal") {
459          addClass(this.slider, this.options.mode);
460        }
461        this.handle = document.createElement("div");
462        this.handle.className = "jx-handle";
463        this.rightImage = document.createElement("div");
464        this.rightImage.className = "jx-image jx-right";
465        this.rightImage.appendChild(this.imgAfter.image);
466        this.leftImage = document.createElement("div");
467        this.leftImage.className = "jx-image jx-left";
468        this.leftImage.appendChild(this.imgBefore.image);
469        this.labCredit = document.createElement("a");
470        this.labCredit.setAttribute("href", "http://juxtapose.knightlab.com");
471        this.labCredit.setAttribute("target", "_blank");
472        this.labCredit.className = "jx-knightlab";
473        this.labLogo = document.createElement("div");
474        this.labLogo.className = "knightlab-logo";
475        this.labCredit.appendChild(this.labLogo);
476        this.projectName = document.createElement("span");
477        this.projectName.className = "juxtapose-name";
478        setText(this.projectName, "JuxtaposeJS");
479        this.labCredit.appendChild(this.projectName);
480        this.slider.appendChild(this.handle);
481        this.slider.appendChild(this.leftImage);
482        this.slider.appendChild(this.rightImage);
483        this.slider.appendChild(this.labCredit);
484        this.leftArrow = document.createElement("div");
485        this.rightArrow = document.createElement("div");
486        this.control = document.createElement("div");
487        this.controller = document.createElement("div");
488        this.leftArrow.className = "jx-arrow jx-left";
489        this.rightArrow.className = "jx-arrow jx-right";
490        this.control.className = "jx-control";
491        this.controller.className = "jx-controller";
492        this.controller.setAttribute("tabindex", 0);
493        this.controller.setAttribute("role", "slider");
494        this.controller.setAttribute("aria-valuenow", 50);
495        this.controller.setAttribute("aria-valuemin", 0);
496        this.controller.setAttribute("aria-valuemax", 100);
497        this.handle.appendChild(this.leftArrow);
498        this.handle.appendChild(this.control);
499        this.handle.appendChild(this.rightArrow);
500        this.control.appendChild(this.controller);
501        this._init();
502      }
503    },
504    _init: function() {
505      if (this.checkImages() === false) {
506        console.warn(
507          this,
508          "Check that the two images have the same aspect ratio for the slider to work correctly."
509        );
510      }
511      this.updateSlider(this.options.startingPosition, false);
512      if (this.options.showLabels === true) {
513        if (this.imgBefore.label) {
514          this.displayLabel(this.leftImage, this.imgBefore.label);
515        }
516        if (this.imgAfter.label) {
517          this.displayLabel(this.rightImage, this.imgAfter.label);
518        }
519      }
520      if (this.options.showCredits === true) {
521        this.displayCredits();
522      }
523      var self = this;
524      window.addEventListener("resize", function() {
525        self.setWrapperDimensions();
526      });
527      this.slider.addEventListener("mousedown", function(e) {
528        e = e || window.event;
529        e.preventDefault();
530        self.updateSlider(e, true);
531        animate = true;
532        this.addEventListener("mousemove", function(e) {
533          e = e || window.event;
534          e.preventDefault();
535          if (animate) {
536            self.updateSlider(e, false);
537          }
538        });
539        this.addEventListener("mouseup", function(e) {
540          e = e || window.event;
541          e.preventDefault();
542          e.stopPropagation();
543          this.removeEventListener("mouseup", arguments.callee);
544          animate = false;
545        });
546      });
547      this.slider.addEventListener("touchstart", function(e) {
548        e = e || window.event;
549        e.preventDefault();
550        e.stopPropagation();
551        self.updateSlider(e, true);
552        this.addEventListener("touchmove", function(e) {
553          e = e || window.event;
554          e.preventDefault();
555          e.stopPropagation();
556          self.updateSlider(event, false);
557        });
558      });
559      this.handle.addEventListener("keydown", function(e) {
560        e = e || window.event;
561        var key = e.which || e.keyCode;
562        var ariaValue = parseFloat(this.style.left);
563        if (key == 37) {
564          ariaValue = ariaValue - 1;
565          var leftStart = parseFloat(this.style.left) - 1;
566          self.updateSlider(leftStart, false);
567          self.controller.setAttribute("aria-valuenow", ariaValue);
568        }
569        if (key == 39) {
570          ariaValue = ariaValue + 1;
571          var rightStart = parseFloat(this.style.left) + 1;
572          self.updateSlider(rightStart, false);
573          self.controller.setAttribute("aria-valuenow", ariaValue);
574        }
575      });
576      this.leftImage.addEventListener("keydown", function(event) {
577        var key = event.which || event.keyCode;
578        if (key == 13 || key == 32) {
579          self.updateSlider("90%", true);
580          self.controller.setAttribute("aria-valuenow", 90);
581        }
582      });
583      this.rightImage.addEventListener("keydown", function(event) {
584        var key = event.which || event.keyCode;
585        if (key == 13 || key == 32) {
586          self.updateSlider("10%", true);
587          self.controller.setAttribute("aria-valuenow", 10);
588        }
589      });
590      juxtapose.sliders.push(this);
591      if (this.options.callback && typeof this.options.callback == "function") {
592        this.options.callback(this);
593      }
594    }
595  };
596  juxtapose.makeSlider = function(element, idx) {
597    if (typeof idx == "undefined") {
598      idx = juxtapose.sliders.length;
599    }
600    var w = element;
601    var images = w.querySelectorAll("img");
602    var options = {};
603    if (w.getAttribute("data-animate")) {
604      options.animate = w.getAttribute("data-animate");
605    }
606    if (w.getAttribute("data-showlabels")) {
607      options.showLabels = w.getAttribute("data-showlabels");
608    }
609    if (w.getAttribute("data-showcredits")) {
610      options.showCredits = w.getAttribute("data-showcredits");
611    }
612    if (w.getAttribute("data-startingposition")) {
613      options.startingPosition = w.getAttribute("data-startingposition");
614    }
615    if (w.getAttribute("data-mode")) {
616      options.mode = w.getAttribute("data-mode");
617    }
618    if (w.getAttribute("data-makeresponsive")) {
619      options.mode = w.getAttribute("data-makeresponsive");
620    }
621    specificClass = "juxtapose-" + idx;
622    addClass(element, specificClass);
623    selector = "." + specificClass;
624    if (w.innerHTML) {
625      w.innerHTML = "";
626    } else {
627      w.innerText = "";
628    }
629    slider = new juxtapose.JXSlider(
630      selector,
631      [
632        {
633          src: images[0].src,
634          label: images[0].getAttribute("data-label"),
635          credit: images[0].getAttribute("data-credit"),
636          alt: images[0].alt
637        },
638        {
639          src: images[1].src,
640          label: images[1].getAttribute("data-label"),
641          credit: images[1].getAttribute("data-credit"),
642          alt: images[1].alt
643        }
644      ],
645      options
646    );
647  };
648  juxtapose.scanPage = function() {
649    var elements = document.querySelectorAll(".juxtapose");
650    for (var i = 0; i < elements.length; i++) {
651      juxtapose.makeSlider(elements[i], i);
652    }
653  };
654  juxtapose.JXSlider = JXSlider;
655  window.juxtapose = juxtapose;
656  juxtapose.scanPage();
657})(document, window);
658!window.addEventListener &&
659  (function(
660    WindowPrototype,
661    DocumentPrototype,
662    ElementPrototype,
663    addEventListener,
664    removeEventListener,
665    dispatchEvent,
666    registry
667  ) {
668    WindowPrototype[addEventListener] = DocumentPrototype[
669      addEventListener
670    ] = ElementPrototype[addEventListener] = function(type, listener) {
671      var target = this;
672      registry.unshift([
673        target,
674        type,
675        listener,
676        function(event) {
677          event.currentTarget = target;
678          event.preventDefault = function() {
679            event.returnValue = false;
680          };
681          event.stopPropagation = function() {
682            event.cancelBubble = true;
683          };
684          event.target = event.srcElement || target;
685          listener.call(target, event);
686        }
687      ]);
688      this.attachEvent("on" + type, registry[0][3]);
689    };
690    WindowPrototype[removeEventListener] = DocumentPrototype[
691      removeEventListener
692    ] = ElementPrototype[removeEventListener] = function(type, listener) {
693      for (var index = 0, register; (register = registry[index]); ++index) {
694        if (
695          register[0] == this &&
696          register[1] == type &&
697          register[2] == listener
698        ) {
699          return this.detachEvent("on" + type, registry.splice(index, 1)[0][3]);
700        }
701      }
702    };
703    WindowPrototype[dispatchEvent] = DocumentPrototype[
704      dispatchEvent
705    ] = ElementPrototype[dispatchEvent] = function(eventObject) {
706      return this.fireEvent("on" + eventObject.type, eventObject);
707    };
708  })(
709    Window.prototype,
710    HTMLDocument.prototype,
711    Element.prototype,
712    "addEventListener",
713    "removeEventListener",
714    "dispatchEvent",
715    []
716  );

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.