2

I'll be using window.postMessage("", "*", [transferableData]) to send data between two browser windows. However, I didn't find any straight answer on how to convert types into Transferables.

So, in order for me to start learning this, it would be great to know how to convert a simple String into an Transferable (ByteBuffer) and read it on the other side (the side that is getting the message with the data). This would help me solving my problem and learning about this concept.

IMPORTANT UPDATE:

This question led me here: Dart Language: printing reports

Transferable Objects are not yet implemented on Dart VM (http://dartbug.com/4149). That means, if you're running your application via Dartium (Dart VM) the other window will be receiving and processing the first argument of postMessage, and not the Transferable Object. However, JavaScript does the job: the object gets transfered and the original array, emptied.

Community
  • 1
  • 1
Felipe
  • 376
  • 2
  • 5
  • 15
  • 1
    window.postMessage() should accept strings, shouldn't it? – Robert Nov 22 '14 at 14:28
  • @Robert, I'm sorry. I forgot to say that I would be using postMessage to send Transferable data => window.postMessage("", "*", [transferableData]). – Felipe Nov 22 '14 at 14:30
  • You mentioned, that `postMessage` truncates the message. I haven't found anything about a maximum message length for `postMessage` though. – Günter Zöchbauer Nov 22 '14 at 14:40

1 Answers1

2
import 'dart:convert';

var list = Utf8.encode('xxx');
var data = list is Uint8List ? list.buffer : new Uint8List.fromList(list).buffer;

to send the data using window.PostMessage use

window.postMessage({'data': data}, '*', [data]);

and read it on the receiver side like

var string = Utf8.decode(message.data['data']);

See also http://dartbug.com/19968 for the status of transferrables.
The recent Dart dev channel release already ships with Dartium 38.xxx as far as I know.
Here is a small test case for transferrables https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/transferables_test.dart

Greg Lowe
  • 15,430
  • 2
  • 30
  • 33
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    The `codeUnits` getter returns a list of 16-bit integers. Creating a `Uint8List` from these will throw away the higher bits, so this solution only works for Latin-1 strings. Either use a `Uint16List` or do UTF-8 encoding first. – lrn Nov 23 '14 at 16:25
  • Guenter I updated the comment based on lrn's comment - feel free to tweak it. Note Utf8.encode() as it is currently implemented always returns a Uint8List. But it's probably better to play it safe and to check the type. – Greg Lowe Nov 23 '14 at 21:43
  • @GregLowe That was not just fixing typos. I think in such a case it's better to add another answer instead of editing an existing one. Actually I find it a good thing when there is more than one answer to a question. Thanks anyway. – Günter Zöchbauer Nov 23 '14 at 21:57
  • As a user I find it better to read through fewer - but correct comments, rather than having to check multiple answers and each comment threads for errors. I think it's better to work together as a team to create up-to-date correct comments - but I respect your difference of opinion, and won't do this to your answers again. Also - I checked here http://stackoverflow.com/help/editing, I would consider my edit to be described as: "To correct minor mistakes". – Greg Lowe Nov 23 '14 at 23:28
  • It seems our opinions differs on "minor mistake". In my opinion the change was substantial enough to become an answer on its own right. I like to see different answers and comments about the advantages and disadvantages because often there isn't just one right answer. I also like being proven wrong because these are the moments where I learn most. I also like getting credit for my own work and be able to give credit to other valuable contributions as yours usually are but this doesn't work if you don't add your own answer. – Günter Zöchbauer Nov 24 '14 at 05:21
  • @GünterZöchbauer, it seems that Dart is not working with Transferable yet. So the code is working because the new window is receiving the data from the first argument from postMessage. Take a look at this: https://code.google.com/p/dart/issues/detail?id=4149 – Felipe Nov 28 '14 at 01:09
  • Hmm, when you build it to JavaScript this shouldn't matter. The linked issue seems to be about Dart isolates only. When I investigated the topic I read somewhere that the array is empty on the senders side after passing it to the other window. You could verify that by adding a print statement after the `postMessage` statement (might only work when run as JS). – Günter Zöchbauer Nov 28 '14 at 05:14
  • @GünterZöchbauer, I did. Actually that's why I suspected that Dart was not working with Transferable Objects yet. The array didn't get emptied. So I started looking for some examples. In fact, the method description doesn't say anything about Transferable Objects: WindowBase.postMessage(dynamic message, String targetOrigin, [List messagePorts]) → void. If what I suspect is true, I should edit the question in order to make it clear that this is not implemented on Dart yet. – Felipe Nov 28 '14 at 16:31
  • The comments on this issue http://dartbug.com/4149 seem to say that it is not available when run in a Dart VM. – Günter Zöchbauer Nov 28 '14 at 16:39
  • 1
    @GünterZöchbauer, I've tested it and it's exactly what they're saying there: it does not work on Dart VM yet, but on JavaScript build it works fine (array gets emptied). I will update the question with this information. Thanks! – Felipe Nov 28 '14 at 16:50