|
1 | 1 | // ==UserScript==
|
2 | 2 | // @name YouTube JS Engine Tamer
|
3 | 3 | // @namespace UserScripts
|
4 |
| -// @version 0.18.2 |
| 4 | +// @version 0.18.3 |
5 | 5 | // @match https://www.youtube.com/*
|
6 | 6 | // @match https://www.youtube-nocookie.com/embed/*
|
7 | 7 | // @match https://studio.youtube.com/live_chat*
|
|
104 | 104 | const DO_createStampDomArrayFnE1_ = true; // added in 2025.02.11 - to improve stampDom responsiveness
|
105 | 105 | const DO_createStampDomArrayFnE1_noConstraintE = true;
|
106 | 106 | const DO_createStampDomArrayFnE1_nativeAppendD = true;
|
| 107 | + const DO_createStampDomArrayFnF1_ = true; |
107 | 108 |
|
108 | 109 |
|
109 | 110 | const FIX_POPUP_UNIQUE_ID = true; // currently only for channel about popup;
|
|
351 | 352 | const nativeRemoveE = HTMLElement_.prototype.remove;
|
352 | 353 | const DocumentFragment_ = DocumentFragment;
|
353 | 354 | const nativeAppendD = DocumentFragment_.prototype.append;
|
| 355 | + const Node_ = Node; |
354 | 356 |
|
355 | 357 | /**
|
356 | 358 | @param {number} x
|
|
3601 | 3603 | const container = this.getStampContainer_(b_);
|
3602 | 3604 |
|
3603 | 3605 | const domShell = container.__domApi;
|
3604 |
| - if (!domShell || !domShell.appendChild || domShell.firstElementChild) throw new Error(); |
| 3606 | + if (!domShell || !domShell.appendChild) throw new Error(); |
| 3607 | + const hasElement = !!domShell.firstElementChild; |
3605 | 3608 | const noscript = document.createElement('noscript');
|
3606 | 3609 | // document.body.appendChild(noscript);
|
3607 | 3610 | const nofn = () => true;
|
3608 | 3611 | const n = a_.length;
|
3609 | 3612 | const fns = new Array(n);
|
| 3613 | + let cxt = 0; |
3610 | 3614 |
|
3611 | 3615 | let mutex = Promise.resolve(0);
|
| 3616 | + let qxd = hasElement ? new WeakSet() : null; |
| 3617 | + const nextTickFnE1 = () => { |
| 3618 | + a_.some((u, i) => { |
| 3619 | + |
| 3620 | + const x = csb(c, u); |
| 3621 | + if (!x) { |
| 3622 | + fns[i] = nofn; |
| 3623 | + cxt++; |
| 3624 | + } else { |
| 3625 | + |
| 3626 | + const cp = this.createComponent_(c[x], u[x], d); |
| 3627 | + cp[stampIdxSb] = i; |
| 3628 | + doDeferRenderStamperBinding_(cp); |
| 3629 | + mutex = mutex.then(() => { |
| 3630 | + noscript.appendChild(cp); |
| 3631 | + }); |
| 3632 | + |
| 3633 | + // Promise.resolve(cp).then(doDeferRenderStamperBinding_); |
| 3634 | + let q = cp; |
| 3635 | + fns[i] = () => { |
| 3636 | + if (q && q.parentNode === noscript) { |
| 3637 | + const cp = q; |
| 3638 | + q = null; |
| 3639 | + } |
| 3640 | + if (!q) return true; |
| 3641 | + }; |
| 3642 | + |
| 3643 | + } |
| 3644 | + |
| 3645 | + }); |
| 3646 | + noscript.setAttribute('ylul8gr', `${Date.now()}`); |
| 3647 | + }; |
| 3648 | + |
| 3649 | + const nextTickFnF1 = ()=>{ |
| 3650 | + |
| 3651 | + a_.some((u, i) => { |
| 3652 | + |
| 3653 | + const x = csb(c, u); |
| 3654 | + if (!x) { |
| 3655 | + fns[i] = nofn; |
| 3656 | + cxt++; |
| 3657 | + } else { |
| 3658 | + |
| 3659 | + const is = this.getComponentName_(c[x], u[x]); |
| 3660 | + let np = domShell.firstElementChild; |
| 3661 | + let chosenNode = null; |
| 3662 | + while (np) { |
| 3663 | + if (np instanceof Node_ && np.is === is && !qxd.has(np)) { |
| 3664 | + qxd.add(np); |
| 3665 | + chosenNode = np; |
| 3666 | + break; |
| 3667 | + } |
| 3668 | + np = np.nextElementSibling; |
| 3669 | + } |
| 3670 | + |
| 3671 | + const cp = chosenNode || this.createComponent_(c[x], u[x], d); |
| 3672 | + let oldIdx = cp[stampIdxSb]; |
| 3673 | + if(chosenNode !== null && cp === chosenNode){ |
| 3674 | + |
| 3675 | + cp[stampIdxSb] = i; |
| 3676 | + doDeferRenderStamperBinding_(cp); |
| 3677 | + fns[i] = nofn; |
| 3678 | + }else{ |
| 3679 | + |
| 3680 | + cp[stampIdxSb] = i; |
| 3681 | + doDeferRenderStamperBinding_(cp); |
| 3682 | + mutex = mutex.then(() => { |
| 3683 | + noscript.appendChild(cp); // ui formation |
| 3684 | + }); |
| 3685 | + |
| 3686 | + // Promise.resolve(cp).then(doDeferRenderStamperBinding_); |
| 3687 | + let q = cp; |
| 3688 | + fns[i] = () => { |
| 3689 | + if (q && q.parentNode === noscript) { |
| 3690 | + const cp = q; |
| 3691 | + q = null; |
| 3692 | + } |
| 3693 | + if (!q) return true; |
| 3694 | + }; |
| 3695 | + |
| 3696 | + } |
| 3697 | + |
| 3698 | + } |
| 3699 | + |
| 3700 | + }); |
| 3701 | + noscript.setAttribute('ylul8gr', `${Date.now()}`); |
| 3702 | + } |
| 3703 | + |
3612 | 3704 | const pr = new Promise(resolvePR => {
|
3613 | 3705 |
|
3614 | 3706 | let mo = new MutationObserver(() => {
|
|
3623 | 3715 | resolvePR();
|
3624 | 3716 | }
|
3625 | 3717 | });
|
3626 |
| - mo.observe(noscript, { subtree: false, childList: true }); |
3627 |
| - nextBrowserTick_(() => { |
3628 |
| - a_.some((u, i) => { |
| 3718 | + mo.observe(noscript, { subtree: false, childList: true, attributes:['ylul8gr'] }); |
3629 | 3719 |
|
3630 |
| - const x = csb(c, u); |
3631 |
| - if (!x) { |
3632 |
| - fns[i] = nofn; |
3633 |
| - } else { |
3634 |
| - |
3635 |
| - const cp = this.createComponent_(c[x], u[x], d); |
3636 |
| - cp[stampIdxSb] = i; |
3637 |
| - doDeferRenderStamperBinding_(cp); |
3638 |
| - mutex = mutex.then(() => { |
3639 |
| - noscript.appendChild(cp); |
3640 |
| - }); |
| 3720 | + if(hasElement){ |
| 3721 | + nextBrowserTick_(nextTickFnF1); |
| 3722 | + }else{ |
| 3723 | + nextBrowserTick_(nextTickFnE1); |
3641 | 3724 |
|
3642 |
| - // Promise.resolve(cp).then(doDeferRenderStamperBinding_); |
3643 |
| - let q = cp; |
3644 |
| - fns[i] = () => { |
3645 |
| - if (q && q.parentNode === noscript) { |
3646 |
| - const cp = q; |
3647 |
| - q = null; |
3648 |
| - } |
3649 |
| - if (!q) return true; |
3650 |
| - }; |
3651 |
| - |
3652 |
| - } |
| 3725 | + } |
3653 | 3726 |
|
3654 |
| - }); |
3655 |
| - }); |
3656 | 3727 |
|
3657 | 3728 | });
|
3658 | 3729 | await pr.then();
|
3659 | 3730 | fns.length = 0;
|
| 3731 | + qxd = null; |
3660 | 3732 |
|
3661 |
| - noscript.remove(); |
| 3733 | + // nativeRemoveE.call(noscript); |
| 3734 | + noscript.remove(); // trigger isAttached change |
3662 | 3735 | const hostElement = this.hostElement;
|
3663 | 3736 |
|
| 3737 | + // console.log('em77', hasElement, noscript.childElementCount, domShell.childElementCount, cxt, a_.length); |
| 3738 | + // if(a_.length !== noscript.childElementCount+ domShell.childElementCount+ cxt){ |
| 3739 | + // const pd = `${Math.floor(Math.random() * 314159265359 + 314159265359).toString(36)}`; |
| 3740 | + |
| 3741 | + // console.log('em77b', pd, [...a_], [...noscript.childNodes], [...domShell.childNodes]) |
| 3742 | + // setTimeout(()=>{ |
| 3743 | + // console.log('em77c', pd, [...domShell.childNodes]) |
| 3744 | + // }, 1000) |
| 3745 | + // } |
| 3746 | + |
3664 | 3747 | // const sdc02 = this.__$$StampDomCounter$$__;
|
3665 | 3748 |
|
3666 | 3749 |
|
3667 | 3750 | /** @type {DocumentFragment} */
|
3668 | 3751 | const gFragment = document.createDocumentFragment();
|
3669 | 3752 |
|
3670 |
| - mutex = mutex.then(() => { |
| 3753 | + mutex = mutex.then(async() => { |
| 3754 | + |
| 3755 | + // await new Promise(r=>setTimeout(r, 1000)); |
| 3756 | + |
3671 | 3757 |
|
3672 |
| - if (domShell.firstElementChild || hostElement.isConnected === false || this.isAttached === false || !hostElement.contains(container) || container.__domApi !== domShell) { |
| 3758 | + if (hostElement.isConnected === false || this.isAttached === false || !hostElement.contains(container) || container.__domApi !== domShell) { |
3673 | 3759 | return;
|
3674 | 3760 | }
|
| 3761 | + // const t1 = performance.now(); |
3675 | 3762 |
|
3676 | 3763 | if (DO_createStampDomArrayFnE1_nativeAppendD) {
|
3677 | 3764 | let elm;
|
|
3684 | 3771 | gFragment.appendChild(elm);
|
3685 | 3772 | }
|
3686 | 3773 | }
|
3687 |
| - }).then(() => { |
| 3774 | + // const t2 = performance.now(); |
3688 | 3775 |
|
3689 |
| - if (domShell.firstElementChild || hostElement.isConnected === false || this.isAttached === false || !hostElement.contains(container) || container.__domApi !== domShell) { |
| 3776 | + // console.log('createStampDomArrayFn_{T2}', t2-t1); |
| 3777 | + }).then(async () => { |
| 3778 | + |
| 3779 | + if (hostElement.isConnected === false || this.isAttached === false || !hostElement.contains(container) || container.__domApi !== domShell) { |
3690 | 3780 | return;
|
3691 | 3781 | }
|
3692 | 3782 |
|
| 3783 | + // const t1 = performance.now(); |
3693 | 3784 | // const arr = [...noscript.childNodes];
|
3694 | 3785 | // g.append(...arr);
|
3695 |
| - domShell.appendChild(gFragment); |
| 3786 | + |
| 3787 | + // if(gFragment.childElementCount>10){ |
| 3788 | + |
| 3789 | + // for(const p of gFragment.childNodes){ |
| 3790 | + |
| 3791 | + // const w = document.createDocumentFragment(); |
| 3792 | + // w.append(p); |
| 3793 | + |
| 3794 | + // domShell.appendChild(w); |
| 3795 | + // await Promise.resolve(0); |
| 3796 | + |
| 3797 | + // } |
| 3798 | + |
| 3799 | + // }else{ |
| 3800 | + |
| 3801 | + domShell.appendChild(gFragment); |
| 3802 | + // } |
| 3803 | + |
| 3804 | + |
| 3805 | + |
3696 | 3806 | // for (const cp of arr) {
|
3697 | 3807 | // const i = cp[stampIdxSb];
|
3698 | 3808 | // const u = a_[i];
|
3699 | 3809 | // const c = c_;
|
3700 | 3810 | // const x = csb(c, u);
|
3701 | 3811 | // this.deferRenderStamperBinding_(cp, c[x], u[x]); // necessary?
|
3702 | 3812 | // }
|
| 3813 | + |
3703 | 3814 | this.flushRenderStamperComponentBindings_();
|
3704 | 3815 | this.markDirty && this.markDirty();
|
3705 |
| - if (shouldTriggerRendererStamperFinished) { |
3706 |
| - const evt = new CustomEvent("yt-rendererstamper-finished", { |
3707 |
| - bubbles: !0, |
3708 |
| - cancelable: !1, |
3709 |
| - composed: !0, |
3710 |
| - detail: { |
3711 |
| - container |
3712 |
| - } |
3713 |
| - }); |
3714 |
| - hostElement.dispatchEvent(evt); |
3715 |
| - } |
| 3816 | + // const t2 = performance.now(); |
| 3817 | + |
| 3818 | + // console.log('createStampDomArrayFn_{T3}', t2-t1); // time consuming |
| 3819 | + |
| 3820 | + if (shouldTriggerRendererStamperFinished) { |
| 3821 | + nextBrowserTick_(() => { |
| 3822 | + const evt = new CustomEvent("yt-rendererstamper-finished", { |
| 3823 | + bubbles: !0, |
| 3824 | + cancelable: !1, |
| 3825 | + composed: !0, |
| 3826 | + detail: { |
| 3827 | + container |
| 3828 | + } |
| 3829 | + }); |
| 3830 | + hostElement.dispatchEvent(evt); |
| 3831 | + })(); |
| 3832 | + } |
| 3833 | + |
| 3834 | + // this.flushRenderStamperComponentBindings_(); |
| 3835 | + |
| 3836 | + |
3716 | 3837 |
|
3717 | 3838 |
|
3718 | 3839 | });
|
3719 |
| - } |
| 3840 | + }; |
| 3841 | + |
3720 | 3842 |
|
3721 | 3843 | const stampIdxSb = Symbol();
|
3722 | 3844 | const createStampDomArrayFn_ = (fn) => {
|
|
3726 | 3848 | }
|
3727 | 3849 | const gn = function (a, b, c, d, shouldTriggerRendererStamperFinished, h) {
|
3728 | 3850 | // this.__$$StampDomCounter$$__ = (this.__$$StampDomCounter$$__ || 0) + 1;
|
3729 |
| - const isNonEmptyArray = (a || 0).length >= 1 |
| 3851 | + if (a.length === 1 && Object.keys(a[0]).length === 0) a.length = 0; |
| 3852 | + const isNonEmptyArray = (a || 0).length >= 1; |
3730 | 3853 | if (!isNonEmptyArray) {
|
3731 | 3854 | return fn.call(this, undefined, b, undefined, d);
|
3732 | 3855 | } else if (h === undefined && typeof b === 'string' && c && typeof c === 'object' && this.is && val_kevlar_should_maintain_stable_list) {
|
|
3751 | 3874 |
|
3752 | 3875 | if (container) {
|
3753 | 3876 |
|
3754 |
| - ((container && container.__domApi) || fn.call(this, undefined, b, undefined, d)); |
3755 |
| - |
3756 |
| - const domShell = container && container.__domApi; |
3757 |
| - const fulfillment = domShell && domShell.appendChild && domShell.firstElementChild === null; |
3758 |
| - |
3759 |
| - // if(a.length > 10) console.log('createStampDomArrayFnE1_',392, domHolder, b2, p) |
3760 |
| - if (fulfillment) { |
3761 |
| - createStampDomArrayFnE1_.call(this, a, b, c, d, shouldTriggerRendererStamperFinished, h); |
3762 |
| - return; |
| 3877 | + let domShell = (container && container.__domApi); |
| 3878 | + |
| 3879 | + if (!domShell) { |
| 3880 | + fn.call(this, undefined, b, undefined, d); |
| 3881 | + domShell = container && container.__domApi; |
3763 | 3882 | }
|
3764 |
| - |
| 3883 | + |
| 3884 | + |
| 3885 | + if (domShell && domShell.appendChild) { |
| 3886 | + |
| 3887 | + if (domShell.firstElementChild === null) { |
| 3888 | + createStampDomArrayFnE1_.call(this, a, b, c, d, shouldTriggerRendererStamperFinished, h); |
| 3889 | + return; |
| 3890 | + } else if (DO_createStampDomArrayFnF1_ && domShell.firstElementChild instanceof Node_) { |
| 3891 | + // let t1 = performance.now(); |
| 3892 | + let error = 0; |
| 3893 | + const createDocumentFragment = document.createDocumentFragment; |
| 3894 | + document.createDocumentFragment = function () { |
| 3895 | + throw new Error("DN96IZkGLTY6"); |
| 3896 | + } |
| 3897 | + let r; |
| 3898 | + try { |
| 3899 | + r = fn.call(this, a, b, c, d, shouldTriggerRendererStamperFinished, h); |
| 3900 | + } catch (e) { |
| 3901 | + error = (e.message === 'DN96IZkGLTY6') ? 1 : e; |
| 3902 | + } |
| 3903 | + document.createDocumentFragment = createDocumentFragment; |
| 3904 | + if (!error) return r; |
| 3905 | + if (error !== 1) throw e; |
| 3906 | + // let t2 = performance.now(); |
| 3907 | + // console.log('createStampDomArrayFnF1_', t2-t1); |
| 3908 | + createStampDomArrayFnE1_.call(this, a, b, c, d, shouldTriggerRendererStamperFinished, h); |
| 3909 | + return; |
| 3910 | + } |
| 3911 | + |
| 3912 | + } |
| 3913 | + |
| 3914 | + |
3765 | 3915 | }
|
3766 | 3916 |
|
3767 | 3917 |
|
|
0 commit comments