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

Syntax error of Worker code in IE11 #58

Open
wyleung opened this issue Jan 17, 2017 · 21 comments
Open

Syntax error of Worker code in IE11 #58

wyleung opened this issue Jan 17, 2017 · 21 comments

Comments

@wyleung
Copy link

wyleung commented Jan 17, 2017

Thank you for the great work on this VectorGrid!

It works fine in Webkit based browsers and Edge. However, when I was testing it in IE 11, it was crashing on: https://github.com/Leaflet/Leaflet.VectorGrid/blob/master/src/Leaflet.VectorGrid.Slicer.js#L33

I'd not take any actions yet to debug / rewrite this part of code. Is anyone seeing the same issue ?

@IvanSanchez
Copy link
Member

We'll need more information. What is the exact parse error?

By using an instance of Chrome (or Chromium) and using the "sources" tab of the dev console, it's easy to see the code that the worker is running. If you copy-paste that code into a standalone file and load it with IE11, does a (better) error appear?

@wyleung
Copy link
Author

wyleung commented Jan 17, 2017

Setup:

Leaflet v1.0.2
Leaflet.VectorGrid: https://leaflet.github.io/Leaflet.VectorGrid/dist/Leaflet.VectorGrid.bundled.js
Internet Explorer: 11.0.9600.18537

Screenshot:

virtualbox_ie11 - win7_17_01_2017_11_16_28

@IvanSanchez
Copy link
Member

