Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested properties get ignored. #1333

Closed
jay-cox opened this issue Feb 24, 2017 · 8 comments
Closed

Nested properties get ignored. #1333

jay-cox opened this issue Feb 24, 2017 · 8 comments

Comments

@jay-cox
Copy link

jay-cox commented Feb 24, 2017

When initializing a quill view with existing content nested properties get overridden by the outermost definition

Steps for Reproduction

  1. Visit the quilljs.com interactive playground
  2. Replace the contents of the #editor-container with
    <span style="color: #000;">black <span style="color: #F00;">red</span> black</span>

Expected behavior:
The word red should be colored red.

Actual behavior:
All the words are black

Platforms:
safari 10.0.3
OS X Yosemite 10.10.5

Version:
1.2.0

@jay-cox
Copy link
Author

jay-cox commented Feb 27, 2017

After investigating I have found that the clipboard module is building up the document in a depth first order. This causes parent attributes to always overwrite child attributes.

One way to fix this is by adding an option for 'retain' Deltas to be soft - i.e. to preserve existing attribute values if they exist.

I have pull requests on the quill-delta and quilljs projects that implement this:

@jhchen
Copy link
Member

jhchen commented Feb 28, 2017

I think for the Clipboard's purposes it should always favor the lower tree nodes since that how CSS rules are prioritized so a config is not necessary. I don't think modifying the Delta API is the best approach and others should be explored first as the cost of this approach is supporting that API forever and all the interactions with other APIs.

@jay-cox
Copy link
Author

jay-cox commented Feb 28, 2017

Yes, for clipboard (as currently written) use case you always want to prioritize the existing values, but for the interactive case you always want to prioritize the new values.

Modifying the delta API should certainly be considered carefully.

The clipboard traverse and match* functions could be rewritten to work top down with the existing delta API, but this will require some extra bookkeeping outside of the Deltas.

@jay-cox
Copy link
Author

jay-cox commented Feb 28, 2017

The Delta API is very simple with only insert, retain, and delete operations, but powerful enough to build a full text editor on top of.

My proposed "soft" retain, while it would be useful in certain document creation situations, is not likely to be useful for general document editing.

If the Delta API is to be expanded is should probably be in a way that is much more generally applicable than my 'soft' retain proposal.

One possible addition that would work for both document editing and creation cases is to allow passing in a function to control how attributes are merged on retain operations. This could be an optional argument to retain operations, or it could be a new operation type.

Doing it that way would allow a simple way to add editor features like 'make selected text 20% larger' as well as allow for a simple way to perform 'soft' retains for document creation workflows.

it could be used something like this:

function scale_text(a, b)
{
  let attributes = extend(true, {}, a);
  if (a['font-size'])
    attributes['font-size'] *= b.scale_factor;  // real code would need to account for units.
  else
    attributes['font-size'] = b.scale_factor + 'em';
  return attributes;
}

filter = new Delta().retain(12, {scale_factor: 1.2}, scale_text)

If it is a requirement that Deltas are able to be persisted, then one could add an indirection through a registry without too much extra effort.

@jhchen
Copy link
Member

jhchen commented Mar 13, 2017

I think I would favor just fixing this specific bug in the Clipboard (which is used for initialization).

@dsathyan
Copy link

dsathyan commented Jul 3, 2017

I can still reproduce the issue

From test case - <span style="color: red;"><span style="color: blue;">Test</span></span>

If I add this to editor(innerHTML) and get the delta (quill.getContents()), I get -
{"ops":[{"attributes":{"color":"red"},"insert":"Test"},{"insert":"\n"}]}

In the clipboard - select the string + cut + undo and the text becomes red

@jhchen
Copy link
Member

jhchen commented Jul 3, 2017

It's working for me. @dsathyan You are following the steps for reproduction precisely? It sounds like you are doing something else from the mention of innerHTML

@dsathyan
Copy link

dsathyan commented Jul 3, 2017

My bad, it does work

And innerHTML unleashes a different beast and not related to clipboard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants