importar ventana desde 'global/window';
importar documento desde 'global/document';
importar mergeOptions desde '../utils/merge-options';
importar {getAbsoluteURL} desde '../utils/url';
/**
* Esta función se usa para disparar un conjunto de fuentes cuando hay algo
* similar a `mediaEl.load()` siendo llamado. Intentará encontrar la fuente a través de
* el atributo `src` y luego el `< fuente> ` elementos. Luego disparará `sourceset`
* con la fuente que se encontró o una cadena vacía si no podemos saberlo. si no puede
* encuentre una fuente, entonces `sourceset` no se activará.
*
* @param {Html5} tecnología
* El objeto tecnológico en el que se configuró sourceset
*
* @return {booleano}
* devuelve falso si el conjunto de fuentes no se activó y verdadero en caso contrario.
* /
const sourcesetLoad = (tecnología) => {
const el = tech.el();
// si se establece `el.src`, esa fuente se cargará.
if (el.hasAttribute('src')) {
tech.triggerSourceset(el.src);
devolver verdadero;
}
/**
* Dado que no existe una propiedad src en el elemento multimedia, los elementos fuente se utilizarán para
* implementar el algoritmo de selección de fuente. Esto sucede de forma asíncrona y
* para la mayoría de los casos donde hay más de una fuente, no podemos decir qué fuente
* cargarse, sin volver a implementar el algoritmo de selección de fuente. en este momento no estamos
* va a hacer eso. Sin embargo, hay tres casos especiales que manejamos aquí:
*
* 1. Si no hay fuentes, no active 'sourceset'.
* 2. Si solo hay un `< fuente> ` con una propiedad/atributo `src` que es nuestro `src`
* 3. Si hay más de un `< fuente> ` pero todos tienen la misma URL `src`.
* Ese será nuestro src.
* /
const fuentes = tech.$$('fuente');
const srcUrls = [];
let src = '';
// si no hay fuentes, no active el conjunto de fuentes
if (!fuentes.longitud) {
falso retorno;
}
// solo cuenta elementos fuente válidos/no duplicados
para (sea i = 0; i < fuentes.longitud; i++) {
const url = fuentes[i].src;
si (url && srcUrls.indexOf(url) === -1) {
srcUrls.push(url);
}
}
// no había fuentes válidas
if (!srcUrls.longitud) {
falso retorno;
}
// solo hay una URL de elemento fuente válida
// usa eso
if (srcUrls.longitud === 1) {
src = srcUrls[0];
}
tech.triggerSourceset(src);
devolver verdadero;
};
/**
* nuestra implementación de un descriptor `innerHTML` para navegadores
* que no tienen uno.
* /
const innerHTMLDescriptorPolyfill = Object.defineProperty({}, 'innerHTML', {
conseguir() {
devuelve this.cloneNode(true).innerHTML;
},
conjunto (v) {
// hacer un nodo ficticio para usar innerHTML en
const dummy = document.createElement(this.nodeName.toLowerCase());
// establece innerHTML en el valor proporcionado
ficticio.innerHTML = v;
// crea un fragmento de documento para contener los nodos del dummy
const docFrag = documento.createDocumentFragment();
// copia todos los nodos creados por innerHTML en dummy
// al fragmento del documento
while (dummy.childNodes.longitud) {
docFrag.appendChild(dummy.childNodes[0]);
}
// eliminar contenido
this.innerText = '';
// ahora agregamos todo ese html en uno agregando el
// fragmento de documento. Así es como lo hace innerHTML.
ventana.Elemento.prototipo.appendChild.call(esto, docFrag);
// luego devuelve el resultado que el setter de innerHTML daría
devuelve esto.innerHTML;
}
});
/**
* Obtener un descriptor de propiedad dada una lista de prioridades y el
* propiedad para obtener.
* /
const getDescriptor = (prioridad, propiedad) => {
let descriptor = {};
para (sea i = 0; i < prioridad.longitud; i++) {
descriptor = Object.getOwnPropertyDescriptor(prioridad[i], prop);
si (descriptor && descriptor.set && descriptor.get) {
romper;
}
}
descriptor.enumerable = verdadero;
descriptor.configurable = verdadero;
descriptor de retorno;
};
const getInnerHTMLDescriptor = (tecnología) => getDescriptor([
tecnología.el(),
ventana.HTMLMediaElement.prototipo,
ventana.Elemento.prototipo,
Description HTML interno Polyfill
], 'HTML interno');
/**
* Parches funciones internas del navegador para que podamos decir sincrónicamente
* si un `< fuente> ` se agregó al elemento multimedia. Por alguna razón esto
* provoca un `conjunto de fuentes` si el elemento multimedia está listo y no tiene ninguna fuente.
* Esto sucede cuando:
* - La página acaba de cargarse y el elemento multimedia no tiene una fuente.
* - El elemento multimedia se vació de todas las fuentes, luego se llamó a `load()`.
*
* Lo hace parcheando las siguientes funciones/propiedades cuando son compatibles:
*
* - `append()` - se puede usar para agregar un `< fuente> ` elemento al elemento multimedia
* - `appendChild()` - se puede usar para agregar un `< fuente> ` elemento al elemento multimedia
* - `insertAdjacentHTML()` - se puede usar para agregar un `< fuente> ` elemento al elemento multimedia
* - `innerHTML` - se puede usar para agregar un `< fuente> ` elemento al elemento multimedia
*
* @param {Html5} tecnología
* El objeto tecnológico en el que se está configurando sourceset.
* /
const firstSourceWatch = función (tecnología) {
const el = tech.el();
// asegúrese de que firstSourceWatch no esté configurado dos veces.
si (el.resetSourceWatch_) {
devolver;
}
const viejo = {};
const innerDescriptor = getInnerHTMLDescriptor(tecnología);
const appendWrapper = (appendFn) => (... argumentos) => {
const retval = appendFn.apply(el, args);
sourcesetLoad(tecnología);
recuperación de retorno;
};
['agregar', 'agregarNiño', 'insertarHTMLAdyacente'].forEach((k) => {
si (!el[k]) {
devolver;
}
// almacena la función anterior
viejo[k] = el[k];
// llama a la función anterior con un conjunto de fuentes si es una fuente
// fue cargado
el[k] = appendWrapper(antiguo[k]);
});
Object.defineProperty(el, 'innerHTML', mergeOptions(innerDescriptor, {
conjunto: appendWrapper (innerDescriptor.set)
}));
el.resetSourceWatch_ = () => {
el.resetSourceWatch_ = nulo;
Objeto.claves(antiguo).forEach((k) => {
el[k] = viejo[k];
});
Object.defineProperty(el, 'innerHTML', innerDescriptor);
};
// en el primer conjunto de fuentes, necesitamos revertir nuestros cambios
tech.one('sourceset', el.resetSourceWatch_);
};
/**
* nuestra implementación de un descriptor `src` para navegadores
* que no tienen uno.
* /
const srcDescriptorPolyfill = Object.defineProperty({}, 'src', {
conseguir() {
if (this.hasAttribute('src')) {
return getAbsoluteURL(window.Element.prototype.getAttribute.call(this, 'src'));
}
devolver '';
},
conjunto (v) {
window.Element.prototype.setAttribute.call(this, 'src', v);
volver v;
}
});
const getSrcDescriptor = (tecnología) => getDescriptor([tech.el(), window.HTMLMediaElement.prototype, srcDescriptorPolyfill], 'src');
/**
* configurar el manejo de `sourceset` en la tecnología `Html5`. Esta función
* parchea las siguientes propiedades/funciones de los elementos:
*
* - `src` - para determinar cuándo se establece `src`
* - `setAttribute()` - para determinar cuándo se establece `src`
* - `load()` - esto vuelve a activar el algoritmo de selección de fuente y puede
* causar un conjunto de fuentes.
*
* Si no hay una fuente cuando estamos agregando soporte para `sourceset` o durante una `carga ()`
* también parcheamos las funciones enumeradas en `firstSourceWatch`.
*
* @param {Html5} tecnología
* La tecnología para parchear
* /
const setupSourceset = función (tecnología) {
if (!tech.featuresSourceset) {
devolver;
}
const el = tech.el();
// asegúrese de que sourceset no esté configurado dos veces.
si (el.resetSourceset_) {
devolver;
}
const srcDescriptor = getSrcDescriptor(tech);
const oldSetAttribute = el.setAttribute;
const oldLoad = el.load;
Object.defineProperty(el, 'src', mergeOptions(srcDescriptor, {
conjunto: (v) => {
const retval = srcDescriptor.set.call(el, v);
// usamos el captador aquí para obtener el valor real establecido en src
tech.triggerSourceset(el.src);
recuperación de retorno;
}
}));
el.setAttribute = (n, v) => {
const retval = oldSetAttribute.call(el, n, v);
si ((/src/i).prueba(n)) {
tech.triggerSourceset(el.src);
}
recuperación de retorno;
};
carga eléctrica = () => {
const retval = oldLoad.call(el);
// si se llamó a load, pero no había una fuente para disparar
// conjunto de fuentes activado. Tenemos que estar atentos a una fuente adjunta
// ya que eso puede desencadenar un `sourceset` cuando el elemento multimedia
// no tiene fuente
si (! sourcesetLoad (tecnología)) {
tech.triggerSourceset('');
firstSourceWatch(tecnología);
}
recuperación de retorno;
};
if (el.currentSrc) {
tech.triggerSourceset(el.currentSrc);
} más si (! sourcesetLoad (tecnología)) {
firstSourceWatch(tecnología);
}
el.resetSourceset_ = () => {
el.resetSourceset_ = nulo;
el.load = oldLoad;
el.setAttribute = oldSetAttribute;
Object.defineProperty(el, 'src', srcDescriptor);
si (el.resetSourceWatch_) {
el.resetSourceWatch_();
}
};
};
exportar el conjunto de fuentes de configuración predeterminado;