Skip to content

Range#expand() #431

Open
Open

Description

@foolip

https://jsbin.com/valihix/edit?html,output

This test shows existence of the API in Blink, EdgeHTML and WebKit, but not Gecko.

It might make sense to standardize alongside w3c/selection-api#37, possibly using some shared logic.

It has been deprecated in Blink for a very long time, tracked by https://crbug.com/445218, but given the level of support I now think we should first investigate standardizing.

Activity

  1. foolip commented on Mar 23, 2017

    @foolip
    MemberAuthor

    The API surface would be:

    partial interface Range {
      void expand(DOMString unit);
    };

    The unit values are "word", "sentence", "block" and "document". Any other values are no-ops. If we really wanted to maybe we could use an enum which would result in an exception instead.

  2. annevk commented on Mar 23, 2017

    @annevk
    Member

    @littledan hey, it seems https://tc39.github.io/ecma402/ doesn't expose anything around word/sentence/etc. boundaries. Is that planned? I think ideally we make sure we use shared primitives to define these aspects, even if below they end up depending on platform conventions and libraries.

  3. littledan commented on Mar 23, 2017

    @littledan

    Yes, it is proposed, in https://github.com/tc39/proposal-intl-segmenter , currently at Stage 2. I'm not really worried about a mismatch in semantics, as probably browsers will implement both of them using the same underlying internationalization libraries (usually ICU).

    That draft spec isn't really well-factored in terms of exposing something HTML can call into--should it be?

    The granularities that Intl.Segmenter exposes are grapheme word sentence and line. It's nice to see that two of those line up with the same name and the same semantics. What does block mean--is this like selecting until the next hard line break?

    FWIW Intl.Segmenter's constructor throws an exception if you pass in a value that's not one of those four.

  4. annevk commented on Mar 23, 2017

    @annevk
    Member

    @rniwa ^^

    I think it would be nice if all three API entry points could call into the same underlying primitive. Obviously Selection and Range have to do some processing around that for it to make sense for their contexts.

  5. rniwa commented on Apr 5, 2017

    @rniwa

    No, what's exposed to ICU is completely different from what we use to modify selection at least in WebKit on Mac and iOS, and they're intentional. For example, ICU on iOS would treat each character in CJK as a separate word for line breaking purposes but for the purpose of selecting text, it would treat multiple characters as a single word. There are many other edge cases and special cases for selection, line breaking, word wrapping, etc...

  6. annevk commented on Apr 5, 2017

    @annevk
    Member

    Sure, but instead of ICU you could use your own implementation. Nothing here is requiring ICU. The idea is just that they share the same implementation.

  7. rniwa commented on Apr 5, 2017

    @rniwa

    Well, on Mac, for example, we emulate clicking on a word (using AppKit) in order to determine the word boundary, and that's nothing to do with ICU. In fact, there is no way for us to expose that to Intl.Segmenter. Also, we do use ICU in other places. Modifying selection is just very special.

  8. domenic commented on Apr 5, 2017

    @domenic
    Member

    In fact, there is no way for us to expose that to Intl.Segmenter

    Does that mean you're unable to implement the "word" part of the Intl.Segmenter proposal? If so it would be good to raise this at TC39, as the proposal is pretty far along in the process.

  9. rniwa commented on Apr 5, 2017

    @rniwa

    In fact, there is no way for us to expose that to Intl.Segmenter

    Does that mean you're unable to implement the "word" part of the Intl.Segmenter proposal?

    No, we can totally implement that for Intl.Segmenter because we have ICU, and we use that for word breaking, etc... what I'm saying is that the word boundary behavior for selection is completely different from what we use for line breaking and Intl.Segmenter. It requires a hit testing in AppKit.

    As a general rule, I don't think it's possible to spec almost anything about how selection behaves in WebKit on Mac & iOS based on a lower level primitive due to the way our stuff is integrated with platform APIs, and they're only remotely related to ICU's word boundary definitions on either OS.

  10. littledan commented on Apr 5, 2017

    @littledan

    This seems entirely reasonable to me. Seems like we can't expose a text-only primitive for Range#expand, even if we might be able to for line breaking (given the right tweaks).

  11. rniwa commented on Apr 5, 2017

    @rniwa

    For your entertainment, TextBoundaries.mm#L183 is the code in WebKit that uses doubleClickAtIndex in AppKit. It's absolutely horrifying but nonetheless, that's what we use for word breaking in our editing / selection code.

  12. annevk commented on Apr 5, 2017

    @annevk
    Member

    I'm really curious why hit testing cannot be avoided. I'm also somewhat interested in what other implementations end up doing. If they all end up doing the same as Intl.Segmenter, having the abstraction could still be useful, even though we could allow difference for selection. (It's a little sad that Range ends up being impacted as well, as it's sorta supposed to be a non-UX API.)

  13. rniwa commented on Apr 5, 2017

    @rniwa

    Sorry, hit testing was a red-herring to say. I don't think AppKit does actual hit-testing. It's likely doing some magic with ICU. I said hit testing because the method is called doubleClickAtIndex. It doesn't go through any sort of hit testing in CSS boxes or any DOM nodes for that matter.

    My point was mainly that we get a string and pass it to AppKit, and AppKit does something with it, which is completely opaque to us. So we can't really describe it in terms of ICU operations.

  14. annevk commented on Apr 5, 2017

    @annevk
    Member

    Sure, but we shouldn't describe anything in terms of ICU operations, since ICU is just an implementation. The actual description needs to be flexible enough either way.

  15. domenic commented on Apr 5, 2017

    @domenic
    Member

    I guess the question in terms of implementations is whether WebKit/JSC would plan to implement Intl.Segmenter's word mode using ICU or AppKit.

  16. 5 remaining items

  17. rniwa commented on Apr 6, 2017

    @rniwa

    FWIW, we will not attempt or consider to remove this API at this moment due to backwards compatibility concerns.

  18. yosinch commented on Apr 6, 2017

    @yosinch

    @annevk, I'm working for Blink at Google, and owner of Blink editing. I'm also a member of editing-tf@
    For Blink, usage of Range#expand() is low and we would like to reduce maintenance cost, I would like to
    remove Range#expand().

  19. annevk commented on Apr 6, 2017

    @annevk
    Member

    @yosinch ah okay, if you're successful in removal we can file a bug against Edge to see if they can consider it too. Maybe then down the line WebKit can reconsider. I'm happy to delay standardizing contentious APIs.

  20. foolip commented on Apr 7, 2017

    @foolip
    MemberAuthor

    @yosinch, do you know any editing people working on Edge? Getting their thoughts on this and Selection#modify() would be good.

    Compat risk wise, Range#expand() has lower usage than many things we have successfully removed, but it would still require httparchive analysis to get an idea about what the breakage would look like. Unfortunately this API is not very grep friendly, my experiments with BigQuery are quite noisy. Happy to help dig in that if you want to pursue removal though.

  21. yosinch commented on Apr 7, 2017

    @yosinch

    @yosinch, do you know any editing people working on Edge? Getting their thoughts on this and Selection#modify() would be good.

    I don't know Edge people working on editing. Last time editing meeting in TPAC , Travis joined for discussion.

  22. foolip commented on Apr 7, 2017

    @foolip
    MemberAuthor
  23. gked commented on Apr 11, 2017

    @gked

    I am of the same opinion as rniwa. We should still be backwards compatible with the web. EdgeHtml will keep the implementation as is. We could, of course, deprecate it in the spec so authors would be discouraged from using it.

  24. annevk commented on Apr 12, 2017

    @annevk
    Member

    @gked it's already maximally deprecated by not being in the DOM Standard to begin with.

  25. foolip commented on Apr 12, 2017

    @foolip
    MemberAuthor

    @gked, do you have any sense of how interoperable the EdgeHTML implementation is with Blink and WebKit? Does it operate on the DOM, the layout tree, or is it all tied up with editing as it is in Blink/WebKit?

  26. annevk commented on Mar 13, 2018

    @annevk
    Member

    @yosinch have you made any progress here?

  27. added
    needs concrete proposalMoving the issue forward requires someone to figure out a detailed plan
    on Jul 8, 2026
  28. josepharhar commented on Oct 6, 2026

    @josepharhar
    Contributor

    Does webkit still support this api? We are still supporting it in chromium, and it looks like usage has gone up a lot since 2017: https://chromestatus.com/metrics/feature/timeline/popularity/393

  29. annevk commented on Oct 7, 2026

    @annevk
    Member

    WebKit still has these non-standard items:

        // Non-standard: We should eventually drop this since no other browser supports it
        undefined expand(optional DOMString unit);
    
        // Non-standard: We should likely drop this since we added it for Firefox interoperability, but now no other browser supports it.
        short compareNode(Node node);
        const unsigned short NODE_BEFORE = 0;
        const unsigned short NODE_AFTER = 1;
        const unsigned short NODE_BEFORE_AND_AFTER = 2;
        const unsigned short NODE_INSIDE = 3;
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions