function createMediaElement(type, media_attrs, source_attrs) {
  var mediaElement = createElement(type, {});

  var sourceElement = createElement("source", {});

  mediaElement.eventPromise = new Promise(function(resolve, reject) {
    mediaElement.addEventListener("loadeddata", function (e) {
      resolve(e);
    });

    // Safari doesn't fire an `error` event when blocking mixed content.
    mediaElement.addEventListener("stalled", function(e) {
      reject(e);
    });

    sourceElement.addEventListener("error", function(e) {
      reject(e);
    });
  });

  setAttributes(mediaElement, media_attrs);
  setAttributes(sourceElement, source_attrs);

  mediaElement.appendChild(sourceElement);
  document.body.appendChild(mediaElement);

  return mediaElement;
}
Creates a new media element with a child source element, binds loadeddata and
    error events, sets attributes and appends to document.body.
@param {string} type The type of the media element (audio/video/picture).
@param {object} media_attrs The attributes for the media element.
@param {object} source_attrs The attributes for the child source element.
@return {DOMElement} The newly created media element.