Development:JavaScript namespacing proposal
The idea of JavaScript namespacing was raised during the developers meeting that occured on Tuesday 29th September 2009 and I think its a fantastic idea, so I wrote this wee proposal and plan to hopefully win people over and get this is in for Moodle 2.0.
Note: This proposal assumes that the patch proposed for MDL-16699 that splits javascript-static into two files and moves JavaScript that is only being used in a single place within Moodle to a file that can be included by the code that uses it.
Concept
The concept is to apply a namespacing scheme to the JavaScript that is used by Moodle core code. By namespacing the JavaScript we can better define the structure of the JavaScript code as well as hopefully make it both more easily accessible and with any luck make it easier to develop JavaScript that is potentially reusable.
To answer a few quick questions about the process:
- How long would it take to namespace the JavaScript
- It wouldn't take very long at all to go through and apply a namespacing scheme to the JavaScript once the structure has been decided upon. Once the JavaScript has been namespaced it would be a simple case of iterating through the files that make up Moodle and converting references to the original JavaScript functions to thier namespaced equivilants.
- Does all JavaScript have to be namespaced
- No not at all. Initially only the core JavaScript files would be converted. After this it would be up to developers to namespace thier code should they choose to.... it would be the perfect opertunity to revise that legacy JavaScript ;)
- What about code that uses the old function calls?
- All of the core uses should be converted as part of the task of namespacing however we certainly need to support the old function calls. We will create mapping functions that simply take a call to a non-namespaced function and pass it to its namespaced equivilant.
- Will any of the JavaScript change?
- No. A couple of new internal functions will be introduced to support namespacing however the actual JavaScript functions being namespaced will not change. You will still be able to call them as you did before, you will just need to use the namespaced reference.
Why bother?
Because ....
- It greatly reduces the chances of developers accidentally creating clashing methods, or variables. Not just with core code but more importantly convlicts that may arrise between 3rd party extensions.
- Hopefully make the JavaScript code more usable and obvious by providing better organisation and structure. This will in turn hopefully reduce the number of identical functions that arise.
- It's the sort of thing that can only be done when revision of code is nessecary and there's no time like a major release for that.
- It looks better, more organised.
The root namespace
The root namespace at the moment I believe should be MOODLE. The reason for this is because it fits with the chosen JavaScript framework for Moodle, YUI. The version of YUI that Moodle has chosen to use is namespaced under YAHOO and whilst I realise that it appears that has been changed for the next major version (3.0) to just Y I personally think using MOODLE instead of something like M would be clearer to the development community.
Core namespaces
The following are namspaces that will be created in order to support the initial conversion to a namespaced JavaScript core.
- component
- JavaScript that creates controls, or structures used throughout Moodle.
- dom
- JavaScript for interacting with the DOM.
- form
- JavaScript for interacting with forms.
- module
- An empty namespace that gives 3rd party developers to extend in a safe area.
- util
- Miscelaneous JavaScript functions.
- user
- JavaScript that is utilised in direct respect to the user.
Time estimate
I think it would take a day to namespace the JavaScript files, and then a further day or two to convert the function calls and test. It is a reasonably simple procedure and with all of the JavaScript clean up that has gone into head already there should be realivily few edge cases left.
Implementation
The implementation of the core namespace and supporting functions to further namespace is reasonably simple, however it would need to be the very first bit of Moodle javascript to be executed. This simply means it would be defined and set up within javascript-priority.js which is the first file to be included in the HTML head.
Conversion of JavaScript files
lib/javascript-static.js
Declaration | Namespaced declaration | Declaration type |
---|---|---|
block_hider | MOODLE.util.block_hider | object |
checkall | MOODLE.form.check_all | function |
checknone | MOODLE.form.check_none | function |
collapsible_region | MOODLE.dom.collapsible_region | object |
deselect_all_in | MOODLE.form.deselect_all_in | function |
findParentNode | MOODLE.dom.find_parent | function |
fix_column_width | MOODLE.util.fix_column_width | function |
fix_column_widths | MOODLE.util.fix_column_widths | function |
focuscontrol | MOODLE.form.set_focus | function |
frame_breakout | MOODLE.frame.add_breakout_target | function |
init_help_icons | MOODLE.util.init_help_icons | function |
openpopup | MOODLE.util.window.popup | function |
select_all_in | MOODLE.form.select_all_in | function |
submit_form_by_id | MOODLE.form.submit_form_by_id | function |
emoticons_help | MOODLE.util.emoticons_help | object |
old_onload_focus | To be depreacted as part of MDL-19740 |
lib/javascript-priority.js
Declaration | Namespaced declaration | Declaration type |
---|---|---|
build_querystring | MOODLE.util.build_query_string | function |
cancel_scroll_to_end | MOODLE.util.scroll.cancel_autoscroll | function |
close_window | MOODLE.util.window.close | function |
close_window_reload | MOODLE.util.window.reload_close | function |
confirm_dialog | MOODLE.component.confirmdialog | object |
create_UFO_object | MOODLE.component.ufo.create | function |
destroy_item | MOODLE.dom.element.remove | function |
getElementsByClassName | Should really be deprecated in favour of YUI equivilant | |
hide_item | MOODLE.dom.element.hide | function |
json_decode | MOODLE.util.json.decode | function |
json_encode | MOODLE.util.json.encode | function |
repeatedly_scroll_t | MOODLE.util.scroll.autoscroll | function |
scroll_to_end | MOODLE.util.scroll.bottom | function |
MOODLE.util.scroll.top | function | |
set_user_preference | MOODLE.user.set_preference | function |
show_item | MOODLE.dom.element.show | function |
stripHTML | MOODLE.util.strip_html | function |
unmaskPassword | MOODLE.form.unmask_password | function |
update_progress_bar | MOODLE.component.progressbar.update | function |
Declaration | Namespaced declaration | Declaration type |
---|---|---|
create_shadow | MOODLE.component.shadow.create | function |
move_all_sidetabs_t... | MOODLE.component.dock.undock_all | function |
navigation_tab_panel | MOODLE.component.dock | object |
navigation_tree | MOODLE.component.tree | object |
navigation_tree_branch | MOODLE.component.tree.branch | object |
remove_shadow | MOODLE.component.shadow.remove | function |
setup_new_navtree | MOODLE.component.tree.init | function |
lib/javascript-deprecated.js
Declaration | Namespaced declaration | Declaration type |
---|---|---|
deprecate | MOODLE.util.deprecate | function |
deprecated_addonload | MOODLE.util.deprecated.addonload | function |
deprecated_confirm_if | MOODLE.util.deprecated.confirm_if | function |
submitFormById | MOODLE.util.deprecated.submitFormById | function |
lib/form/form.js
Declaration | Namespaced declaration | Declaration type |
---|---|---|
date_selector_calendar | MOODLE.form.mforms.date_selector.calendar | object |
elementShowAdvanced | MOODLE.form.mforms.show_advanced.show | function |
get_form_element_value | MOODLE.form.mforms.get_element_value | function |
init_date_selectors | MOODLE.form.mforms.date_selector.init | function |
lockoptionsall | MOODLE.form.mforms.lockoptionsall | function |
lockoptionsallsetup | MOODLE.form.mforms.lockoptionsallsetup | function |
set_form_element_disabled | MOODLE.form.mforms.disable_element | funciton |
showAdvancedInit | MOODLE.form.mforms.show_advanced.init | function |
showAdvancedOnClick | MOODLE.form.mforms.show_advanced.handle_click | function |
Resulting namespaced structure
- MOODLE
- component
- confirmdialog
- dock
- undock_all
- tree
- branch
- progressbar
- update
- shadow
- create
- remove
- ufo
- create
- dom
- element
- hide
- remove
- show
- collapsible_region
- find_parent
- element
- form
- mforms
- date_selector
- calendar
- init
- show_advanced
- init
- handle_click
- show
- get_element_value
- lockoptionsall
- lockoptionsallsetup
- disable_element
- date_selector
- check_all
- check_none
- deselect_all_in
- set_focus
- select_all_in
- submit_form_by_id
- unmask_password
- mforms
- util
- deprecated
- addonload
- confirm_if
- submitFormById
- json
- decode
- encode
- scroll
- autoscroll
- bottom
- top
- window
- close
- popup
- reload_close
- block_hider
- fix_column_width
- fix_column_widths
- init_help_icons
- emoticons_help
- build_query_string
- strip_html
- deprecate
- deprecated
- user
- set_preference
- component