-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Fix part of #2575: RTCs refactor second milestone #4017
Conversation
vojtechjelinek
commented
Oct 23, 2017
- Moved information about RTCs from Component.py files to specs.js file.
- Loading specs.js directly from frontend and backend.
- specs.js file validity checked in tests.
Codecov Report
@@ Coverage Diff @@
## develop #4017 +/- ##
===========================================
- Coverage 45.87% 45.85% -0.03%
===========================================
Files 300 300
Lines 21169 21196 +27
Branches 3327 3329 +2
===========================================
+ Hits 9712 9719 +7
- Misses 11457 11477 +20
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @vojtechjelinek! I think this looks great. I just have a few minor comments.
assets/rich_text_components_specs.js
Outdated
@@ -0,0 +1,231 @@ | |||
/* eslint-disable */ | |||
/* Don't modify anything outside the {} brackets. | |||
* Insides of the {} brackets should be formatted as a JSON object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The contents of the {} brackets should ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
assets/rich_text_components_specs.js
Outdated
* JSON rules: | ||
* 1. All keys and string values must be enclosed in double quotes. | ||
* 2. Each key/value pair should be on a new line. | ||
* 3. All values and keys must be constant, you can't use any Javascript |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JavaScript
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
assets/rich_text_components_specs.js
Outdated
} | ||
}, | ||
"default_value": "You have opened the collapsible block." | ||
}] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deindent by 2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
# Check that the component directory exists. | ||
component_dir = os.path.join( | ||
feconf.RTE_EXTENSIONS_DIR, component_id) | ||
feconf.RTE_EXTENSIONS_DIR, component_name) | ||
self.assertTrue(os.path.isdir(component_dir)) | ||
|
||
# In this directory there should be a config .py file, an | ||
# html file, a JS file, an icon .png file and a protractor.js file, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update this sentence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
# Check that the component id is valid. | ||
self.assertTrue(self._is_camel_cased(component_id)) | ||
self.assertTrue(self._is_camel_cased(component_name)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we keep it as component_id? ID implies uniqueness.
Perhaps we should rename backend_name to backend_id as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it should be id.
For the backend_name I was trying to be consistent with frontend_name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. I'm fine with changing both to id, if you like, but up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
core/templates/dev/head/app.js
Outdated
@@ -72,8 +72,7 @@ oppia.constant('EVENT_ACTIVE_CARD_CHANGED', 'activeCardChanged'); | |||
// The conditioning on window.GLOBALS.RTE_COMPONENT_SPECS is because, in the | |||
// Karma tests, this value is undefined. | |||
oppia.constant( | |||
'RTE_COMPONENT_SPECS', | |||
window.GLOBALS.RTE_COMPONENT_SPECS ? window.GLOBALS.RTE_COMPONENT_SPECS : {}); | |||
'RTE_COMPONENT_SPECS', richTextComponents ? richTextComponents : {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually if we specify this in karma-globals then can we get rid of the ternary operator conditioning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
core/templates/dev/head/app.js
Outdated
@@ -517,7 +517,9 @@ oppia.factory('rteHelperService', [ | |||
}, | |||
createToolbarIcon: function(componentDefn) { | |||
var el = $('<img/>'); | |||
el.attr('src', componentDefn.iconDataUrl); | |||
el.attr('src', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Break after '(' if contents of (...) span multiple lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
core/templates/dev/head/app.js
Outdated
var interpolatedUrl = $interpolate( | ||
componentDefn.previewUrlTemplate, false, null, true)( | ||
customizationArgsDict); | ||
var componentPreviewUrl = componentDefn.previewUrlTemplate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be called componentPreviewUrlTemplate? A URL template != URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, sorry -- noticed a few more things!
if 'BaseRichTextComponent' in ancestor_names: | ||
cls._rte_components[clazz.__name__] = clazz() | ||
with open(feconf.RTE_EXTENSIONS_SPECS_PATH, 'r') as f: | ||
cls._rte_components = constants.parse_json_from_js(f) | ||
|
||
@classmethod | ||
def get_all_rte_components(cls): | ||
"""Get a list of instances of all custom RTE components.""" | ||
if len(cls._rte_components) == 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm reading correctly, the data looks like a dict, but the docstring here and the use of len() indicate a list. Is this a mistake? If so let's fix this to say something like "if not cls._rte_components" and change the docstring to "Get a dict mapping RTE component IDs to their definitions." or similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
core/templates/dev/head/app.js
Outdated
componentDefn.previewUrlTemplate, false, null, true)( | ||
customizationArgsDict); | ||
var componentPreviewUrlTemplate = componentDefn.previewUrlTemplate; | ||
if (componentDefn.previewUrlTemplate.startsWith( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try indexOf() === 0
here; startsWith is less browser-compatible. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -0,0 +1,231 @@ | |||
/* eslint-disable */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, I just realized, if this is going in assets, should we pull protractor.js out of extensions/rich_text_components as well and move it to somewhere in core/tests? Then delete extensions/rich_text_components altogether?
On the other hand, if extensions/rich_text_components is staying, then shouldn't this file go in it (like rule_templates.json goes in extensions/interactions)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need extensions/rich_text_components because there are other files we use. I would have to create new rule for this file in app.yaml in order to serve it from extensions/rich_text_components
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm. How does extensions/interactions/rule_templates.json do it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That file is not directly loaded from the frontend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, OK. In that case, let's keep it in assets/ and put a README.md file in extensions/rich_text_components that points to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -0,0 +1,6 @@ | |||
Steps to successfully add new Rich Text Component: | |||
1. Create folder in _extensions/rich_text_components_ with all the files | |||
2. Create new record in JSON in _asseets/rich_text_components_specs.js_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NB: assets is misspelled.
2. Create new record in JSON in _asseets/rich_text_components_specs.js_ | ||
3. Add script-imports into _core/templates/dev/head/components/rich_text_components.html_ | ||
|
||
[More in Wiki](https://github.com/oppia/oppia/wiki/Rich-Text-Editor-%28RTE%29-Overview) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest linking more specifically, to this: https://github.com/oppia/oppia/wiki/Rich-Text-Editor-%28RTE%29-Overview#rich-text-components
Please also update the wiki page. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two small issues but otherwise LGTM; please feel free to submit after addressing them. Thanks!