W3C

- DRAFT -

Web Platform - editing APIs

22 Sep 2016

Agenda

See also: IRC log

Attendees

Present
Yves, Chong, GaryK, OlliP, Enrica, Chaals, Léonie, Johannes, Kochi, DomC, Yoshi, Yoisho, Hayato., MarkV, Travis, MarkVickers, Glazou, AnnevK, Navid, Joshua
Regrets
Chair
chaals
Scribe
chaals, Travis

Contents


<chaals> Chair: Léonie

<chaals> Scribe: chaals

intro

Input events

JW: input type with spellchecker. Last time we said we may need something more general, replace a text node.

<dcooney> present?

JW: suggested we use spellchecker. benefit is we get more information about why the change happened.

<dcooney> Zakim: help

<johanneswilm> https://w3c.github.io/input-events/

Gary: UIEvents gives base definition, the rest of the editing stuff is collected into the input-events spec.

JW: 5.1.2 in the input events spec. The one called insert non text - previously replace content, so the proposal is to be explicit that this is a spellchecker. So can it only come from spellchecker, or e.g. making something all caps?

Enrica: Think it should.

JW: Couldn't be insertText - *can* go across element boundaries

Enrica: is nonText an HTML fragment?

JW: Can be

CMN: It's mostly text. The key is that it's something "semi-automatic" working quite probably in the background, as opposed to the user at their point of attention…

enrica: If you're replacing a word across elements - e.g. for bold and non, how do you decide what the result is, bold or not..

JW: Right now nobody has a smart way to do this much, and it's for the user agent.

[bikeshedding...]

RESOLUTION: insertReplacementText

IME

JW: We can't stop IME mid-stream. This makes collaborative editors hard.
... latest approach comes from Chong - divide the IME stuff so some events can be cancelled, some not.
... some IMEs just insert new characters. We get some input events that cannot be canceled, and at the end of construction we get a removal and a reinsertion, which we can cancel / handle in JS.
... there are cases where we have some text that needs to be fed into the IME. For this we get a new beforeInput event before the construction starts, and if that is not cancelled deletes the curent word
... and starts construction in its place. This can be canceled - if you cancel it, the initial word will be there as well as the replacement.

CZ: If you cancel onInput you want to be in the state before then.
... but in some IMEs you can start the composition from existing text.
... so we can't just remove the composition, or you lose the text that was there before.
... so we make a text replacement happen, which allows us to separate it into deletion and insertion which are cancelable, with the composition happening in the middle.

JW: This is only if you preventDefault - then you have to remove the text yourself.

<chongz> https://github.com/w3c/input-events/issues/33

Travis: In a spellchecking scenario, the UA is going to try to change something, fires an event, you can cancel there and you're in original state. If you don't cancel, you remove word and replace…

Chong: This is only about IME.
... everything during it is non-cancelable. so we have the two cancelable pieces at start and end, deleting something and replacing it.

JW: If I preventDefault and delete the word myself, I can still get the insertion at the end to allow the actual composition to take place.

CMN: this actually works fine for spellcheck if you do it that way. Which is a good thing, IMHO.

GaryK: If you preventDefault on first deletion, does that stop the IME?

Chong: No. The composition and insertion is still going to happen.

Gary: you cannot cancel within the composition, but you can cancel the insertion at the end, what if you do.

<johanneswilm> https://github.com/w3c/input-events/issues/34

<johanneswilm> https://github.com/w3c/input-events/issues/33

<Travis> Etherpad available for describing steps: https://pad.w3ctag.org/p/22-09-2016-editing

Chong: Issue 33 is about the first cancelable event, 34 is about the one at the end. JS doesn't need to worry what is happening in the middle

JW: Except that you need to know not to make a mess in here while compositoin is going on.

[so if composition is going on and on, you probably want an unblocking thing…]

JW: If people are typing japanese and working on long chunks, they can commit a piece of composition and restart with the rest of what they are working on, as necessary.
... should we go with this?

[general nodding]

Gary: We have lots of deleteby and insertby. I don't know if people are going to want to catch all of these, because it's a long list.

JW: Here we are reducing a bit the number of different types we have.

Travis: So is there a way to catch "deletion" without caring what type it is?

[Smaug nods]

RESOLUTION: Yes we can do the issues 33/34 proposal for cancelable at each end of IME.

catching inserts / deletes

Gary: If we strictly use insert and delete as prefixes for events, maybe format* as well, makes it much easier to catch all events.

JW: Yep, seems reasonable.

CMN: +1

Smaug: Why categorise everything using one attribute? Why not type and subtype…
... inputType with 200 different things doesn't seem what you care about.

JW: Question is who will use this. So far I see maybe a dozen editors, and they are the customers for this. Making your own editor for your homepage seems unlikely, given the size of it.
... don't mind whether we use subtypes or prefixes. But I don't think we are talking about a mass-market of developers here.

Smaug: Think splitting this would be nicer ergonomics.

