Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

waitForChildren might still not be reliable #33

Closed
fregante opened this issue Jan 14, 2021 · 5 comments
Closed

waitForChildren might still not be reliable #33

fregante opened this issue Jan 14, 2021 · 5 comments
Labels

Comments

@fregante
Copy link
Collaborator

fregante commented Jan 14, 2021

So this happened:

Screen Shot 7 Screen Shot 8

"7 years old" should be .appended to this block, but on my slow connection it was .appended before the block finished loading.

This matches exactly the situation that this feature was supposed to prevent. It selected the correct element but when elementReady resolved the element wasn't fully done yet.

Happened on: https://github.com/npmhub/npmhub
Source: https://github.com/sindresorhus/refined-github/blob/cd2788a4114de6fdfc42a9a13a018cf4ee8caf8e/source/features/repo-age.tsx#L102
Browser: Safari

@fregante fregante added the bug label Jan 14, 2021
@sindresorhus
Copy link
Owner

sindresorhus commented Jan 14, 2021

Could you try putting

stop(element);
in a setTimeout call, just to rule out any race issue.


Only Safari?

@fregante
Copy link
Collaborator Author

Only Safari?

Unsure. I tried building a repro but I can't replicate the issue: https://refined-github-html-preview.kidonng.workers.dev/sindresorhus/element-ready/raw/d57faa6/large-demo.html

  • Green bar: shows what happens when .append is called at random while the page load.
  • Red bar: same, but uses elementReady with the same selector

The red bar is consistently at the bottom.

@fregante
Copy link
Collaborator Author

I was able to replicate consistently it on Chrome too, but not on the same page. In normal circumstances, the text should have appeared to the right side of the sidebar, but it appeared before:

Screen Shot 9

  1. I set the network speed to 10kbps / 500ms response time
  2. Loaded https://github.com/npmhub/npmhub
  3. Ran this code in the console as soon as possible:
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).elementReady=e()}}(function(){return function(){return function e(t,r,s){function n(i,u){if(!r[i]){if(!t[i]){var c="function"==typeof require&&require;if(!u&&c)return c(i,!0);if(o)return o(i,!0);var l=new Error("Cannot find module '"+i+"'");throw l.code="MODULE_NOT_FOUND",l}var a=r[i]={exports:{}};t[i][0].call(a.exports,function(e){return n(t[i][1][e]||e)},a,a.exports,e,t,r,s)}return r[i].exports}for(var o="function"==typeof require&&require,i=0;i<s.length;i++)n(s[i]);return n}}()({1:[function(e,t,r){"use strict";const s=Symbol("null");let n=0;t.exports=class extends Map{constructor(){super(),this._objectHashes=new WeakMap,this._symbolHashes=new Map,this._publicKeys=new Map;const[e]=arguments;if(null!=e){if("function"!=typeof e[Symbol.iterator])throw new TypeError(typeof e+" is not iterable (cannot read property Symbol(Symbol.iterator))");for(const[t,r]of e)this.set(t,r)}}_getPublicKeys(e,t=!1){if(!Array.isArray(e))throw new TypeError("The keys parameter must be an array");const r=this._getPrivateKey(e,t);let s;return r&&this._publicKeys.has(r)?s=this._publicKeys.get(r):t&&(s=[...e],this._publicKeys.set(r,s)),{privateKey:r,publicKey:s}}_getPrivateKey(e,t=!1){const r=[];for(let o of e){null===o&&(o=s);const e="object"==typeof o||"function"==typeof o?"_objectHashes":"symbol"==typeof o&&"_symbolHashes";if(e)if(this[e].has(o))r.push(this[e].get(o));else{if(!t)return!1;{const t=`@@mkm-ref-${n++}@@`;this[e].set(o,t),r.push(t)}}else r.push(o)}return JSON.stringify(r)}set(e,t){const{publicKey:r}=this._getPublicKeys(e,!0);return super.set(r,t)}get(e){const{publicKey:t}=this._getPublicKeys(e);return super.get(t)}has(e){const{publicKey:t}=this._getPublicKeys(e);return super.has(t)}delete(e){const{publicKey:t,privateKey:r}=this._getPublicKeys(e);return Boolean(t&&super.delete(t)&&this._publicKeys.delete(r))}clear(){super.clear(),this._symbolHashes.clear(),this._publicKeys.clear()}get[Symbol.toStringTag](){return"ManyKeysMap"}get size(){return super.size}}},{}],2:[function(e,t,r){"use strict";t.exports=(()=>{const e={};return e.promise=new Promise((t,r)=>{e.resolve=t,e.reject=r}),e})},{}],3:[function(e,t,r){"use strict";const s=e("many-keys-map"),n=e("p-defer"),o=new s;t.exports=((e,{target:t=document,stopOnDomReady:r=!0,waitForChildren:s=!0,timeout:i=1/0}={})=>{const u=[e,r,i,s,t],c=o.get(u);if(c)return c;let l;const a=n(),{promise:p}=a;o.set(u,p);const f=e=>{cancelAnimationFrame(l),o.delete(u,p),a.resolve(e)};return i!==1/0&&setTimeout(f,i),function n(){const o=t.querySelector(e);if((e=>["interactive","complete"].includes((e.ownerDocument||e).readyState))(t)&&(r||o))return void f(o||void 0);let i=o;for(;i;){if(!s||i.nextSibling)return void f(o);i=i.parentElement}l=requestAnimationFrame(n)}(),Object.assign(p,{stop:()=>f()})})},{"many-keys-map":1,"p-defer":2}]},{},[3])(3)});;
elementReady('.gutter-condensed').then(el => el.append('YOOOOOOOOOOOOOOOOOOOOO'))

@sindresorhus
Copy link
Owner

Maybe this has something to do with GitHub modifying the DOM?

@fregante
Copy link
Collaborator Author

Maybe this has something to do with GitHub modifying the DOM?

Not as far as I know, that content appears in the static HTML in both cases.

However it's very likely that this is caused by Refined GitHub itself since I can't replicate it without it.

When nextSibling is encountered we can't tell whether it comes from the HTML or if was added by another rogue script. While technically this is a "bug" in element-ready, I don't think it can be solved for this reason.

As for RG’s bug described in the first post, I can investigate once refined-github/refined-github#2586 is added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants