-
Notifications
You must be signed in to change notification settings - Fork 90
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
Use vega-loader for validating links #47
Conversation
Currently, it is implemented for dataURL (like |
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.
This approach won't work for nested specs. We need to create a custom loader and pass a baseUrl around. The loader would first try the baseUrl and if that returns a 404, try a link relative to the editor.
src/components/app.tsx
Outdated
if (error.target.status === 404) { | ||
// Relative to caller | ||
this.loaderPromise({baseURL: evt.origin}, dataURL).then(() => { | ||
parsed['data']['url'] = evt.origin + dataURL; |
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.
This won't work if we have a nested spec. Instead of this approach, we should set a baseUrl in the state and create a custom Vega loader. Here is some inspiration: https://github.com/domoritz/draco/blob/master/draco-tools/src/shared/js/components/Visualization.js#L50
src/components/app.tsx
Outdated
const dataURL = parsed['data']['url']; | ||
|
||
// Checking wheather link is absolute or relative to editor | ||
this.loaderPromise({baseURL: 'https://vega.github.io/editor/'}, dataURL).then((data) => { |
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 think we should first check whether the URL is absolute. In that case, we won't do anything.
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.
vega-loader
already checks whether it is absolute or not. If not then I am checking it with relative to the editor which means we aren't doing anything when URL is absolute. I tested it.
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.
Okay, this will might change when we switch to a custom loader.
This is irrelevant with the fix I am proposing above. |
I'd love to get this in. Can I help with anything @ydlamba? |
I understand your approach, working on it. |
f3a60a8
to
10d17c6
Compare
src/components/app.tsx
Outdated
console.info('[Vega-Editor] Received Message', evt.origin, data); | ||
// send acknowledgement | ||
const parsed = JSON.parse(data.spec); | ||
let dataURL = parsed['data']['url']; |
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.
Let's delete this. We shouldn't expect a spec to have a URL data source.
src/components/app.tsx
Outdated
const editorURL = 'https://vega.github.io'; | ||
const loader = vega.loader(); | ||
const options = { | ||
baseURL: this.props.baseURL |
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.
Instead of forcing the baseURL, try to check for every request whether it makes sense to change the baseURL. First, check whether there is data at the evt.origin
that you grabbed above. If not, use the editor as the base.
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.
This isn't quite what I was hoping for. Can you override how the loader loads a single resource?
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.
Here is my proposal. Let me know what you think.
src/components/app.tsx
Outdated
/** | ||
* Async function that updates the baseURL (if gets 404) | ||
*/ | ||
public async updateBaseUrl(url: string){ |
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.
This can be deleted
src/components/app.tsx
Outdated
console.info('[Vega-Editor] Received Message', evt.origin, data); | ||
// send acknowledgement | ||
const parsed = JSON.parse(data.spec); | ||
if(parsed['data']['url']) { |
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.
delete this as well
src/components/app.tsx
Outdated
@@ -134,6 +159,12 @@ class App extends React.Component<Props & {match: any, location: any}> { | |||
} | |||
} | |||
|
|||
function mapStateToProps(state: State, ownProps) { |
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.
delete this as well
src/components/app.tsx
Outdated
@@ -160,4 +194,4 @@ const mapDispatchToProps = function(dispatch) { | |||
}; | |||
}; | |||
|
|||
export default withRouter(connect(null, mapDispatchToProps)(App)); | |||
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App)); |
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 undo this now
src/components/renderer/renderer.tsx
Outdated
.logLevel(vega.Warn) | ||
.initialize(Editor.chart); | ||
|
||
Editor.view = new vega.View(runtime, { |
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.
Use something like this instead
const runtime = vega.parse(props.vegaSpec);
const loader = vega.loader();
const originalHttp = loader.http;
loader.http = async(url, options) => {
try {
return await originalHttp(url, {options, ...{baseURL: this.props.baseURL}});
} catch {
return await originalHttp(url, options);
}
};
Editor.view = new vega.View(runtime, {
loader: loader,
logLevel: vega.Warn,
})
.initialize(Editor.chart);
I haven't tested this but I think this communicates the idea.
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 think there is some problem with loader.http
, its baseURL option is not working. Instead loader.load
is working fine.
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 have created the issue as well.
PR is now updated. I have tested this and working as expected (just with few minor changes). You can also have a look. |
src/components/renderer/renderer.tsx
Outdated
// Custom Loader | ||
loader.load = async(url, options) => { | ||
try { | ||
return await originalLoad(url, {options, ...{baseURL: this.props.baseURL}}); |
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.
- it should be ...options, right?
- what if options is undefined?
- shouldn't custom options override our baseurl? (this one os less important and you can ignore it)
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 guess you are thinking about options in options. Actually, we need to add baseURL directly in the options.
...options
will appendbaseURL
in options of options (nested object) whileoptions
will directly add baseURL in options. I tested it, working fine.- We don't need to worry about options (not options in options) loader is taking care of it.
- Ignored for now.
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.
So, if we go for loader.load(url, {options: {baseURL: this.props.baseURL}})
it won't work.
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'm confused. I thought the behavior of ...options and just options is flipped from how you describe it. I will test it when I'm.at a computer again.
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 think I was right.
options = {foo:42, bar: 123}
$ {...options, ...{baseUrl: 'foo.bar'}}
{foo: 42, bar: 123, baseUrl: "foo.bar"} // good
$ {options, ...{baseUrl: 'foo.bar'}}
{options: {foo: 42, bar: 123}, baseUrl: "foo.bar"} // not good
See https://github.com/vega/vega-loader#loader for documentation of the loader. We want all options at the top level.
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.
Yeah. This is correct. I was thinking it the wrong way, nevermind. I've updated the PR.
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.
Last question. Why override load and not http?
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.
Because loader.http
method performs an HTTP request with a post-sanitization URL i.e we don't have baseURL option with this method. On the other hand, loader.load
does all processing itself.
For more info check this vega/vega-loader#7.
Sweet, just one comment. |
Changes are done, please let me know if I am missing something. |
Use vega-loader for validating links
absolute
orrelative to the editor
. If gets404
then check whether it isrelative to the caller
and if still gets an error then throws it.Fixes #30.