1 01:13:14,033 --> 01:13:43,547 Engineering (VisualEditor) Against the Odds 2 01:13:49,087 --> 01:13:52,723 Alright 3 01:13:52,723 --> 01:13:56,493 Hello, everybody. I'm Trevor Pascal. 4 01:13:56,493 --> 01:14:04,094 This is Roan Kattouw and Ed Sanders, we work at the Wikimedia Foundation, specifically the VisualEditor 5 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 6 01:14:09,789 --> 01:14:12,719 for the past couple of years 7 01:14:12,719 --> 01:14:18,791 and how working on VisualEditor is essentially engineering 'Against the odds'. 8 01:14:18,791 --> 01:14:22,300 And so in fact we have found that the odds are against us. 9 01:14:22,300 --> 01:14:28,729 But can anyone guess what makes creating VisualEditor so difficult ? 10 01:14:28,729 --> 01:14:32,518 Like what sort of things are standing in our way ? 11 01:14:32,518 --> 01:14:37,119 - The community The community.. definitely NOT ! 12 01:14:37,119 --> 01:14:41,093 The green shirt ? - Ehm browser support ? 13 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... 14 01:14:48,533 --> 01:14:51,834 Anyone else ? - Working with wiki text 15 01:14:51,834 --> 01:14:58,370 Ah, yeah OK now we are getting good So yeah definitely differences in Operating Systems 16 01:14:58,370 --> 01:15:04,213 different kinds of computers people are using.. That includes like laptops, tablets, phones. 17 01:15:04,213 --> 01:15:09,516 We are moving towards getting mobile support going. 18 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. 19 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. 20 01:15:23,576 --> 01:15:27,931 And they don't really seem to agree on how standards should be done 21 01:15:27,931 --> 01:15:31,206 at least not when you get down to the nitty gritty details. 22 01:15:31,206 --> 01:15:35,022 And eh we sort of demand a little rigor 23 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, 24 01:15:42,418 --> 01:15:45,228 there is a lot of design flaws and they bubble up into the User Interface 25 01:15:45,228 --> 01:15:48,689 and users get really confused about what is going on. 26 01:15:48,689 --> 01:15:51,780 because it doesn't quite work the way Microsoft Word works, 27 01:15:51,780 --> 01:15:56,150 because wikitext is not the same as Microsoft Word. It's a data? format. 28 01:15:56,150 --> 01:16:00,312 And so we have to work very hard just to maintain compatibility. 29 01:16:00,312 --> 01:16:03,288 And eh... isn't that so sad. 30 01:16:03,288 --> 01:16:08,924 But we are really hoping to share some of these experiences with you, 31 01:16:08,924 --> 01:16:15,202 not necessarily to make you cry, but because we think there are some interesting challenges, 32 01:16:15,202 --> 01:16:20,507 most of which we have overcome and there are some kinda exciting stories to tell. 33 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. 34 01:16:29,128 --> 01:16:33,490 Alright, so Let's talk wikitext. 35 01:16:33,913 --> 01:16:37,810 Wikitext, like Trevor said, is a limiting factor to us. 36 01:16:37,810 --> 01:16:40,887 And one of the main problems is that if you are a VisualEditor user, 37 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. 38 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 39 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. 40 01:16:55,867 --> 01:17:03,385 Which works [...] for most of our [...] but the reality is that wikitext sort of [..] there. 41 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. 42 01:17:10,215 --> 01:17:15,049 And so it ends up being that wikitext limits the users in what they can do. 43 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 44 01:17:20,507 --> 01:17:22,128 because people will get upset. 45 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. 46 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. 47 01:17:35,392 --> 01:17:42,119 I'll show a few examples of like headaches we've had in our [..] 48 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. 49 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, 50 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. 51 01:18:01,462 --> 01:18:05,606 Which is a little bit weird, but whatever fine, it's how everyone does it. 52 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. 53 01:18:15,584 --> 01:18:20,166 and your 'Bar' ends up completely outside of the list. That's also fine 54 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, 55 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. 56 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, [...] 57 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. 58 01:18:50,614 --> 01:18:55,626 But this is of course completely non-transparent to anyone. 59 01:18:55,626 --> 01:19:00,871 And in general we tend to ignore that newline characters exist. 60 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. 61 01:19:07,226 --> 01:19:11,457 But.. and that actually works just fine. 62 01:19:11,457 --> 01:19:14,908 But it doesn't really work, or it's not really useful 63 01:19:14,908 --> 01:19:17,839 because you try to do this... 64 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, 65 01:19:21,301 --> 01:19:23,488 so you probably are going to add a newline in there. 66 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, 67 01:19:29,063 --> 01:19:34,355 because clearly that's what you meant, because clearly knows everything [...] a list. 68 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 69 01:19:42,408 --> 01:19:45,319 doesn't really work, or HTML and wikitext doesn't really get along that well. 70 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, 71 01:19:53,275 --> 01:19:58,641 then VisualEditor needs to do, well not that, because that doesn't work. 72 01:19:58,641 --> 01:20:04,766 and if you try to create this HTML here... 73 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, 74 01:20:21,852 --> 01:20:27,749 this is what you probably would expect to happen, except that it is completely [..] 75 01:20:27,749 --> 01:20:31,317 [...] so maybe we shouldn't let you do that. 76 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. 77 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. 78 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. 79 01:20:46,092 --> 01:20:49,772 Because we know that formatted text in a list is major trouble. 80 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. 81 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. 82 01:21:06,878 --> 01:21:10,688 It will create a paragraph break inside your list item. 83 01:21:10,688 --> 01:21:16,166 This isn't the most beautiful wikitext of all time, but it kind of works. 84 01:21:16,166 --> 01:21:18,484 You... 85 01:21:23,604 --> 01:21:26,018 This works, it's not very beautiful.. 86 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. 87 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. 88 01:21:40,246 --> 01:21:47,622 One of my favorite examples is the [...] link syntax in wikitext is so amazing. 89 01:21:47,622 --> 01:21:51,974 You would think that you can totally embed an image inside the text of a link. 90 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'. 91 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. 92 01:22:06,147 --> 01:22:09,684 If you try to do this in wikitext then everything freaks out and 93 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. 94 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. 95 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 96 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 97 01:22:38,081 --> 01:22:41,072 Users have no idea. 98 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, 99 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 [..] 100 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, 101 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, 102 01:23:08,533 --> 01:23:13,273 that people that do use wikitext yell at us whenever we do it, 103 01:23:13,273 --> 01:23:17,561 and so we also try and nudge users away from them. 104 01:23:17,561 --> 01:23:23,993 One of these things is, is with links. 105 01:23:25,403 --> 01:23:29,311 This is a feature in wikitext where you have link trails. 106 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 107 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. 108 01:23:41,293 --> 01:23:45,805 Where if you write text after a link, it automatically moves it into the link. 109 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, 110 01:23:50,626 --> 01:23:53,882 because if you then try to convert it back to HTML you'd get something different. 111 01:23:53,882 --> 01:23:58,908 and it would actually go and help you and put bar inside the link 112 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 [..] 113 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, 114 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 115 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 116 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 117 01:24:30,167 --> 01:24:34,591 This kind of behavior steering is, kind of like, it sort of promotes harmony, 118 01:24:34,591 --> 01:24:38,984 because VE users ended up creating wikitext that looked hideous and that people were upset about.. 119 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. 120 01:24:47,678 --> 01:24:54,923 You can also put spaces at the beginning of paragraphs, which [...] VE. 121 01:24:54,923 --> 01:24:59,876 You would think that we would just generate wikitext with a space at the beginning, 122 01:24:59,876 --> 01:25:05,484 unfortunately it doesn't work that way, because a space [..] meaningful [...] a tag. 123 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. 124 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 125 01:25:20,934 --> 01:25:24,405 and deliberately ignore them and throw them away. 126 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. 127 01:25:27,670 --> 01:25:32,886 It's just like trying to steer around various pitfalls again. 128 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. 129 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. 130 01:25:45,705 --> 01:25:48,751 So you have to wrap the # in a . 131 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" 132 01:25:54,828 --> 01:25:57,376 "This won't really work, are you sure you want to do this?" 133 01:25:57,376 --> 01:26:01,312 Which a more egregious example of this would be 134 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. 135 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" 136 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 137 01:26:23,804 --> 01:26:27,148 have to do, to give a faithful representation [...] 138 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" 139 01:26:32,345 --> 01:26:34,921 But we can't really stop them. 140 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. 141 01:26:43,525 --> 01:26:46,922 so that would be incredibly confusing for people who have never used wikitext 142 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. 143 01:26:50,895 --> 01:26:54,392 So I talked about solutions to these kinds of problems, 144 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, 145 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. 146 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, 147 01:27:10,928 --> 01:27:20,040 is [...] understand, so it's just a bunch of crappy workarounds. It's not really [...] 148 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. 149 01:27:26,242 --> 01:27:28,554 I recommend them. 150 01:27:29,564 --> 01:27:31,472 So more specifically to the [...] 151 01:27:31,472 --> 01:27:36,410 I'm really only going to be talking about a browser feature known as ContentEditable. 152 01:27:36,410 --> 01:27:40,123 It is a very magical feature that browsers provide. 153 01:27:40,123 --> 01:27:44,786 Probably the richest feature that they have ever introduced. 154 01:27:44,786 --> 01:27:51,090 It makes HTML like this.. editable by simply putting a switch. 155 01:27:51,710 --> 01:27:57,274 Job done. Let's go home now. We are all sorted. 156 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 157 01:28:04,339 --> 01:28:09,575 this is not one of them. ContentEditable is really inconsistent. 158 01:28:09,575 --> 01:28:14,038 It is very overzealous and it's very annoy able. 159 01:28:14,038 --> 01:28:18,673 You are basically always in a defensive position, trying to figure out what just happened. 160 01:28:18,673 --> 01:28:21,766 It doesn't even have events. It does weird things. 161 01:28:21,766 --> 01:28:25,473 Based on what day of the week it is, which way the wind is blowing. 162 01:28:25,473 --> 01:28:30,610 Depending on which browser you are in and what OS you are on. 163 01:28:30,610 --> 01:28:35,189 I think there is a math.random() somewhere in there. I'm not really sure. 164 01:28:35,189 --> 01:28:41,328 We had this idea early on... let's just avoid ContentEditable full stop. 165 01:28:41,328 --> 01:28:43,064 We worked on the WikiEditor. 166 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. 167 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. 168 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 169 01:29:02,206 --> 01:29:04,966 And we dit it. And it worked. 170 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. 171 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 172 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. 173 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 174 01:29:31,543 --> 01:29:35,709 from the way it does in desktop browsers. 175 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, 176 01:29:40,429 --> 01:29:47,016 because we were quite limited in what we were able to accomplish. 177 01:29:47,016 --> 01:29:53,007 So we realized that the reason that our ContentEditable experience was so bad, 178 01:29:53,007 --> 01:29:57,364 was because we were making the DOM the center of our application. 179 01:29:57,364 --> 01:30:00,245 That everything in our application, the Data was in the DOM 180 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. 181 01:30:05,326 --> 01:30:09,520 And the View, which was ContentEditable, was right there in the DOM. 182 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. 183 01:30:16,767 --> 01:30:20,813 The truth is that this was they way ContentEditable was designed to be used. 184 01:30:20,813 --> 01:30:24,242 So it seemed sensible. But it really set us up for failure. 185 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. 186 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 187 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 188 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 189 01:30:51,974 --> 01:30:55,484 It is sort of resource intensive. 190 01:30:55,484 --> 01:31:02,791 This whole experience is really just taught us one thing: Browsers are dangerous. 191 01:31:02,791 --> 01:31:06,108 They lie to you, they will waste your time. 192 01:31:06,108 --> 01:31:11,873 They are bound to make you look foolish, and they are toys. 193 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 194 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. 195 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 196 01:31:28,718 --> 01:31:33,602 overcome the toy-like state of browsers. 197 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. 198 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. 199 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 200 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. 201 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.. 202 01:32:09,111 --> 01:32:13,493 and how they effect our work, is: Ed Sanders 203 01:32:13,493 --> 01:32:15,784 Hello 204 01:32:21,224 --> 01:32:26,740 So I'm going to talk to you about something specifically bad about ContentEditable, 205 01:32:26,740 --> 01:32:30,045 which is: copy-paste. 206 01:32:33,455 --> 01:32:37,418 Here is the good news: ContentEditable gives you copy paste. 207 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 208 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 209 01:32:48,651 --> 01:32:52,687 intercept key events and [..] 210 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. 211 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. 212 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. 213 01:33:14,505 --> 01:33:19,327 Which turns out to be really useful, because you can actually move someones selection, 214 01:33:19,327 --> 01:33:25,773 just before it writes the data to the clipboard and change what goes into the clipboard. 215 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. 216 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. 217 01:33:41,414 --> 01:33:48,354 With an asterisk, because if there is anyone from Mozilla here, we need to talk... 218 01:33:48,354 --> 01:33:51,354 On to the not so good news. 219 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. 220 01:33:58,163 --> 01:34:02,171 It's like, it's the worst of the worst. 221 01:34:02,171 --> 01:34:04,872 If we are talking about Trevor's play kitchen 222 01:34:04,872 --> 01:34:10,373 This is like using Play-Doh to make a play kitchen to run the restaurant. 223 01:34:10,373 --> 01:34:15,856 It's just, every browser, there is no documentation, every browser does it somewhat differently, 224 01:34:15,856 --> 01:34:21,781 and this may or may not change next week. 225 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, 226 01:34:29,604 --> 01:34:32,895 take whatever we want out... only works in Chrome. 227 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. 228 01:34:40,681 --> 01:34:45,507 That will work in Firefox and maybe even IE one day. 229 01:34:45,507 --> 01:34:51,250 Let's have a look at what we actually want to do in VisualEditor. 230 01:34:51,250 --> 01:34:55,611 We have a couple of use cases. There is the easiest one. 231 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. 232 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 233 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. 234 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" 235 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. 236 01:35:24,552 --> 01:35:27,688 Do one copy from one VE instance to another. 237 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 238 01:35:32,574 --> 01:35:35,615 clipboard properly. 239 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 240 01:35:40,549 --> 01:35:44,270 document is actually, clean HTML. 241 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. 242 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. 243 01:35:54,798 --> 01:35:58,872 I copied like a paragraph in an editor and now I've got [..] 244 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, 245 01:36:07,264 --> 01:36:13,685 because you know [..] 246 01:36:13,685 --> 01:36:16,731 So some solutions 247 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 248 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 249 01:36:30,018 --> 01:36:37,035 when you hit save. So we can put that on the clipboard. 250 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 [..] 251 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. 252 01:36:51,071 --> 01:36:59,909 which is a table and a bunch of random stuff, [..] 253 01:36:59,909 --> 01:37:06,590 If we can also put in the clipboard some sort of marker, for internal copy paste, 254 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: 255 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? 256 01:37:17,302 --> 01:37:23,833 If it is, then we can just draw the data from our internal data structure. 257 01:37:23,833 --> 01:37:28,886 So [..] Things get easy 258 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. 259 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. 260 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. 261 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 [..] 262 01:38:03,632 --> 01:38:07,870 Here is the hard way, which is what happens if you have Firefox or Internet Explorer. 263 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. 264 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. [..] 265 01:38:30,213 --> 01:38:35,666 And then we put everything back where we found it. So slightly convoluted process. 266 01:38:35,666 --> 01:38:38,663 Job done. 267 01:38:38,663 --> 01:38:40,990 Not so fast. 268 01:38:40,990 --> 01:38:45,827 Mo' problems 269 01:38:45,827 --> 01:38:52,029 The ContentEditable clipboard has a habit of tweaking your HTML, so that it looks better. 270 01:38:52,029 --> 01:38:57,885 Internet Explorer in particular throws away lot's of whitespace, that's not so bad. 271 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. 272 01:39:06,188 --> 01:39:11,265 That's quite unfortunate for us, because we use RDFa to define all template metadata. 273 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 [..] 274 01:39:18,249 --> 01:39:21,280 We can work around this by serializing all the templates 275 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. 276 01:39:29,821 --> 01:39:32,773 Element destruction 277 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. 278 01:39:39,135 --> 01:39:42,305 Because you didn't mean to have an empty span there right ? 279 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. 280 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 [..] 281 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. 282 01:40:12,206 --> 01:40:16,883 End.. Almost 283 01:40:16,883 --> 01:40:21,762 As I've mentioned. We don't think we've got this completely sorted out. 284 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, 285 01:40:27,777 --> 01:40:37,742 copy and paste and stuff and then people get it to break again. 286 01:40:37,742 --> 01:40:55,318 And also as I've mentioned a few times, [..] 287 01:40:55,318 --> 01:40:58,736 And that was that.