Gary: what other input types do we have - can we categorise them easily?

smaug: we have insert, delete, modify?

gary: format.

JW: And history

Travis: They are insert and delete when you do them.

JW: Browser doesn't know the transaction history

Gary: For browser stack only

JW: editor has to maintain its own undo stack - this came from the discussion at last meeting, you *cannot* use global stack

Travis: So you implement the user's intent to undo on your own. If you don't cancel those, you don't know what will happen.

JW: e.g. MS Office or Google Docs maintain different history stacks for different input areas. And that seems reasonable.

Travis: undo/redo notifications aren't associated with input

Gary: it's likely that this is some kind of modification. It isn't guaranteed, but it's probably the case.

Chong: for copy/paste, beforeInput shouldn't care about history or keyboard, just about DOM updates.
... if you prevent undo for input, the history stack still pops. if you preventDefault for cut, it only prevents deletion of the word ubt it still goes to the clipboard.

JW: You don't know the browser would do an update. Maybe the browser won't delete something because it thinks you are in the wrong place, but the editor still needs to handle it.
... we used to have movement, but that went away.

Travs: Doesn't feel right, but can't put a finger on why.

Gary: Making beforeInput catch everything is a decision taken a while ago.

Enrica: This is about DOM mutations, but there are some exceptions.

Travis: Think this is about user intentions…
... so there are things that don't feel like input in terms of "here is some text"

Gary: This isn't fired for everything, only things that are likely to mess with the DOM.

Travis: Maybe this is just a bikeshed on the name…

[And tra-la-la, we bikeshed the name]

Glazou: Gecko used "editAction"

Travis: Let's table that and think about it some more.

Gary: This goes with the inputSubType discussion too, right?
... but we do need to make sure tehre is an easy way for developers to collect all of a class of events.
... my concern is that if we get too granular we might cut off things we want, later.

JW: So we are lookng at delete, insert, format, history …

Travis: There are complex properties here… directions and so on.

Gary: We can get lost in this, but stripping the top level seems worthwhile.

[break - and then undo history]

Undo Redo history…

JW: Ojan asked if we should have a different category, how should it relate to general system stack…
... CKEditor tried to build on top of a browser's history. Doesn't work, since they handle the events themselves there isn't any history.
... we want a way to say that some element is not handled by global history, then how do you enable/disable the various undo menus?

<chongz> Undo/redo https://github.com/w3c/input-events/issues/36

JW: Ryosuke had a proposal for enabling/disablign features. You can add undo/redo given that it's available.

Travis: for contentEditable we don't have a dedicated element - would need to be applicable to all elements. Is it applicable globally.

Gary: With multiple undo stacks - e.g. Office, GoogleDocs, I don't see how a global attribute would work.

Travis: No, just that you can apply it to any element

Gary: seems like it would work…
... going to be ugly to find

Travis: And you have a tree - can you disable it further down the tree, and reneable it even deeper?

<johanneswilm> https://github.com/w3c/input-events/issues/32#issuecomment-248762122

JW: The proposal (see link above) is an attribute for the container of contentEditable.

enrica: there are other features we want to enable or disable - bold, spellcheck, whatever.

Gary: Would be nice if you culd find the container that is editable

JW: editingHost.

Gary so it is there, or not there. You wouldn't find it on some other element somewhere else.

Editing element?

Travis: Is it time to add the "editSection" element?

Enrica: Why?

Travis: Once you put something into contentEditable state, there's a whole lot of special magic.
... like <input> where attributes only apply sometimes, depending on type.
... so if, when you become contentEditable you start getting a whole lot of possible extra things to do, then we're following the anti-pattern of input.
... Or we can subclass elements and make a specific element that would be the editing host. Then the attributes are specific to that element and not going to hang on any element…

JW: This doesn't sound unreasonable, and might clarify contentEditable.

Gary: That's the way this should have been done, but what is the cost of the transition to there?
... this is a big task to do that.

Enrica: think we can spec the attribute now, and if we do the new element, we can add that.

Travis: You could describe the attribute but not commit to it.

Smaug: implenenting a new element is trivial. And it would simplify the platform a lot.

Gary: have a new element now, stripped down so it just gets basic functionality.

Chong: Would we allow disable copy?

Travis: I think we can answer that question orthogonally.
... if there is a feature we need to add, it would be easier to do it if we had a specific element to which that would apply.

Chong: some actions like disable copy don't necessarily apply only to contentEditable.

Travis: Copy could be blocked generically.

CMN: There is a transition path, if we only put nice new stuff onto the editor element.

Gary: If we make an element, is it going to be a bucket to fix everything before we ship?

JW: The discussion of fixing the other parts is something we want to take - selection normalisation, how do we get around it, etc.. this is a mega task.

Gary: If we make a starting point, and don't aim to fix everything before we actually ship the element

CMN: Yeah, that's the only logical approach.

Enrica: So a new element thta will behave as contentEditable, plus new features.

Gary: Right.

