Panorama player on any map with Yandex share snippet

Laaflet OSM map is used to demostrate how XMLHttpRequest hijack can help with panoramas.

by Sergey Kruk

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.css">
<body>
<div id="panorama"></div>
<div id="map"></div>
</body>

CSS

html, body {
	margin: 0px;
	padding: 0px;
	width: 100%;
	height: 100%;
}

#panorama {
	width: 100%;
	height: 65%;
}

#map {
	width: 100%;
	height: 35%;
}

JavaScript

var ll = L.latLng(55.75074572, 37.61782676);
var $map = L.map('map', {center: ll, zoom: 15});
var $cm = L.circleMarker(ll, {
	radius: 5,
  opacity: 1,
  color: '#d44',
  fillOpacity: 0.5,
  fillColor: '#d44'
});
var $panoDiv = $('#panorama');
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo($map);
$cm.addTo($map);

function openPanoramaAt(latlng) {
  var panoScript = document.createElement('script');
  panoScript.type = 'text/javascript';
  panoScript.src = 'https://panoramas.api-maps.yandex.ru/embed/1.x/?lang=ru&ll=' + latlng.lng + '%2C' + latlng.lat + '&ost=dir%3A0.0%2C0.0~span%3A130%2C70.26418362927674&size=' + $panoDiv.width() + '%2C' + $panoDiv.height() + '&l=stv';
  $panoDiv.empty();
  $panoDiv[0].appendChild(panoScript);
}

function markMapAt(latlng) {
	$map.panTo(latlng);
  $cm.setLatLng(latlng);
}

var observer = new MutationObserver(function (mutations) {
	mutations.forEach(function (mutation) {
  	var len = mutation.addedNodes.length;
    if (len === 0) {
    	return;
    }
    for (var i = 0; i < len; i += 1) {
    	if (mutation.addedNodes[i].nodeName == 'IFRAME') {
      	(function(XMLHttpR) {
        	var open = XMLHttpR.prototype.open;
        	var send = XMLHttpR.prototype.send;
        	
          mutation.addedNodes[i].contentWindow.XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
          	console.log(url);
            open.call(this, method, url, async, user, pass);
          };
          
          mutation.addedNodes[i].contentWindow.XMLHttpRequest.prototype.send = function (data) {
          	var t = this;
            var url = this._url;
            var oldorsc;
            
            function orsc () {
            	if (t.readyState == 4) {
              	var gjCoord = JSON.parse(t.response).data.Data.Point.coordinates;
								markMapAt(L.latLng(gjCoord[1], gjCoord[0]));
              }
              
              if (oldorsc) {
              	oldorsc();
              }
            }
  ...