WEBVTT 01:13:14.033 --> 01:13:43.547 Engineering (VisualEditor) Against the Odds 01:13:49.087 --> 01:13:52.723 Alright 01:13:52.723 --> 01:13:56.493 Hello, everybody. I'm Trevor Pascal. 01:13:56.493 --> 01:14:04.094 This is Roan Kattouw and Ed Sanders, we work at the Wikimedia Foundation, specifically the VisualEditor 01:14:04.094 --> 01:14:09.789 and today we want to talk to you a little bit about some of the challenges that we have to deal with 01:14:09.789 --> 01:14:12.719 for the past couple of years 01:14:12.719 --> 01:14:18.791 and how working on VisualEditor is essentially engineering 'Against the odds'. 01:14:18.791 --> 01:14:22.300 And so in fact we have found that the odds are against us. 01:14:22.300 --> 01:14:28.729 But can anyone guess what makes creating VisualEditor so difficult ? 01:14:28.729 --> 01:14:32.518 Like what sort of things are standing in our way ? 01:14:32.518 --> 01:14:37.119 - The community The community.. definitely NOT ! 01:14:37.119 --> 01:14:41.093 The green shirt ? - Ehm browser support ? 01:14:41.093 --> 01:14:48.533 Having to support like everything like IE6 and mobile ? - Oh [....] I don't think we ever claimed IE6 support... 01:14:48.533 --> 01:14:51.834 Anyone else ? - Working with wiki text 01:14:51.834 --> 01:14:58.370 Ah, yeah OK now we are getting good So yeah definitely differences in Operating Systems 01:14:58.370 --> 01:15:04.213 different kinds of computers people are using.. That includes like laptops, tablets, phones. 01:15:04.213 --> 01:15:09.516 We are moving towards getting mobile support going. 01:15:09.516 --> 01:15:17.660 And also.. It turns out even for modern browsers this is still a problem. I mean these are not the IE6. 01:15:17.660 --> 01:15:23.576 Ehm.. but... even in modern browsers there is a lot of huge differences even at this point in time. 01:15:23.576 --> 01:15:27.931 And they don't really seem to agree on how standards should be done 01:15:27.931 --> 01:15:31.206 at least not when you get down to the nitty gritty details. 01:15:31.206 --> 01:15:35.022 And eh we sort of demand a little rigor 01:15:35.022 --> 01:15:42.418 But also yes, wikitext. It is a huge issue for us. There is a lot of ambiguities, there is lot of limitations, 01:15:42.418 --> 01:15:45.228 there is a lot of design flaws and they bubble up into the User Interface 01:15:45.228 --> 01:15:48.689 and users get really confused about what is going on. 01:15:48.689 --> 01:15:51.780 because it doesn't quite work the way Microsoft Word works, 01:15:51.780 --> 01:15:56.150 because wikitext is not the same as Microsoft Word. It's a data? format. 01:15:56.150 --> 01:16:00.312 And so we have to work very hard just to maintain compatibility. 01:16:00.312 --> 01:16:03.288 And eh... isn't that so sad. 01:16:03.288 --> 01:16:08.924 But we are really hoping to share some of these experiences with you, 01:16:08.924 --> 01:16:15.202 not necessarily to make you cry, but because we think there are some interesting challenges, 01:16:15.202 --> 01:16:20.507 most of which we have overcome and there are some kinda exciting stories to tell. 01:16:20.507 --> 01:16:27.252 So to tell the first one, I'm going to switch over to Roan Kattouw, who is going to talk to us about Wikitext. 01:16:29.128 --> 01:16:33.490 Alright, so Let's talk wikitext. 01:16:33.913 --> 01:16:37.810 Wikitext, like Trevor said, is a limiting factor to us. 01:16:37.810 --> 01:16:40.887 And one of the main problems is that if you are a VisualEditor user, 01:16:40.887 --> 01:16:45.816 if you are like a VisualEditor-only user, then as far as you are concerned wikitext does not exist. 01:16:45.816 --> 01:16:51.879 Like it is our job and our goal to pretend to these people that wikitext has never been there 01:16:51.879 --> 01:16:55.867 and will never be there and they can live in this sort of fantasyland where they don't have to deal with it. 01:16:55.867 --> 01:17:03.385 Which works [...] for most of our [...] but the reality is that wikitext sort of [..] there. 01:17:03.385 --> 01:17:10.215 and users might want to do things that you can't do nicely or can't do at all in wikitext. 01:17:10.215 --> 01:17:15.049 And so it ends up being that wikitext limits the users in what they can do. 01:17:15.049 --> 01:17:20.507 We can't let them do things that are not representable in wikitext or that produce very ugly wikitext 01:17:20.507 --> 01:17:22.128 because people will get upset. 01:17:22.128 --> 01:17:29.273 Which means that certain things are not allowed, but they are totally arbitrary and as a user you don't know why. 01:17:29.273 --> 01:17:35.392 because you don't know about wikitext, so you don't know about these completely random limitations. 01:17:35.392 --> 01:17:42.119 I'll show a few examples of like headaches we've had in our [..] 01:17:42.119 --> 01:17:48.326 In wikitext you can do nested lists. You can do this perfectly well in HTML as well. 01:17:48.326 --> 01:17:52.339 It's perfectly normal, it's the way HTML wants you to do this, is kind of weird, 01:17:52.339 --> 01:18:00.292 where it wants you to nest the 2nd level list at the end of the previous list item. 01:18:01.462 --> 01:18:05.606 Which is a little bit weird, but whatever fine, it's how everyone does it. 01:18:05.606 --> 01:18:15.584 If you insert a line break there, after 'Nested list' and you don't put a star there, then it ends the list completely. 01:18:15.584 --> 01:18:20.166 and your 'Bar' ends up completely outside of the list. That's also fine 01:18:20.166 --> 01:18:27.227 But, if you wanted to put text after the nested list but within the same list item, 01:18:27.227 --> 01:18:33.761 so you have a list item 'Foo' and then a nested list and then 'Bar'. You can't do that in wikitext. 01:18:33.761 --> 01:18:43.489 It is perfectly valid HTML, it's something that initially would almost ... if you did certain things in VisualEditor, [...] 01:18:43.489 --> 01:18:50.614 but you can't do it in wikitext. So we take all sorts of pains to not allow you to do this, because it creates nightmares. 01:18:50.614 --> 01:18:55.626 But this is of course completely non-transparent to anyone. 01:18:55.626 --> 01:19:00.871 And in general we tend to ignore that newline characters exist. 01:19:00.871 --> 01:19:07.226 You also can't really use formatted text in lists. Wikitext allows you to do it if you use an HTML tag here. 01:19:07.226 --> 01:19:11.457 But.. and that actually works just fine. 01:19:11.457 --> 01:19:14.908 But it doesn't really work, or it's not really useful 01:19:14.908 --> 01:19:17.839 because you try to do this... 01:19:17.839 --> 01:19:21.301 which, you wouldn't be using a tag if you didn't care about the way your newlines were produced, 01:19:21.301 --> 01:19:23.488 so you probably are going to add a newline in there. 01:19:23.488 --> 01:19:29.063 Then it happily breaks your list for you and throws 'Bar' outside the list and into it's own paragraph, 01:19:29.063 --> 01:19:34.355 because clearly that's what you meant, because clearly knows everything [...] a list. 01:19:34.355 --> 01:19:42.408 This is superevil. It also shows you how sort of this whole notion of using HTML some places in wikitext 01:19:42.408 --> 01:19:45.319 doesn't really work, or HTML and wikitext doesn't really get along that well. 01:19:45.319 --> 01:19:53.275 Obviously this means, that if you have pre formatted text in a list and you try to press enter in it, 01:19:53.275 --> 01:19:58.641 then VisualEditor needs to do, well not that, because that doesn't work. 01:19:58.641 --> 01:20:04.766 and if you try to create this HTML here... 01:20:15.775 --> 01:20:21.852 If you try to create something like this, like if the user tried to press Enter inside a formatted text in a list, 01:20:21.852 --> 01:20:27.749 this is what you probably would expect to happen, except that it is completely [..] 01:20:27.749 --> 01:20:31.317 [...] so maybe we shouldn't let you do that. 01:20:31.317 --> 01:20:36.260 So instead what happens is that if you press Enter inside the list item, then it splits the list item. 01:20:36.260 --> 01:20:41.027 We never try to insert any sort of line break like thing there, because we know it explodes. 01:20:41.027 --> 01:20:46.092 And also if you select text in a list and try to make it formatted, we break out of the list. 01:20:46.092 --> 01:20:49.772 Because we know that formatted text in a list is major trouble. 01:20:49.772 --> 01:20:56.473 Of course this only makes sense if you [...] and if you are the user, this makes no sense whatsoever. 01:20:58.053 --> 01:21:06.878 You can also if you [..] in a list, you can also do this in wikitext and it will do what you expect. 01:21:06.878 --> 01:21:10.688 It will create a paragraph break inside your list item. 01:21:10.688 --> 01:21:16.166 This isn't the most beautiful wikitext of all time, but it kind of works. 01:21:16.166 --> 01:21:18.484 You... 01:21:23.604 --> 01:21:26.018 This works, it's not very beautiful.. 01:21:26.018 --> 01:21:33.032 This is basically what you would get if we [..] work in their own way and insert a paragraph break. 01:21:33.032 --> 01:21:40.246 So obviously the solution is to not let the user create paragraphs breaks in list items and they have no idea why. 01:21:40.246 --> 01:21:47.622 One of my favorite examples is the [...] link syntax in wikitext is so amazing. 01:21:47.622 --> 01:21:51.974 You would think that you can totally embed an image inside the text of a link. 01:21:51.974 --> 01:21:58.833 So what this is trying to do is trying to create a link to 'Page' with the link text being 'Foo', an image and then 'Bar'. 01:21:58.833 --> 01:22:06.147 This seems reasonable, you can totally do this in HTML, you can totally have an image that's like part of a link action. 01:22:06.147 --> 01:22:09.684 If you try to do this in wikitext then everything freaks out and 01:22:09.684 --> 01:22:16.515 it decides that the image is more important than the link and it just barfs a bunch of wikitext all over your page. 01:22:16.515 --> 01:22:25.854 If we let you try to create a link across an image, then it would try to generate the wikitext like that. 01:22:25.854 --> 01:22:29.997 which would then when you render it back would create this garbage and so we cannot really do that 01:22:29.997 --> 01:22:37.931 and if you try to link across an image, it will silently cut the link at the image and [..] because we know links and images are trouble 01:22:38.081 --> 01:22:41.072 Users have no idea. 01:22:44.852 --> 01:22:50.636 If you wanted to do this, this completely sensible HTML, you should totally be able to do this in VisualEditor, 01:22:50.636 --> 01:22:59.053 except we don't let you, because if you then try to put the wikitext back, it will be [..] 01:22:59.053 --> 01:23:03.793 So those are things that were just broken in wikitext, which means you can't do them in wikitext, 01:23:03.793 --> 01:23:08.533 but there are also things that you can kinda do in wikitext except the result is so ugly, 01:23:08.533 --> 01:23:13.273 that people that do use wikitext yell at us whenever we do it, 01:23:13.273 --> 01:23:17.561 and so we also try and nudge users away from them. 01:23:17.561 --> 01:23:23.993 One of these things is, is with links. 01:23:25.403 --> 01:23:29.311 This is a feature in wikitext where you have link trails. 01:23:29.311 --> 01:23:36.770 So if you try to create a link to 'Foo', followed by the word 'bar', you would think that you would [..] like that 01:23:36.770 --> 01:23:41.293 but in fact that doesn't actually work that way, because wikitext is helpful and does link trailing. 01:23:41.293 --> 01:23:45.805 Where if you write text after a link, it automatically moves it into the link. 01:23:45.805 --> 01:23:50.626 So if you are trying to do the conversion like on the first line, it would actually break on you, 01:23:50.626 --> 01:23:53.882 because if you then try to convert it back to HTML you'd get something different. 01:23:53.882 --> 01:23:58.908 and it would actually go and help you and put bar inside the link 01:23:58.908 --> 01:24:06.863 and so instead we have to use a nowiki tag and people started crying and yelling at us for inserting all these [..] 01:24:06.863 --> 01:24:14.402 The solution to this problem, if you can call it that, is to, when users type text at the end of the link, 01:24:14.402 --> 01:24:20.319 try and make sure that by default that text is always part of the link and so you try and nudge them into creating 01:24:20.319 --> 01:24:25.386 content that looks like the thing on the 2nd line, which works and try to make it harder for them 01:24:25.386 --> 01:24:30.167 to create content looks like the thing on the 3rd line, because we know that's trouble 01:24:30.167 --> 01:24:34.591 This kind of behavior steering is, kind of like, it sort of promotes harmony, 01:24:34.591 --> 01:24:38.984 because VE users ended up creating wikitext that looked hideous and that people were upset about.. 01:24:38.984 --> 01:24:47.678 But.. you know, it's not a real solution and it's completely [...] to people who use it. 01:24:47.678 --> 01:24:54.923 You can also put spaces at the beginning of paragraphs, which [...] VE. 01:24:54.923 --> 01:24:59.876 You would think that we would just generate wikitext with a space at the beginning, 01:24:59.876 --> 01:25:05.484 unfortunately it doesn't work that way, because a space [..] meaningful [...] a tag. 01:25:05.484 --> 01:25:10.665 So what we actually have to do is wrap the space with a nowiki tag and again people get upset at us. 01:25:10.665 --> 01:25:20.934 We haven't even solved this problem yet. We think that we might want to detect these spaces 01:25:20.934 --> 01:25:24.405 and deliberately ignore them and throw them away. 01:25:24.405 --> 01:25:27.670 But you know, you can't really do that, that's not a real solution to a problem. 01:25:27.670 --> 01:25:32.886 It's just like trying to steer around various pitfalls again. 01:25:32.886 --> 01:25:40.813 Here is another example. You can type '#3' and also you can try to naively serialize that. 01:25:40.813 --> 01:25:45.705 But it doesn't do what you expect, because # means that you are trying to do a numbered list. 01:25:45.705 --> 01:25:48.751 So you have to wrap the # in a . 01:25:48.751 --> 01:25:54.828 Which again, we try to discourage people from doing this, by throwing: "What you typed looks like wikitext" 01:25:54.828 --> 01:25:57.376 "This won't really work, are you sure you want to do this?" 01:25:57.376 --> 01:26:01.312 Which a more egregious example of this would be 01:26:07.882 --> 01:26:12.998 Which a more egregious example of this would be this, where the user actually tries to type wikitext in VE. 01:26:12.998 --> 01:26:18.245 We come up with a big flashy warning: "This won't work the way you expect it would" 01:26:18.245 --> 01:26:23.804 and if you do save that actually have nowiki tags. We can't really prevent that, because this is what we 01:26:23.804 --> 01:26:27.148 have to do, to give a faithful representation [...] 01:26:27.148 --> 01:26:32.345 So instead we just surface a warning and go like: "Well people don't really like you to do this" 01:26:32.345 --> 01:26:34.921 But we can't really stop them. 01:26:34.921 --> 01:26:43.525 We have also considered converting this to a link, but we are trying to pretend wikitext doesn't exist. 01:26:43.525 --> 01:26:46.922 so that would be incredibly confusing for people who have never used wikitext 01:26:46.922 --> 01:26:50.895 and they mash some buttons and all of a sudden they have a link and they have no idea why. 01:26:50.895 --> 01:26:54.392 So I talked about solutions to these kinds of problems, 01:26:54.392 --> 01:26:58.079 and these are just a few examples, there are like a lot of other things that we steer around, 01:26:58.079 --> 01:27:05.009 but they are not really solutions, they are 'solutions' in air quotes, because they are like the lesser of all evils. 01:27:05.009 --> 01:27:10.928 we should try and nudge people to do, what we think is the right thing, but the reason it is the right thing, 01:27:10.928 --> 01:27:20.040 is [...] understand, so it's just a bunch of crappy workarounds. It's not really [...] 01:27:20.040 --> 01:27:24.462 So now Trevor is going to talk about Browsers, which I'm sure we can all agree are lovely things. 01:27:26.242 --> 01:27:28.554 I recommend them. 01:27:29.564 --> 01:27:31.472 So more specifically to the [...] 01:27:31.472 --> 01:27:36.410 I'm really only going to be talking about a browser feature known as ContentEditable. 01:27:36.410 --> 01:27:40.123 It is a very magical feature that browsers provide. 01:27:40.123 --> 01:27:44.786 Probably the richest feature that they have ever introduced. 01:27:44.786 --> 01:27:51.090 It makes HTML like this.. editable by simply putting a switch. 01:27:51.710 --> 01:27:57.274 Job done. Let's go home now. We are all sorted. 01:27:57.274 --> 01:28:04.339 But.. It turns out that of all the wonderful features browsers have given us over the past decade or so 01:28:04.339 --> 01:28:09.575 this is not one of them. ContentEditable is really inconsistent. 01:28:09.575 --> 01:28:14.038 It is very overzealous and it's very annoy able. 01:28:14.038 --> 01:28:18.673 You are basically always in a defensive position, trying to figure out what just happened. 01:28:18.673 --> 01:28:21.766 It doesn't even have events. It does weird things. 01:28:21.766 --> 01:28:25.473 Based on what day of the week it is, which way the wind is blowing. 01:28:25.473 --> 01:28:30.610 Depending on which browser you are in and what OS you are on. 01:28:30.610 --> 01:28:35.189 I think there is a math.random() somewhere in there. I'm not really sure. 01:28:35.189 --> 01:28:41.328 We had this idea early on... let's just avoid ContentEditable full stop. 01:28:41.328 --> 01:28:43.064 We worked on the WikiEditor. 01:28:43.064 --> 01:28:48.790 We tried to make a syntax highlighting version of wikitext editing in a ContentEditable and we ran into a lot of issues. 01:28:48.790 --> 01:28:54.458 So we just figured, let's just make a synthetic surface, this is what Google Docs does for instance. 01:28:54.458 --> 01:29:02.206 [..] ContentEditable, all the text selection and the blinking cursor and all of that is done with just rendering divs 01:29:02.206 --> 01:29:04.966 And we dit it. And it worked. 01:29:04.966 --> 01:29:13.121 But.. even though we had full control, we also had all the responsibility to implement everything from scratch. 01:29:13.121 --> 01:29:19.259 And that is where we got this limitation. Things like spellcheck and when you type on mobile 01:29:19.259 --> 01:29:25.251 pressing spacebar twice, what does it do. And different IME's, and what happens if you swipe. 01:29:25.251 --> 01:29:31.543 And mobile text selection is also a big problem, because it works very different and looks very different 01:29:31.543 --> 01:29:35.709 from the way it does in desktop browsers. 01:29:35.709 --> 01:29:40.429 All these things are stacking up against us and we sort of maybe we have to revisit ContentEditable, 01:29:40.429 --> 01:29:47.016 because we were quite limited in what we were able to accomplish. 01:29:47.016 --> 01:29:53.007 So we realized that the reason that our ContentEditable experience was so bad, 01:29:53.007 --> 01:29:57.364 was because we were making the DOM the center of our application. 01:29:57.364 --> 01:30:00.245 That everything in our application, the Data was in the DOM 01:30:00.245 --> 01:30:05.326 and the ContentEditable was having it's way with it, without our permission, most of the time. 01:30:05.326 --> 01:30:09.520 And the View, which was ContentEditable, was right there in the DOM. 01:30:09.520 --> 01:30:16.767 And of course the controller was relying on events from the DOM. That's what put us in that defensive position. 01:30:16.767 --> 01:30:20.813 The truth is that this was they way ContentEditable was designed to be used. 01:30:20.813 --> 01:30:24.242 So it seemed sensible. But it really set us up for failure. 01:30:24.242 --> 01:30:29.461 We realized that what we needed to do, was to come up with a different architecture completely. 01:30:29.461 --> 01:30:34.201 Where we simply just use ContentEditable for the little things that it is good for, like rendering 01:30:34.201 --> 01:30:43.182 text selection and some, but not all, of our input, because even the events that it gives sometimes are telling lies 01:30:43.182 --> 01:30:50.004 so we pretty much have to monitor it, repeatedly, over and over and over and check up and see what it is doing 01:30:51.974 --> 01:30:55.484 It is sort of resource intensive. 01:30:55.484 --> 01:31:02.791 This whole experience is really just taught us one thing: Browsers are dangerous. 01:31:02.791 --> 01:31:06.108 They lie to you, they will waste your time. 01:31:06.108 --> 01:31:11.873 They are bound to make you look foolish, and they are toys. 01:31:11.873 --> 01:31:16.209 Using a browser to make an application on Wikipedia, is like using my 7 year old daughter's 01:31:16.209 --> 01:31:22.530 play kitchen to run a restaurant. Everything seems to be there, but you got to use your imagination. 01:31:22.530 --> 01:31:28.718 And that is what I think a lot of VisualEditor engineering is, coming up with very imaginative ways to 01:31:28.718 --> 01:31:33.602 overcome the toy-like state of browsers. 01:31:33.602 --> 01:31:42.434 Which we hit all the time. So my recommendation to anybody doing [..] development, is to: Protect yourself. 01:31:42.434 --> 01:31:47.802 By scrapping. And that is exactly what we do. That is the architecture that we came up with. 01:31:47.802 --> 01:31:53.371 You scrap the DOM completely, to the point where we are really seeing it as a thin rendering client 01:31:53.371 --> 01:32:00.926 with some input and keep browsers on a very short leash and to give them a minimal amount of control. 01:32:00.926 --> 01:32:09.111 That is my recommendation to you all. And now to talk about the troubles of Operating Systems.. 01:32:09.111 --> 01:32:13.493 and how they effect our work, is: Ed Sanders 01:32:13.493 --> 01:32:15.784 Hello 01:32:21.224 --> 01:32:26.740 So I'm going to talk to you about something specifically bad about ContentEditable, 01:32:26.740 --> 01:32:30.045 which is: copy-paste. 01:32:33.455 --> 01:32:37.418 Here is the good news: ContentEditable gives you copy paste. 01:32:37.418 --> 01:32:41.986 You can press Ctrl-C, put stuff on the clipboard, you press Ctrl-V it takes out of the clipboard 01:32:41.986 --> 01:32:48.651 and that is pretty much half the job done for you. We don't have to [..] the data in some fake clipboard 01:32:48.651 --> 01:32:52.687 intercept key events and [..] 01:32:52.687 --> 01:33:00.884 There is even more good news. Brought to you by Clippy. It has a bunch of events that are actually quite useful. 01:33:00.884 --> 01:33:08.195 So not only are there oncopy and onpaste events. But they happen before the copy and before the paste. 01:33:08.195 --> 01:33:14.505 So if you have the oncopy event fired, that means the data hasn't been written to the clipboard yet. 01:33:14.505 --> 01:33:19.327 Which turns out to be really useful, because you can actually move someones selection, 01:33:19.327 --> 01:33:25.773 just before it writes the data to the clipboard and change what goes into the clipboard. 01:33:25.773 --> 01:33:34.649 Even more good news, there is an API, with getData and setData, so you can write stuff directly into the clipboard. 01:33:34.649 --> 01:33:41.414 This is only available on copy and paste events. And we can make directly set whatever the hell we want in there. 01:33:41.414 --> 01:33:48.354 With an asterisk, because if there is anyone from Mozilla here, we need to talk... 01:33:48.354 --> 01:33:51.354 On to the not so good news. 01:33:51.354 --> 01:33:58.163 It's really bad. It's really inconsistent. Copy paste is to ContentEditable, what ContentEditable is to browsers. 01:33:58.163 --> 01:34:02.171 It's like, it's the worst of the worst. 01:34:02.171 --> 01:34:04.872 If we are talking about Trevor's play kitchen 01:34:04.872 --> 01:34:10.373 This is like using Play-Doh to make a play kitchen to run the restaurant. 01:34:10.373 --> 01:34:15.856 It's just, every browser, there is no documentation, every browser does it somewhat differently, 01:34:15.856 --> 01:34:21.781 and this may or may not change next week. 01:34:21.781 --> 01:34:29.604 As I mentioned earlier, that beautiful API that would let us do whatever we want in getting the clipboard data, 01:34:29.604 --> 01:34:32.895 take whatever we want out... only works in Chrome. 01:34:32.895 --> 01:34:40.681 So unfortunately, we have to support more that one browser, so we need to come up with another method. 01:34:40.681 --> 01:34:45.507 That will work in Firefox and maybe even IE one day. 01:34:45.507 --> 01:34:51.250 Let's have a look at what we actually want to do in VisualEditor. 01:34:51.250 --> 01:34:55.611 We have a couple of use cases. There is the easiest one. 01:34:55.611 --> 01:35:03.238 Which is to copy some text from the top of your document and paste it a bit lower. 01:35:03.238 --> 01:35:08.699 In that case, you cannot choose a favorite clipboard, because we can just use the internal data 01:35:08.699 --> 01:35:12.953 that is already in our model, as Trevor mentioned we have taken the model out of ContentEditable. 01:35:12.953 --> 01:35:18.031 we store all our data in the [..] So every time we get copy, we can say: "Oh, you selected from 1 to 6" 01:35:18.031 --> 01:35:24.552 and then when you hit paste, it gives us the same thing, you can just move it out. 01:35:24.552 --> 01:35:27.688 Do one copy from one VE instance to another. 01:35:27.688 --> 01:35:32.574 That means, getting all this rich data, like templates or images, and making sure that goes into the 01:35:32.574 --> 01:35:35.615 clipboard properly. 01:35:35.615 --> 01:35:40.549 And we also might want to copy into a Word document. So we need to make sure that what goes into the Word 01:35:40.549 --> 01:35:44.270 document is actually, clean HTML. 01:35:44.270 --> 01:35:50.882 So you might have thought, just copy between the instances, well we can just take our internal data and JSON serialize it. 01:35:50.882 --> 01:35:54.798 But then if you paste that into Word, then you are going to be like, wow what just happened there. 01:35:54.798 --> 01:35:58.872 I copied like a paragraph in an editor and now I've got [..] 01:35:58.872 --> 01:36:07.264 And people may also want to copy stuff from the website and paste it into the.. maybe not so much Wikipedia, 01:36:07.264 --> 01:36:13.685 because you know [..] 01:36:13.685 --> 01:36:16.731 So some solutions 01:36:16.731 --> 01:36:22.992 1. We have this thing called DM HTML, which isn't the ContentEditable HTML, because ContentEditable HTML 01:36:22.992 --> 01:36:30.018 will randomly [..] your HTML, we keep a [..] copy of the DM HTML, which is what gets send back to the server 01:36:30.018 --> 01:36:37.035 when you hit save. So we can put that on the clipboard. 01:36:37.035 --> 01:36:44.052 If you put a template that is a table [..] to the table, replace it with a little marker saying: This is info box [..] 01:36:44.052 --> 01:36:51.071 So if you put that in the clipboard, when you paste to another VisualEditor instance, you get a template and not just the rendering of a template. 01:36:51.071 --> 01:36:59.909 which is a table and a bunch of random stuff, [..] 01:36:59.909 --> 01:37:06.590 If we can also put in the clipboard some sort of marker, for internal copy paste, 01:37:06.590 --> 01:37:11.551 so we can say, oh this copy actually came from VisualEditor, then when we hit paste we can say: 01:37:11.551 --> 01:37:17.302 Well this was a VisualEditor copy, was it from the same window that we are currently in? 01:37:17.302 --> 01:37:23.833 If it is, then we can just draw the data from our internal data structure. 01:37:23.833 --> 01:37:28.886 So [..] Things get easy 01:37:28.886 --> 01:37:34.883 We can use the plain clipboard data. We put our DM HTML in the HTML part of the clipboard. 01:37:34.883 --> 01:37:41.562 BTW. the clipboard has a plain text area, an HTML area and sort of random custom metadata. 01:37:41.562 --> 01:37:53.186 And then we can set a custom key pointing to some internal store for the actual internal data, if they need to be a paste. 01:37:53.186 --> 01:38:03.632 And that's not too bad. There's a few problems with actually setting the data directly [..] 01:38:03.632 --> 01:38:07.870 Here is the hard way, which is what happens if you have Firefox or Internet Explorer. 01:38:07.870 --> 01:38:16.277 You hit copy and as you saw earlier, we have really early events. So we take your selection, which is in the CE. 01:38:16.277 --> 01:38:30.213 And we then make generous and DM HTML, put it in a hidden text area, move our selection to the text area, then we wait a bit, wait for the copy to happen. [..] 01:38:30.213 --> 01:38:35.666 And then we put everything back where we found it. So slightly convoluted process. 01:38:35.666 --> 01:38:38.663 Job done. 01:38:38.663 --> 01:38:40.990 Not so fast. 01:38:40.990 --> 01:38:45.827 Mo' problems 01:38:45.827 --> 01:38:52.029 The ContentEditable clipboard has a habit of tweaking your HTML, so that it looks better. 01:38:52.029 --> 01:38:57.885 Internet Explorer in particular throws away lot's of whitespace, that's not so bad. 01:38:57.885 --> 01:39:06.188 Firefox, [..] we need to talk again. They throw away, a whole bunch of attributes, such as RDFa. 01:39:06.188 --> 01:39:11.265 That's quite unfortunate for us, because we use RDFa to define all template metadata. 01:39:11.265 --> 01:39:18.249 So if you are in FireFox and you try to do this, you just throw away all your template metadata and you just be left with [..] 01:39:18.249 --> 01:39:21.280 We can work around this by serializing all the templates 01:39:21.280 --> 01:39:29.821 which we think CE might destroy, which we put in another template [..] another attribute [..] won't destroy. 01:39:29.821 --> 01:39:32.773 Element destruction 01:39:32.773 --> 01:39:39.135 Empty spans, we use empty spans in Mozilla to store this internal templating and then Mozilla decides to destroy it. 01:39:39.135 --> 01:39:42.305 Because you didn't mean to have an empty span there right ? 01:39:42.305 --> 01:39:47.550 So a little hack we can do there is to have a [..] and that sort of protects it... atm. 01:39:49.960 --> 01:40:03.309 And reordering. If you sort of copy just a table cell and try to paste that in a paragraph it might sort of wrap it in tables, it might move the paragraph outside [..] 01:40:03.309 --> 01:40:12.206 so we need to make sure that when we do do this fake paste [..] trip, that we paste into the right sort of content. 01:40:12.206 --> 01:40:16.883 End.. Almost 01:40:16.883 --> 01:40:21.762 As I've mentioned. We don't think we've got this completely sorted out. 01:40:21.762 --> 01:40:27.777 We get reports of bugs. We'd love you to try and just fire up VisualEditor in your browser, 01:40:27.777 --> 01:40:37.742 copy and paste and stuff and then people get it to break again. 01:40:37.742 --> 01:40:55.318 And also as I've mentioned a few times, [..] 01:40:55.318 --> 01:40:58.736 And that was that.