JW: So an issue for switching. On the JS we were told we cannot fix things in contentEditable because there is legacy. But in the new element if we inherit the legacty we have a problem.

Gary: Right - this is the issue. If we were going to fix something broken, we're saying "but we are not going to make something different from contentEditable".

Smaug: Don't see how adding the element makes anything worse.

Gary: If we have a gating function, of fixing everything, then it slows us down.

JW: Getting to a more fixed version is to change the values of the contentEditable attribute. If we do it with a new element, we need a flag that covers e.g. version.

Travis: That is still fine.

Gary: If we can version it, then we are fine for dealing with legacy, and that means we should do it now rather than later.

Travis: We can scope the problem space better if we have the element.

JW: Can we do versioning already?

smaug: we start with mode="legacy"

CMN: or mode="broken" ?

Travis: It isn't a major effort to implement the element...

Gary: Right, it's a management issue

RESOLUTION: We think that this makes sense to propose something concrete

[in which bikeshed do we do the work?]

Undo / Redo stack popped

Gary: We have a bunch of attributes that can go on this new element.

JW: history management, interaction with browser undo/redo functions

Gary: cut/copy/paste?

JW: Yep.

Enrica: thought this is all the different features we can enable / disable

smaug: do we need these things on input, textarea

Gary, Yoshi: you don't need it

scribe: no rich text editors in input

[well, sort of]

CMN: Nope, if you want rich features use the new element.

Travis: Will you want system undo/redo inside the editable element?

JW: You need to use that if you handle anything…

Gary: Is there any use case for it?

JW: Never seen one.

Travis: So we could make system default "no system undo stack"…

Gary: We should try that at least.

CMN: +1

JW: Or allow turning it on...

Gary: Supporting it at all seems odd if there isn't a use case.

JW: It is possible there is a use case, just can't find one.

Travis: Sounds like work to turn it off.

Gary: if you turn it off you get the saving of not managing the events

Travis: Yeah, although I need new logic to turn it off.

Gary: So if you can ssume undo won't happen, you get big runtime benefits, but there is some more code complexity if you have to be able to enable them.

Yo1: What do you mean about enable/disable? Control the menu item from javascript?

Gary: Yes - JS can tell the browser about UI things

Yo1: so the undo stack is created - if the JS calls appendChild, this doesn't go to the undo history.

Travis: Right. But the JS that did the appendChild knows it did, and it is creating its own stack. It needs to make it look like there is history, so the browser needs to allow an undo event that the JS that will then capture and process.

Yo1: JS adds to the history?

Travis: Manages its own history.
... it could be done automatically, in theory

JW: That would be complex.

[example of why undo histories are awful]

scribe: I write ten things in a paragraph in a collaborative editor, my colleague deletes that paragraph, I need the ten things popped off the stack. Do we try to tell the browser how to manage the history, or just say "let the user do "undo" and tell me, and I will manage that in my JS
... the idea in beforeInput is that you get things from the browser related to what teh user wanted, which is better than by trying to trap keypress events and guess what the user wanted.

Chong: We need two attributes - control which context menu will be shown, second is to show undo or redo...

CMN: It's just "please enable undo in your interface"

JW: there is also "does global history apply"

Travis: and "should context menu appear at all"?

Chong: what if everything is disabled?

Gary: It's a UX decision. But don't make the menu disappear because then the user doesn't know if they get no menu because they did the wrong thing or because it was disabled.

[yep, this is UI that the browser should be able to manage]

Gary: Instead of a boolean for canUndo you suggested something else?

JW: No, I just wanted to have booleans for the functions.

Yo1: Sometimes in UI you have context information to hint at what will happen in the undo. Localisation is a mess there.

Gary: We could add that later…

JW: Recap: We make the element, that can be versioned. It can do contentEditable plus Ryosuke's proposal of turning on/off features. Current features are the different inputTypes, and global history

Enrica: We had contentEditable="*"...

JW: This will take over from that. All the new ones that haven't been made, will only be implemented in the new element.

Enrica: So a page that uses <foo contenteditable="true"> it will only behave in the old way

[Yes]

Enrica: So why do we need the versioning?

JW: Because we will inherit legacy problems, and want a way to say "OK, we will fix that in a new version mode" so we can fix problems stepwise.

Enrica: beforeInput will only be fired for the new element, and not for <x contentEditable>

Gary: Sort of - it will fire on input elements

JW: It will for legacy behaviour, but the idea is to have an HTML element that collects.

Annevk: What happens when you mix the attribute and element?

Travis: These are the same problems we already have with the attribute.

Annevk: not sure how it make sense if you tie undo/redo to the existence of the editor element

Travis: We want to give a lot of new properties to the editor. And we prefer to have a single element contain these, instead of further adding to global things that can accompany contentEditable on any element.

Annevk: I'm worried that you are going down the XHTML2 path…

Travis: That risk is valid…

[discussion about evolution]

Glazou: SO will you be able to express, in the brave new world, what contentEditable does?

