-
Notifications
You must be signed in to change notification settings - Fork 64
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
Issue 414 #425
Issue 414 #425
Changes from 3 commits
8507dce
240b70b
6f78d3f
04d0da5
8480090
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,6 +80,37 @@ function create(elOrId: string|Element, params: PileupParams): Pileup { | |
ReactDOM.render(<Root referenceSource={referenceTrack.source} | ||
tracks={vizTracks} | ||
initialRange={params.range} />, el); | ||
|
||
//if the element doesn't belong to document DOM observe DOM to detect | ||
//when it's attached | ||
var observer = null; | ||
if (!document.contains(el)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TIL that but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I dissagree with this answer at SO. Here you have better source: It is a standard, the only remark is that IE doesn't support it for document but only for document.body. I can change it to document.body if it solves the problem. Anyway, I took it from this answer at SO: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as an alternative, you can do: var contains = document.contains || document.body.contains;
if (!contains(el)) {
...
} PhantomJS framework can sometimes surface issues like this; but, the pros still outweigh its cons, so we are still sticking to it. Also, any such issue will affect people trying to render views in headless mode, so it would be great if we address this even though it is a weird workaround. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this doesn't work: I get some strange Invalid invocation error in Chrome, Firefox reports different error... But I fixed it by replacing: |
||
observer = new MutationObserver(function(mutations) { | ||
mutations.forEach(function(mutation) { | ||
if (mutation.type === 'childList') { | ||
var added= false; | ||
for (var i=0; i<mutation.addedNodes.length;i++) { | ||
if (mutation.addedNodes[i]===el) { | ||
added = true; | ||
} | ||
} | ||
if (added) { | ||
if (reactElement) { | ||
reactElement.setState({updateSize:true}); | ||
} else { | ||
throw 'ReactElement was not initialized properly'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you give me an example why we might need this error? Looks like this type of an error is out of the scope for pileup.js? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, I don't like when the code fails to do what it's supposed to do and don't give any hint what went wrong. But it's your code so I can remove it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I say we keep it if you hit this problem when trying to solve this issue. The check for the reactElement happens deep within that also: it is also your code now; so we get to decide on the best practice together ;) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can move it up. But it must be inside MutationObserver constructor.
Anyway, where do you want to move it? Inside forEach loop? (line 90) |
||
} | ||
} | ||
} | ||
}); | ||
}); | ||
// configuration of the observer: | ||
var config = { attributes: true, childList: true, characterData: true, subtree: true }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we are only looking for mutations of type There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably you are right, I will check it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks a lot! |
||
|
||
// start observing document | ||
observer.observe(document, config); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have no experience with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also don't have any experience. I found an article here: I was thinking about watching proper elements, but I couldn't find any better solution. My first idea was quite opposit - watch our node element if it's parent has changed, but I couldn't make it work (even though that MutationObserver in theoury allows to observe modification of node attributes - maybe parent is not treated as an attribute...). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough. If you don't have any performance issues in your complex application after this change, it is unlikely that we will have that for other simpler applications. Thanks for the pointer! |
||
} | ||
|
||
return { | ||
setRange(range: GenomeRange) { | ||
if (reactElement === null) { | ||
|
@@ -104,6 +135,11 @@ function create(elOrId: string|Element, params: PileupParams): Pileup { | |
reactElement = null; | ||
referenceTrack = null; | ||
vizTracks = null; | ||
|
||
// disconnect observer if it was created | ||
if (observer !== null && observer !== undefined) { | ||
observer.disconnect(); | ||
} | ||
} | ||
}; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about using some underscore utilities to make this code more concise? For example:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do that, but for me this code is really hard to read and understand. This later on will influence time spent on debuging and improving code.
But this is my opinion. Maybe for Javascript developers this syntax is obvious and easy to read :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
your version is definitely more explicit, but let's delegate some of the logic to underscore for clarity. The for-loop-based check is a pretty common pattern, so I think it is safe to replace that with the
filter
method. What we can do is to add a few sentences in between the chain so that it becomes more obvious for future developers taking a look at the code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will leave it to you. I don't know underscore notation.