Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

T/857 View placeholder #872

Merged
merged 14 commits into from
Mar 22, 2017
Merged

T/857 View placeholder #872

merged 14 commits into from
Mar 22, 2017

Conversation

szymonkups
Copy link
Contributor

@szymonkups szymonkups commented Mar 16, 2017

Suggested merge commit message (convention)

Feature: Added placeholder utility that can be applied to view elements. Closes ckeditor/ckeditor5#4008.


Additional information

Requires #864.

@szymonkups szymonkups requested a review from Reinmar March 16, 2017 14:32
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';

const CSS_CLASS = 'ck-placeholder';
const DATA_ATTRIBUTE = 'data-placeholder';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember I did something like this in my first PR to the CKEditor 4. And I remember that Fred gave me R- then telling it an unnecessary complication. Now, I see that we use it more and more. And to some point I like it.

But on the other hand, it's 2017 and all of us have IDEs which will easly find for us all data-placeholder and replace with anything we want. Also, I think that if one day we will want to replace it with something else, it probably will be a configurable variable so it will have to be changed anyway. At the same time, the fact that I have data-placeholder in the Chrome dev tools, and DATA_ATTRIBUTE in the code, and need to check and remember that it equals does not help to debug. It might not be hard with one variable, but we get more and more of these. I know, that it's a popular good practice, but, my question is: what do we get?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I even think I know the answer. These kind of constants is useful to avoid magic strings and magic number. For instance:

const BLOCKS_SPACING = 15;

// ...

createBlock( BLOCK_SPACING );

is far more readable them:

createBlock( 15 );

But in this case, I'm not sure if these 2 are magic strings. I don't see anything hard to understand in:

element.setAttribute( 'data-placeholder', placeholderText );

I even like it more that the current version, because I immediately know what I need to look for in the browser's inspector in case of debugging.

So my proposal is to use this kind of constants only when the value or/and the context of its usage might be unclear and adding named const improve readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see many of this in our code. I've recently used this approach when I was working on CSS classes in image and widgets, but same as you - I have a feeling that we could get rid of this.

extend( listener, EmitterMixin );

// Each document stores information about its placeholder elements and check functions.
const documentPlaceholders = new Map();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not a WeakMap?

Copy link
Contributor Author

@szymonkups szymonkups Mar 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't iterate over WeakMap items.
Now I can see what you mean - I can go without iterating at all :D Good point.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact what you need is to add a placeholders property to the document, but in a nice way, without modifying document object. WeakMap do exactly this.


for ( let placeholders of documentPlaceholders.values() ) {
placeholders.delete( element );
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you would change documentPlaceholders to the WeakMap you will have to change the loop to: documentPlaceholders( element.document ).delete( element );. But I think it worth to change it anyway.

@pjasiun
Copy link

pjasiun commented Mar 17, 2017

And one more thought: the view/placeholder.js file is, in fact, a singleton class. With public and private methods, properties. Don't get be wrong, I like how it is implemented, but I might spend too much time with OOP if I see it this way ;)

@Reinmar
Copy link
Member

Reinmar commented Mar 17, 2017

And one more thought: the view/placeholder.js file is, in fact, a singleton class.

It's a module (being a file is just a way to express a module). And indeed – a module can be like a singleton class. The exported stuff is the public API, the rest is private. It's exactly the same what we used to do with:

const api = ( function() {
  var priv = [];

  return { 
    add: function( priv ) {
      priv.push( item );
    }
  };
} )();

But a module is nicer :)

import global from '@ckeditor/ckeditor5-utils/src/dom/global';

const setTimeout = global.window.setTimeout;
const clearTimeout = global.window.clearTimeout;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this?

import global from '@ckeditor/ckeditor5-utils/src/dom/global';

const setTimeout = global.window.setTimeout;
const domDocument = global.document;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this?

const setTimeout = global.window.setTimeout;
const setInterval = global.window.setInterval;
const clearInterval = global.window.clearInterval;
const domDocument = global.document;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this? ;)

@@ -23,6 +23,7 @@ import {
} from '../conversion/model-selection-to-view-converters';

import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
import '../../theme/theme.scss';
Copy link

@pjasiun pjasiun Mar 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that we used to have global theme.scss per repository, but since we use Webpack, we could load styles more locally. This is a perfect example of it. We could have placeholder.scss and import it from placeholder.js. Thanks to these styles will not be added to the build as long as someone will not include the js file (there might be no usage of the placeholder.js) and, what is more important, it's very simple to find styles used in that JS fine. You just go to imports like you would do with a class or function.

//cc @oleq @Reinmar

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it really worked, we could get rid of nightmares like https://github.com/ckeditor/ckeditor5-link/blob/master/theme/theme.scss#L4. Waiting for confirmation from Reinmar, then I'm gonna create an umbrella issue in ckeditor5 because it applies to the entire codebase.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it works great. I use it a lot in another project.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I second that then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that this might be connected with a way how at the end we will build editor with proper theme. I am not sure if this is defined yet but let's wait for @Reinmar response.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, there are important things to remember here.

Importing an SCSS file many times may lead to code duplication and bugs. Even if placeholder.scss will be imported only once, it may be importing other SCSS files which are imported somewhere else already, making those rules appear twice. This is super sad and dangerous. I hit this hard when trying to start importing SCSS files in their proper JS components. It blew up.

The solution here is a refactoring of our SCSS. The code needs to be split into two layers – helpers and components. Helpers must not contain any rules – they should only contain mixins, functions, etc. This means that you will be able to import a helper multiple times without duplicating the code. The components will use helpers to define final CSS rules. However, a single component must not be imported more than once.

The second thing is that we must support multiple themes. No one so far made any research about that and the only related ticket so far is https://github.com/ckeditor/ckeditor5-ui/issues/144. But it clarifies that plugins (and engine) must not depend on a particular theme. This is a long topic and it doesn't make sense to spend time on it now, but how it applies to this particular case? It doesn't. The import can be anywhere. But the SCSS file should, at least for now, have no dependency on the theme-lark package.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point, actually. If we import things directly, switching to another theme will require changes in each single js file that imports SCSS vs. changing theme.scss file only. I wonder whether this could be possible.

@pjasiun
Copy link

pjasiun commented Mar 22, 2017

The change is fine for me. You can merge it as soon as you rebase the branch.

@pjasiun pjasiun merged commit 79b42da into master Mar 22, 2017
@pjasiun pjasiun deleted the t/857 branch March 22, 2017 19:23
@pjasiun
Copy link

pjasiun commented Mar 22, 2017

Nevermind.

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

Successfully merging this pull request may close these issues.

Create utility for creating placeholders
4 participants