[Yes. (we hope)]

Yo!: Why do we need to support the current legacy in the new version?

JW: I also thought that...
... but all the stuff only works in execCommand, and so on.

[so we can make a transition easier]

Glazou: this is document-wide, not element wide. If you have multiple editing elements, with different features turned on/off, that will be tricky.
... there is also designMode, which is document-wide.
... so there is nowhere to make the editor element replace that.

Travis: In practical use cases it is an iframe.

Glazou: Not necessarily. It is still feasible, and there are intranets that do this.
... anyway, we need to think about designMode

Enrica: caveat I see fora new element is that there are many cases where the attribute leverages the fact that you can put it on any container. Do we want to go down the path of a container? Are we making a monster - can we turn it on and off inside the subtree?

JW: That's a requirement for us.

DG: Implemented templates inside contentEditable, through CSS property that prevents selecting, modifying etc.
... an editable container nested in a non-editable, nested in an editable, is a case we need to deal with.

[break until 11.50]

Static range

Smaug: Why?

Gary: there's a range. Issue is that it keeps up to date with manipulations, which is expensive.
... concern that putting a range in an event and someone copies it, you have to do all the calculation, even if they never actually *use* them.
... There was pushback on using ranges. We wanted it for beforeInput, but didn't want to put a full range there because it would be expensive. But it would be nice to have a lightweight snapshot you can use for some things. It will be invalidated if there are changes.

Smaug: You don't know if what you are getting is valid or not.

Gary: right. if you have a cascade of event handlers that modify the DOM, we have a tricky problem. We have getTargetRanges which sends a snapshot, but you can upgrade to a real Range if you care, but you hould opt into that becaus they are expensive

Smaug: Does range perfomance show up in profiling?

JW: We were told not to add ranges by browsers because they wouldn't implement

Smaug: Is this implementation or specification

Enrica: We track all ranges. By giving a range within an event, instead of being able to request the range live, you get problems.
... being able to request the range at the moment you want it is better than having an invalid snapshot that comes from when the event started.

Smaug: this is still a static range so can go invalid again.

Enrica: Sure, but you can keep requesting it.

Smaug: You will need to create new static ranges all the time

Enrica: With range, you *must* create the new thing on every change. Whereas being able to request, you can reduce the number of ranges you create,

Olli: Web developer has to request the static ranges..

AnnevK: Do you keep the static ranges around, or make a lot of new requests for them??

Gary: You can still get a real range. But the cost of forcing that everywhere is really high

Smaug: I am worried that this will be error-prone for developers. You don't know when they stop representing reality.

JW: When we use these in editors, we just occasionally want to get the range, make a change, and if you want an update you request the new static range. But you don't need it very often.

Smaug: Why do you keep the event alive?

Travis: To track undo stack

[discussion about usage patterns for ranges]

Yo1: There are use cases where live range is actually not helpful, and you *want* a static range.
... having liveness everywhere makes heavy browser implementation and leads programmers down bad paths.

Enrica: Ojan said, we agree, beforeInputevent gives you the situation before everything happens. So you *want* that to represent the situation at that time, not be updated…

Smaug: I would like to see the performance profile...

[bikeshed on name...]

Smaug: This should be a dictionary.

AnnevK: That makes it clearer that it isn't going to update.

Gary: We return an array of these…

AnnevK: You can return a sequence of dictionaries.
... static range as platform object has some dodgy characteristics. Dictionaries are pretty stable.

Travis: Like this.

Gary: Makes sense conceptually.

Travis: So instead of interface, you say dictionary

Smaug: Yep

Yo1: But using a dictionary, typecheking is harder.

Travis: Yes, but not clear what you would need that for. You could add .type or something.

Yo1: You can't do static typechecking…

Travis: You don't get that anywhere else in JS…

Gary: If you have a .type then you can make a static typechecker

Travis: Sure, but JS in general is not typed - you have to add a layer that covers that.
... a dictionary is a typed object in WebIDL.
... there is a formalism for static range as a dictionary

Yo1: OK, that works.

RESOLUTION: Interface should be turned into dictionary.
... Move forward with static ranges.

Static range can be affected by getTargetRange?

Gary: Actually they are just associated with, not affected by. There is no action going to happen to this.
... think it's just a wording confusion.

JW: If I merge two paragraphs, they are associated with the event, even if the range is in the middle of them...

Gary: Yes, but we say the thing associated is the middle of the paragraph.

Smaug: What if you remove the entire contentEditable and then ask for getTargetRange ?

DG: You get the dictionary, but they are removed from the document.

Smaug: Needs to be specified what happens.

Enrica: Shuld be defined to happen the same way as it would in a live range.

Smaug: during dispatch you have a range that you use to create the snapshot

Gary: current selection is managed somehow. This is saying "so snapshot that"

Smaug: OK
... If we already have that range, why not give it out?

gary: Because if you want the snapshot, that you copy and cache, …

Smaug: Should we just enable ranges to .makeSnapshot()

