This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/465819/1187898/API%20for%20CustomElements%20in%20YouTube.js
- For
WeakRef
supported browsers, Once all registered callbacks are performed, the injector will be cleared.
- We offer both asynchronous and synchorized callback in
customYtElements.whenRegistered
. However, since _initializeProperties()
and all other related layouting and rendering will be conducted immediately after component registration. Synchorized callback is preferred.
Browser Support
Example 1:
// ==UserScript==
// @name Testing
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://www.youtube.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant none
// @run-at document-start
// @require https://greatest.deepsurf.us/scripts/465819-api-for-customelements-in-youtube/code/API%20for%20CustomElements%20in%20YouTube.js?version=1187694
// ==/UserScript==
(function () {
'use strict';
console.log('script started');
customYtElements.whenRegistered('ytd-rich-grid-renderer', (proto) => {
console.log('yt element is registered', proto.is);
proto.calcElementsPerRow = () => 5;
});
})();
Example 2 - GC Checking
- You might also check whether the injector function is garbage collected (GC) or not.
(function () {
'use strict';
console.log('script started');
customYtElements.whenRegistered('ytd-rich-grid-renderer', (proto) => {
console.log('yt element is registered', proto.is);
proto.calcElementsPerRow = () => 5;
if (typeof WeakRef === 'function') {
console.debug('Is injector is cleared in memory? (#1)', proto._registered.__injector__.deref() === undefined);
setTimeout(() => {
console.debug('Is injector is cleared in memory? (#2)', proto._registered.__injector__.deref() === undefined);
}, 5000);
}
});
})();

Example 3 - Run on old browser (Waterfox Classic) with YouTube built-in polyfill
- It is compatible to Polyfill for customElements used on older browsers (e.g. Waterfox Classic/Firefox 56).
- You might use
yt-page-data-fetched
or similar way to ensure customElements
is polyfilled.
Example 3A - ready by yt-page-data-fetched
// @run-at document-start
(function () {
'use strict';
console.log('script started');
let onYtInitialized = () => {
document.removeEventListener('yt-navigate', onYtInitialized, true);
onYtInitialized = null;
customYtElements.whenRegistered('ytd-rich-grid-renderer', (proto) => {
console.log('yt element is registered', proto.is);
proto.calcElementsPerRow = () => 6;
if (typeof WeakRef === 'function') {
// You can also check whether the injector is garbage collected (GC) or not.
console.debug('Is injector is cleared in memory? (#1)', proto._registered.__injector__.deref() === undefined);
setTimeout(() => {
console.debug('Is injector is cleared in memory? (#2)', proto._registered.__injector__.deref() === undefined);
}, 5000);
}
});
};
// Please make sure `@run-at document-start` is used
document.addEventListener('yt-page-data-fetched', onYtInitialized, true);
})();
Example 3B - ready by polyfill
(function () {
'use strict';
console.log('script started');
const onCustomElementsReady = () => {
console.log('onCustomElementsReady');
customYtElements.whenRegistered('ytd-rich-grid-renderer', (proto) => {
console.log('yt element is registered', proto.is);
proto.calcElementsPerRow = () => 6;
if (typeof WeakRef === 'function') {
// You can also check whether the injector is garbage collected (GC) or not.
console.debug('Is injector is cleared in memory? (#1)', proto._registered.__injector__.deref() === undefined);
setTimeout(() => {
console.debug('Is injector is cleared in memory? (#2)', proto._registered.__injector__.deref() === undefined);
}, 5000);
}
});
};
if (typeof customElements === 'undefined') {
Object.defineProperty(window, 'customElements', {
get: function () {
delete window.customElements;
Promise.resolve(0).then(onCustomElementsReady); // onCustomElementsReady will be immediately called after polyfill js script.
return undefined;
},
set: function () {
},
enumerable: false,
configurable: true
})
} else {
onCustomElementsReady();
}
})();