Yeah, it's failing to parse the code inside the blob:, but it's not displaying any good information on which line is failing. This will need a bit of extra investigation. :-(

@wyleung
Copy link
Author

wyleung commented Jan 17, 2017

@IvanSanchez Too bad :( I can spend some time on this issue today..

@dosstx
Copy link

dosstx commented Jan 17, 2017

I had this same issue at the office, but I can't seem to replicate at home. I think I solved it by adding some polyfills to the head of my HTML like so:

<script src="fetch-ie8/fetch.js"></script>
<script src="es6-promise/dist/es6-promise.js"></script> 

Does that solve your issue? Make sure you grab the latest versions of those polyfills because I think there was some bad code in earlier versions.

You can try my demo and see if you have any issues with the web workers: https://goo.gl/GeavZS

@jklongi
Copy link

jklongi commented Mar 8, 2017

I am also getting this in IE all version except Edge. Very hard to debugg since its inside the blob. Any news / suggestions on this? The solution by dosstx did not work.

@dosstx
Copy link

dosstx commented Mar 8, 2017

@jklongi Did you add the function to your code to call the polyfills?

ES6Promise.polyfill();

I'm using IE11 and it works for me....

@perliedman
Copy link
Member

I don't think any of the maintainers have IE as a priority, so this would be a good time to step up and submit a PR! We would really appreciate help with this.

@jklongi
Copy link

jklongi commented Mar 9, 2017

@dosstx Yes I did but it doesn't help. I cant get my code or nor even your example to work. Just facing the same error as @wyleung . I am using browserstack and couple real windows machines to get IE 11 & 10 but not any of them work.

I looked into it and I think the function that gives the worker code __$strToBlobUri is returning the blob in every other browser like so: "blob:http://localhost:8000/fe350922-c073-4d79-af88-cf5c194ccfac" but in IE it returns the blob input as a string but it has been cut off like so:

"data:text/plain; charset=us-ascii,'use strict';

var simplify_1 = simplify$1;

// calculate simplification data using optimized Douglas-Peucker algorithm

function simplify$1(points, tolerance) {

    var sqTolerance = tolerance * tolerance,
        len = points.length,
        first = 0,
        last = len - 1,
        stack = [],
        i, maxSqDist, sqDist, index;

    // always retain the endpoints (1 is the max value)
    points[first][2] = 1;
    points[last][2] = 1;

    // avoid recursion by using a stack
    while (last) {

        maxSqDist = 0;

        for (i = first + 1; i < last; i++) {
            sqDist = getSqSegDist(points[i], points[first], points[last]);

            if (sqDist > maxSqDist) {
                index = i;
                maxSqDist = sqDist;
            }
        }

        if (maxSqDist > sqTolerance) {
            points[index][2] = maxSqDist; // save the point importance in squared pixels as a z coordinate
            stack.push(first);
            stack.push(index);
     "

However the stuff inside that function might be beyond my skill to debugg..

@jklongi
Copy link

jklongi commented Mar 9, 2017

I was actually able to (kind of) solve this by using the workerCode from version 1.1.0 and calling the worker with this._worker = new Worker(window.URL.createObjectURL(new Blob([workerCode])));
So there is something going on with the forming of new worker code through that __$strToBlobUri function.

@msully
Copy link

msully commented Apr 18, 2017

Thanks @IvanSanchez for creating a great Leaflet Plugin.
I have the same issue with IE 11 as reported.

Any recommendations for a fix?

@msully
Copy link

msully commented Apr 25, 2017

@IvanSanchez this may be helpful in understanding the IE 11 issue.
A web application that uses the Web Worker blob method may not function in Internet Explorer 11
https://support.microsoft.com/en-us/help/3023851

@IvanSanchez
Copy link
Member

@msully Hhhhmmm, not very helpful, albeit interesting.

Maybe loading the VectorGrid file with a <script src=... crossorigin='anonymous'> will make something happen?

@msully
Copy link

msully commented May 10, 2017

@IvanSanchez unfortunately loading the VectorGrid file <script src=... crossorigin='anonymous'> had no effect.

Two steps to resolve the IE11 issue:

  1. I remove the variable "workerCode" as a blob URL and moved the worker code into an external file lccWebWorker.js.
    Then referenced it as var lccworkerCode = './js/lccWebWorker.js';
initialize: function(t, e) {
        L.VectorGrid.prototype.initialize.call(this, e);
        var e = {};
        var lccworkerCode = './js/lccWebWorker.js';
        for (var r in this.options) "rendererFactory" !== r && "vectorTileLayerStyles" !== r && "function" != typeof this.options[r] && (e[r] = this.options[r]);
        this._worker = new Worker(lccworkerCode), this._worker.postMessage(["slice", t, e])
    },
  1. Added IE 11 Promise support: http://stackoverflow.com/questions/36016327/how-to-make-promises-work-in-ie11

A working example : Grass cutting map

@Harvinator
Copy link

Harvinator commented Jul 13, 2017

Thanks @msully

For me I changed one line in the L.VectorGrid.Slicer initialize function

From...
this._worker = new Worker(workerCode);
To...
this._worker = new Worker(options.workerCode || workerCode);

Then when creating my layer

L.vectorGrid.slicer(geoJson, {
    workerCode: '/path/to/Leaflet.VectorGrid/WebWorker.js',
    [...]
}).addTo(map);

The code that goes in WebWorker came from var workerCode = __$strToBlobUri("...HERE..."); in the distributed source (just had to replace \n with new line and \" with ")

@perliedman
Copy link
Member

@Harvinator does VectorGrid still work in Chrome/Firefox etc. after these changes?

If so, would you be able to make a pull request? It's very hard to review the changes you made when just pasting code into a comment. Pull requests are ideal for this.

@Harvinator
Copy link

@perliedman I've tested in Chrome and it does work yes.

Created pull request #109

(Also edited my above comment to remove all of the worker code I unnecessarily copy/pasted in)

@protchenkos
Copy link

Are there any plans to merge #109 and publish updated version to npm?

@2803media
Copy link

Any update on this problem for IE 11? Thanks

@2803media
Copy link

@Harvinator do you please provide a working example I can't find a way to make it works ! Thanks in advance

@2803media
Copy link

2803media commented Sep 19, 2018

For those who search a working WebWorker.js here is the gist: https://gist.github.com/2803media/2c2e370fb317311969bd9efcea09e521

The trick is to load the regular script for all browsers except for IE like that:

            `<script type="text/javascript">
	var ua = window.navigator.userAgent;
	var msie = ua.indexOf("MSIE ");

	if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {
		document.write('<script type="text/javascript" src="/wp-content/themes/mytheme/js/Leaflet.VectorGrid.bundled.min2.js"><\/script>');
		document.write('<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.js"><\/script>');
		document.write('<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"><\/script>');
	} else {
		document.write('<script type="text/javascript" src="/wp-content/themes/codium-dn/js/Leaflet.VectorGrid.bundled.min.js"><\/script>');
	}
</script>`

Notice the difference for Leaflet.VectorGrid.bundled.min2.js versus Leaflet.VectorGrid.bundled.min.js which is the official one. The gist of Leaflet.VectorGrid.bundled.min2.js is here: https://gist.github.com/2803media/f32ec54340d1d03b44fa0f3609480690

After as @Harvinator said you load the slice like that:

             `if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))  // If Internet Explorer, return version number
					    {
								vectorGrid2 = L.vectorGrid.slicer( geojsonLayer, {
									workerCode: '/wp-content/themes/mytheme/js/WebWorker.js',
									rendererFactory: L.canvas.tile,
									vectorTileLayerStyles: {
										sliced: {
										fillOpacity: 0.1,
										color: 'blue',
										weight: 1,
										stroke: true,
										fill: true,
										}
									},
									interactive: true,
									maxZoom: 19, // max zoom to preserve detail on
									tolerance: 20, // 5 simplification tolerance (higher means simpler)
									extent: 4096, //4096, // 4096 tile extent (both width and height)
									buffer: 64, // 64 default 64tile buffer on each side
									indexMaxZoom: 0, // 0 max zoom in the initial tile index
									indexMaxPoints: 100000, // 100000 max number of points per tile in the index
								}).addTo(map);

							} else {
								vectorGrid2 = L.vectorGrid.slicer( geojsonLayer, {
									rendererFactory: L.canvas.tile,
									vectorTileLayerStyles: {
										sliced: {
										fillOpacity: 0.1,
										color: 'blue',
										weight: 1,
										stroke: true,
										fill: true,
										}
									},
									interactive: true,
									maxZoom: 19, // max zoom to preserve detail on
									tolerance: 20, // 5 simplification tolerance (higher means simpler)
									extent: 4096, //4096, // 4096 tile extent (both width and height)
									buffer: 64, // 64 default 64tile buffer on each side
									indexMaxZoom: 0, // 0 max zoom in the initial tile index
									indexMaxPoints: 100000, // 100000 max number of points per tile in the index
								}).addTo(map);
							}`

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

No branches or pull requests

9 participants