JW: Javascript developers don't know the range is costly. We keep the things around, and then we discover that the browser is slowing down.

Travis: We need a range for selectionAPI already. There is no cost handing that out.

Gary: Do we need getTargetRange - to get something other than the current selection?

JW: Yes. For example hitting backspace.

Travis: So how do you figure out the target range after the first event listener makes a mess of the DOM?

JW: Seems like it would be OK if you ask after that to receive an empty range.

Travis: that's an equally bad scenario?

JW: I don't see the use case. I take it, and make it a live range if I need that, but most of the time I don't.

Smaug: Then it is broken

Travis: That seems unavoidable though.

Enrica: Reason to get here was range as part of event.

Smaug: That should disappear

Enrica: range is passed everywhere. First event handler changes the DOM, so you give a live range. live range comes with a cost.
... so instead you ask for the range if you want it, and if something has happened in the middle you still want to know that.

Smaug: Why doesn't getTargetRange return live ranges?

Enrica: To reduce perfomance.

Smaug: But this is a separate method so you don't keep them around.

Gary, you might be creating and sending them out.

Travis: Does 2nd listener need to know state is dirty? If so how do they know that?
... so two editors are attached to the same content, do I need to know that state is dead as I get it?

JW: This seems like a special case of having created a bug for yourself…

Yo1: It's not such a special case…

JW: If you update the DOM, then you throw away the range and they get an empty array?

Gary: getTargetRange has to know that the first time it gives the right answer…

JW: You have a hidden live range, you give the user a static snapshot. If the range is no longer valid, you give back an empty handle.

Travis: Think that can be precisely specified, if you describe it in those terms and check initial state vs current state.

Smaug: yes, and it is a bit overspecified…

Enrica: Imagine browser fires beforeInput with deleteBackwards.
... so implementing the editor I need the range to find which character to eliminate. I get "node+3"
... do my own mutation. Can I put back a selection so the next time I will find where I am now? The answer should be yes, right?

Travis: You need to put the caret somewhere

Enrica: I want to get a range that is valid. Let's say I block deleting "a"…
... the browser will delete everything else, and put the selection back.
... so we have to be able to compute the range.

Travis: With multi-listeners for the deleteBackwards, you might delete a lot more.

Gary: The first handler deletes the "t" in cat. So it gets back a collapsed range, and realises it doesn't need to do more.

JW: Editors have plugins. You can't make a grammar checker without using the central management.
... so you *can't* have things that just randomly add listeners and actually still work.

Travis: Do you rely on selection to put the caret back?

Gary: can't tell you for sure, but we should.

Travis: Point is we don't care how we deal with the following listener case, but we really do need to document it carefully.

[lunch until 2pm]

Clipboard API

Gary: Seems close to what we are doing. We can push it outside.

enter key

Chong: we got feedback that what we say doesn't make sense

JW: We don't really know whether a user is looking for a new paragraph or a line break when they press enter

Chong: So should we send inputType enter?

JW: Yes. Some editors differentiate linebreak, using shift - in both directions.

Gary: When you press the enter key who knows whether it means line break or para?

JW: Your platform.
... think they should be kept apart. The developer in CKEditor found it strange listening to insertPara when he thought it was a linebreak.
... the other one thought it was odd because users cannot tell the difference between linebreaks and new paragraphs.

DW: We listen to both, and have a number of places where there are sequences and users don't find them…
... so we should have both.

Gary: prefix issue is here. Could we have insertEnterPara / insertEnterlinebreak

Travis: Good to have separate.

Chong: We want to use paragraph. What happens in a list?

Gary: New list item is kind of a paragraph.

Chong: what about paragraph separator?

Travis: What if you just want a linewrap?

Gary: this is why we have CR and LF … and the confusion engendered there.
... "line break" is a fine explanation for reality.

RESOLUTION: we need to bikeshed the names some more.
... You need to distinguish between paragraph break - new block which might actually be a list item or table row - and linebreak which is essnetially inline punctuation.

Event Order

Gary: We were thinking about event order for things. UI Events can define order for basic UI events, Drag and Drop should define how the DnD events relate to each other, but how do we define the ordering when clipboard gets mixed into drag/drop...
... You can't have each spec trying to define how they fit into all other specs in ordering. We think it makes more sense to have a single spec that orders events as we need to compose them.
... the idea is to make this just an ordered list
... there are some wrinkles that make it a bit more complex, but having everything in one spot seems to make sense.

Smaug: can we get this right without having it in the HTML spec?

Gary: I created a stub spec, as a list in order.

JW: Do we want to do this?

CMN: Yes… Agree there may be dragons, but lets do some exploratory work.

RESOLUTION: yes, we'll try to move forward on this.

order of DeleteByDrag / insertFromDrop

JW: We can split these two ways

Chong: We can split so one fires after the other, or nest them…
... related problem is we need one undo for most stuff, but for drag and drop we need to undo two different things. Is there a difficulty in there.

JW: If we have one update to the DOM what happens if we cancel the deleteByDrag

Chong: We will still insert stuff, but the delete getes cancelled. You can stop one at a time.

Travis: Is DOM modified when drag starts, or drag end?

<garykac> Stub for event order spec: https://github.com/garykac/event-order

Chong: When you finish the move.

Travis: So thats delete and insert, which would normally give two beforeInputs

JW: Which we need to get both target ranges

Travis: Makes sense.

Chong: When each command executes we create an undo. Including move.

Travis - and we are going to turn off undo by default, right?

Chong: we want to merge the two events so they go into the undo stack as a single piece.

Travis: appendChild can do this too. How does that work?

JW: These only fire on user-initiated, not where the JS does this.

Chong: we fire events nested. But we want to change it to sequential…
... the undo is tricky - can we undo in one action.

Gary: when do undo events get fired?

Travis, will users be OK if they had to press undo twice to undo a drag and drop?

CMN: Users get really scared by undo - if it doesn't seem to do what they think, they'll just stay away from it in future

Enrica: We want an undo-group in the undo manager

Gary: But people are not going to use browser undo, right?

Travis: Is there a context to know that it is a drag/drop not a copy paste?

JW: We should add a note for developers to watch out and group these things so end-users don't get surprised.

Chong: How is a browser going to implement this

Travis: That's up to you. We don't want to change the way the API is designed.

JW: If I am in this, where the targetRanges come from is variable?

Enrica: but you'll get the second range, so it's OK.
... assume these are only fired if there is a successful drop.

JW: So if you drag a part of a text node, we need a deterministic way to count the offsets so they are interoperable.

Travis: the data needs to be correct. Browsers need to be self-consistent.

JW: Are they nested or sequential?

CMN: inconsistency across browsers here is not going to be nice.

Travis: If you cancel teh insertion, does that turn it into a cut?

Enrica: yes.

Travis: So you must represent the DOM between the two steps.

Chong: yes, we have a single operation, but we can fake it.

Travis: We want to make this atomic.

David: I think it would be smarter to *expect* that will become the case more often.

Travis: I like the idea of letting scripts mes around in the middle of an atomic event.

<Travis> ..says Travis sarcastically

Chong: the beforeInputs should both be fired between drop, and dragend.

Enrica: to make it atomic, you get both beforeInputs before DOM mutation.

Yo1: JS can change the DOM tree in the middle. So insertFromDrop is a difficult situation. That's why we propose the non-nested order.
... if the dragging comes from another process, deleteByDrag won't be dispatched.

So the undomanager should be aware of that.

Travis: fire deleteFromDrag then insertFromDrop both cancelable immediately after each other.

JW: So in JS I get the two events, the targetRanges will work?

Smaug: You need to have a live range somewhere

CMN: when you do it yourself, the static range is going to be invalidated potentially, so you need to calculate yourself if there is going to be an issue.

Enrica: What if you are dragging between two applications?

Travis: We should just build an atomic primitive.

JW: You need multiple target ranges - e.g. pulling stuff across flexboxes.
... we don't want to mix those metaphors with drag and drop.

Annevk: You can also have bidi…

Gary: We would need two sets of ranges if we are going to make atomic DnD

Travis: Right. But to do this right and not break the Web we have to do this in the middle of the two events, and we cannot then optimise into doing atomic.

Gary: But allowing beforeInput to have two sets of ranges sounds ugly. Are there other use cases for that?

Smaug: DOM doesn't have a concept of atomic move.

Travis: I mean not being able to run scripts between two events.

Smaug: you have mutation events. So you can't.

Yo!: Move is not an atomic operation.

Annevk: agreed.

[exploring the implications]

Annevk: These should not fire sync.

JW: Is this the next agendum, microtasks?

Gary: what if you cancel one but not the other?

Travis: it can't be inserted if you didn't remove it…

Annevk: If you do the modification, a little task, …

Travis: These have to be sync because they are in user action land.

[more discussion]

AvK: it's problematic.
... mutation events come back.

<Travis> scribe: Travis

[Going on 10 minute break]

[In the midst of a discussion of how beforeinput is supposed to dispatch: sync?]

annevk: there are so many side-effects that have to be specified to track the state that the browser needs to "do the action" if the event is not canceled.
... this is not specified

For mutation events: "they" are trying to faze them out of the platform.

scribe: these beforeinput are the same as mutation events

smaug: I disagree; these are not the same as mutation events.
... the issue is how to track the drop place.

JW: You would use some 'internal' live range, right?

smaug: yes, that is possible.
... so I don't see it being the same issue.

Yo: we re-evaluate the target node where the action is taking place.

Point about whether to use Microtasks or not.

Travis: Does microtasks seem like a potential feasible idea.

annevk: No, microtasks happen after the fact. You can't do cancelation.
... yo, what was the problem with insertion into display:none?

Yo: because the user wouldn't see the insertion.

garykac: but that's OK, right?
... it's doing what you told it to do.

Yo: you could keep a reference to the target, and insert at the target.

enrica: In webkit, you can't have a selection in a display: none region.

annevk: The selection would be removed, but does that prevent anything else from happening?

enrica: it can happen at the end

annevk: well, layout can be forced causing it to change...
... conceptually, the model could work.
... Hmm, what about if you focus change in the middle of the event?
... it really depends on what order various things are checked.
... this should be done as part of actions and what they do. (Such as when to check for focus, selection, when the updated it--or not.)
... If focus moves, then where does the drop happen.
... "It's not hard, it's just work." (TM)

JW: We want to spec the current behavior...
... wondering if the events are fired on the original element, and insertion happens where the selection ends up.
... On compStart if you move selection elsewhere, the events fire on the original element...

smaug: The input event should fire wherever the focus is (my preference)

JW: You paste on word/google docs
... you get paste event, then you open a new element editor, and put the selection there. Then you let the paste complete in the target location.
... This is a possible use-case.

enrica: Makes more sense to me that if you move the selection, all the subsequent events follow the selection.

annevk: If you write out the algorithm, you find the right model falls out.

garykac: Common case is the selection is not changed.

annevk: You need to get the edge cases right.

RESOLUTION: The user-agent action (and any subsequent input events) will target/fire on the element that has the selection (or focus--we're not sure which).

annevk: take a look at clipboard as an example, but don't assume it's correct.

garykac: what happens when events are in separate specs?

annevk: spec management problem. You can figure it out; big spec or factored with monkeypatches, etc.)

what's the order of drag and drop?

RESOLUTION: drag-drop order of operations should be sequential (separated and not nested)

<chongz> https://github.com/ProseMirror/prosemirror/issues/7

iOS contenteditable big menu.

JW: folks writing JS editors have issue in iOS. Big menu is overlapping their menu. They don't know what to do.
... they can't switch to it either.

enrica: proposal was to add an attribute to control the states.
... two aspects:
... add new input types to support backcolor, frontcolor, etc.
... specify what kind of features should be supported (can be read by user agent to customize the menu).

garykac: These are the attributes on the CE tag?

enrica: yes.
... rniwa proposed a list of supported actions, or in a new attribute.
... also the ability to do some shortcuts (like all the 'insert' things) at once.
... all the supported things in the input types.

JW: I agree with all of this--one exception.
... other contenteditable versions, we don't do this?

enrica: Has default values according to the style of contenteditable.

JW: with other CE types, we may need to still get the input events for things that are not supported even in the other modes.
... I know ojan also agrees.
... Let's just keep the discussion of the other CE types to the next meeting.
... Yes, I'm in favor of resolving on this.

RESOLUTION: Move forward with Apple proposal on menu UI state attributes (except for the various CE input type restrictions)

Topic meetings

garykac: how about another meeting in a few months?
... to help accelerate progress?

JW: yep.

Clipboard API Proposal

garykac: Current clipboard ops can sometimes (i.e., paste sanitization) block the UI thread

Proposal makes it async

scribe: also can't put permissions prompt in.
... rniwa mentioned cut/paste between Mac and iOS.
... we need this to be async to handle this.
... We are now seeing we're blocked, and need to just move directly to the async model.
... Note: mozilla said [maybe] drag drop should be async?
... I want to focus directly on clipboard
... It's basically blocking google and apple.
... This is a reasonably large change to the clipboard API spec. Any concerns?

smaug: Not really.
... question: how does the web page tell the UI that it has something to copy?

garykac: there's a permission associated with it.

smaug: How to enable the copy button in the menu bar?

garykac: This isn't related.

smaug: No way for the webpage to say that "I have something to copy".
... OK. That's fine.

garykac: this would be handled by the attribute
... For the spec, I'll sync with grisha we are editors.

small issue review

garykac: long key press?
... https://usercontent.irccloud-cdn.com/file/vVDORvQY/image.png

Should contenteditable have break-word behavior by default?

<ojan> no :)

garykac: Clickability of elements with user-select: none
... CSS group resolved by taking our feedback.
... Set virtual enter key text, presentation of Google's proposal.

<smaug> https://html.spec.whatwg.org/#input-modalities:-the-inputmode-attribute

<smaug> (warning, single page link)

garykac: The above is the inputmode attribute proposal.

smaug: looks just like the HTML5 attribute. Is it the same?
... Should follow-up with HTML issue, and have it fixed there.

garykac: yes, doesn't need to be a completely new spec.

chongz: reason to not merge inputmode and inputaction is because of the combinatorial explosion: URL + serach, URL + action

garykac: May not be necessarily true.
... seems like it doesn't belong in that document.
... How to make undo/redo useful?

JW: CK editor realized that undo/redo before input don't work because we only fire if there's something in the history.
... we need a way to still get the event.
... does it mean we need to disabled the global history?

enrica: problem is undo will not happen if JS has handled all operations because browser's undo stack is empty.
... if we let them use what we proposed before does it solve the problem?

JW: It would show/hide; should it also control the events?

enrica: I think so.

JW: It should be enabled by default, if disabled no events fired.

chongz: If you focus another element and hit undo, it won't come back to you

garykac: It's OK, we want that.

JW: Let's have that be the default.

garykac: For virtual keyboard type, it should be in HTML5?

chongz: Dave said the spec is meant to replace HTML attribute

garykac: setting the virtual key enter text...

smaug: these are based on what Android has.
... what if the content author wants customization

<garykac> https://rawgit.com/dtapuska/action-hint/master/index.html

garykac: Please take a look and send comments to the WICG.

chongz: on a form/input field, on enter, you can submit form and hide the keyboard.
... currently we can dismiss keyboard on input

yo: you may need to move focus.

enrica: blur()-ing?

yo: yes.
... should blink remove break-work behavior?

Travis: seemed like Ojan said yes (by saying no).

yo: in webkit, several word-break css properties are applied automatically.
... how about apple? it affects iOS. are they OK?

<chongz> Example http://jsfiddle.net/pfe9mj4o/10/

enrica: it does not happen there.

garykac: it seems reasonable to do so.
... (to remove word-break)

long-key press and IME

JW: Entering IME while holding the key down does not end-up entering the IME, while with Japanese IME always switches.

<ojan> i support trying to remove the added CSS properties that magically appear when you set contentEditable. What we can actually ship will depend on web compat in practice.

In Blink: preventDefault() on insertText should not cancel long-press actions.

(That was chongz)

<ojan> In general, I think adding hte magic CSS properties is bad because the content is almost always then sent to a location that doesn't have those CSS properties, so it renders differently than what the author wrote.

<ojan> (e.g. when you send your email, it's not viewed in a context that has break-word)

<ojan> (sorry for the out of line comments)

JW: user hit's 'a', beforeinput 'a', update data model, add a to a DOM, IME finally shows up, which 'a' do you want?

<kochi> ojan: your comment seems align with Yosin's idea

<ojan> i actually think the break-word behavior is a better editing experience, but that doesn't matter because we can't change the whole web to break-wording their non-editable content

[scribe is lost]

<kochi> a

<kochi> oops

JW: long key-press on Mac starts an IME, which then does some magic replacement actions

[long debate about how this works when selection point is moved around in beforeinput]

JW: Congratulations! We're done for today.

Summary of Action Items

Summary of Resolutions

  1. insertReplacementText
  2. Yes we can do the issues 33/34 proposal for cancelable at each end of IME.
  3. We think that this makes sense to propose something concrete
  4. Interface should be turned into dictionary.
  5. we need to bikeshed the names some more.
  6. yes, we'll try to move forward on this.
  7. The user-agent action (and any subsequent input events) will target/fire on the element that has the selection (or focus--we're not sure which).
  8. drag-drop order of operations should be sequential (separated and not nested)
  9. Move forward with Apple proposal on menu UI state attributes (except for the various CE input type restrictions)
[End of minutes]

Minutes formatted by David Booth's scribe.perl version 1.144 (CVS log)
$Date: 2016/09/22 16:29:18 $

Scribe.perl diagnostic output

[Delete this section before finalizing the minutes.]
This is scribe.perl Revision: 1.144  of Date: 2015/11/17 08:39:34  
Check for newer version at http://dev.w3.org/cvsweb/~checkout~/2002/scribe/

Guessing input format: RRSAgent_Text_Format (score 1.00)

Succeeded: s/whetere/whether/
Succeeded: s/Type/Action/
Succeeded: s/?/ element?/
Succeeded: i/Travis: Is it time to add/Topic: Editing element?
Succeeded: s/Kochi/Yoshi/
Succeeded: s/in the undo/in the undo. Localisation is a mess there./
Succeeded: s/disu/discu/
Succeeded: s/Do you need a lot of those/Do you keep the static ranges around, or make a lot of new requests for them?/
Succeeded: s/collapsed/removed from the document/
Succeeded: s/ging/gine/
Succeeded: s/Event order//
Succeeded: s/Topic:/Topic: enter key/
Succeeded: s/Ching/Chong/g
Succeeded: s/yes, but/yes, we have a single operation, but/
Found Scribe: chaals
Inferring ScribeNick: chaals
Found Scribe: Travis
Inferring ScribeNick: Travis
Scribes: chaals, Travis
ScribeNicks: chaals, Travis
Present: Yves Chong GaryK OlliP Enrica Chaals Léonie Johannes Kochi DomC Yoshi Yoisho Hayato. MarkV Travis MarkVickers Glazou AnnevK Navid Joshua
Agenda: https://github.com/w3c/WebPlatformWG/blob/gh-pages/meetings/16-09-22TPAC-3.md
Got date from IRC log name: 22 Sep 2016
Guessing minutes URL: http://www.w3.org/2016/09/22-webapps-minutes.html
People with action items: 

[End of scribe.perl diagnostic output]