From fa9ee5d340d47ec52332358804d7358655484825 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Fri, 2 Feb 2018 16:43:34 -0500 Subject: [PATCH 1/4] ElementStyler: Remove unused `autochange' This used to be a thing back when we used Dojo, but it doesn't appear to be used anymore. * src/ui/ElementStyler.js (setValueByName): Remove `autochange' check. Lines starting --- src/ui/ElementStyler.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ui/ElementStyler.js b/src/ui/ElementStyler.js index 9442b1f..b046e87 100644 --- a/src/ui/ElementStyler.js +++ b/src/ui/ElementStyler.js @@ -508,9 +508,7 @@ module.exports = Class( 'ElementStyler', $element.val( ''+( value ) ); } - // the autochange propery signifies that we should trigger the - // change event - if ( $element !== undefined && ( change_event || ( $element.data( 'autochange' ) === true ) ) ) + if ( $element && change_event ) { $element.trigger( 'change' ); } From d0bbc04218795ecdb752baf76fce48db6553a92a Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Fri, 2 Feb 2018 16:55:50 -0500 Subject: [PATCH 2/4] ElementStyler: Remove jQuery for legacyradio value setting Continued eradication of jQuery for performance reasons. * src/ui/ElementStyler.js (setValueByName): Do not use jQuery for legacyradio styling. Throw exception on `change_event' argument set (this should no longer be used). --- src/ui/ElementStyler.js | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/ui/ElementStyler.js b/src/ui/ElementStyler.js index b046e87..fd88463 100644 --- a/src/ui/ElementStyler.js +++ b/src/ui/ElementStyler.js @@ -452,7 +452,13 @@ module.exports = Class( 'ElementStyler', { change_event = ( change_event === undefined ) ? true : change_event; - var $element; + // just to be sure before we fully remove this + if ( change_event !== false ) + { + throw Error( + "ElementStyler#setValueByName change_event is being removed" + ); + } // set value switch ( this._getElementType( name ) ) @@ -486,33 +492,19 @@ module.exports = Class( 'ElementStyler', var i = elements.length; while ( i-- ) { - var $question = $( elements[ i ] ); - - if ( $question.attr( 'value' ) == value ) - { - $question.attr( 'checked', true ); - $element = $question; - } - else - { - $question.attr( 'checked', false ); - } + const question = elements[ i ]; + question.checked = ( question.value === ''+value ); } break; default: - $element = this.getElementByName( + const $element = this.getElementByName( name, index, null, $context ); $element.val( ''+( value ) ); } - if ( $element && change_event ) - { - $element.trigger( 'change' ); - } - return this; }, From ffb709dbc48c383d9247e3d5bb46d4b94acb226a Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Mon, 5 Feb 2018 10:05:07 -0500 Subject: [PATCH 3/4] doc: Add trivia macro Useful for random historical facts that give useful context for developers of Liza. It hopefully helps to mitigate some of the issues of Theory Building as noted by Peter Naur. * doc/liza.css: Refactor some styles to make them more concise. (.trivia): Add styling. * doc/macros.texi (trivia): Add macro. --- doc/liza.css | 13 +++++++------ doc/macros.texi | 12 ++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/doc/liza.css b/doc/liza.css index 623bb28..0990fe9 100644 --- a/doc/liza.css +++ b/doc/liza.css @@ -125,9 +125,7 @@ but don't sacrifice space on small screens. border-color: #d33682; } -.doc-notice.devnotice p::before, -.doc-notice.devnote p::before, -.doc-notice.tip p::before +.doc-notice p::before { display: block; float: left; @@ -151,9 +149,12 @@ but don't sacrifice space on small screens. content: '\261E'; } -.doc-notice.devnotice p, -.doc-notice.devnote p, -.doc-notice.tip p +.doc-notice.trivia p::before +{ + content: '\1F914'; +} + +.doc-notice p { padding-left: 1.75em; } diff --git a/doc/macros.texi b/doc/macros.texi index 117786d..ed7dbfd 100644 --- a/doc/macros.texi +++ b/doc/macros.texi @@ -150,6 +150,18 @@ This system has maintenance concerns. @end macro +@c Conveying the historical details of the project is important to +@c understand why the system exists in the state that it does +@c today. Use of this macro will hopefully help mitigate some of the +@c problems noted by Peter Naur in his paper Programming as Theory Building: +@c http://pages.cs.wisc.edu/~remzi/Naur.pdf +@macro trivia{text} +@noticestart{trivia} +\text\ +@noticeend +@end macro + + @c link to source file if URI is known, otherwise display @c the path to the file @ifset SRCURI From 6de77f02c060c90be21dd57a43c5ae94717a5e7a Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Tue, 6 Feb 2018 11:33:44 -0500 Subject: [PATCH 4/4] doc: Begin documentation of DOM abstraction * doc/program.texi (DOM Abstraction): New section. --- doc/program.texi | 106 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/doc/program.texi b/doc/program.texi index a806822..248b703 100644 --- a/doc/program.texi +++ b/doc/program.texi @@ -45,6 +45,7 @@ Programs are ideally compiled from a @ref{Program XML,,Program@tie{}XML} @end menu + @node Program UI @section Program UI @maintenance{ @@ -101,11 +102,13 @@ It also displays question help text (also configured through the XML) and any error messages (@pxref{Error Handling}). @menu -* Group Styles:: Different ways of displaying groups of questions to - the user. +* Group Styles:: Different ways of displaying groups of questions + to the user. +* DOM Abstraction :: Representing and efficiently manipulating the DOM. @end menu + @node Group Styles @subsection Group Styles @refactor{ @@ -187,6 +190,104 @@ A list of available styles is detailed in @ref{t:group-styles}. +@node DOM Abstraction +@subsection DOM Abstraction +@cindex DOM +@cindex Dojo, History +@cindex jQuery +@devnotice{jQuery is still used throughout parts of the framework and + is a performance bottleneck@mdash{ + }it needs to be fully removed and replaced with this + DOM@tie{}abstraction.@footnote{ + See @srcrefraw{src/ui/ElementStyler}.}} + +@trivia{Liza was conceived long before frameworks like React existed. + The implementation originally used Dojo because of its + broad widget set, + but it was later dropped because of extreme performance issues, + especially on the browsers of the day + (Liza had to support Internet Explorer@tie{}6!); + at one point, + certain steps took over a minute to load for the + most unfortunate of users. + jQuery was then used for various parts of the UI and for ease of + DOM manipulation, + because of the lack of good and universal DOM APIs back then. + It too became a bottleneck. + Using DOM@tie{}APIs is now easy with modern browsers.} + +Liza's DOM abstraction contains a couple of components: + +@cindex DOM, Context +@cindex DOM, Field +@itemize +@item @dfn{DOM Fields} represent a field on the DOM. + Each field has a name and an index associated with the + DOM@tie{}node. + Nodes are cached in memory after first access and queue requests + during lookups to prevent stampeding. + Provides basic DOM operations, + including styling, containing row, and parent/sibling selecting. + See @srcref{src/ui/field}. +@item @dfn{DOM Context} is a slice of the DOM used for restricting queries. + It can attach and detach sections of the DOM, + and be further split into a context hierarchy. + The @srcrefjs{src/ui/context,DomContext} provides field querying + (see @srcrefjs{src/ui/field,DomField}) and caching. + See @srcrefraw{src/ui/context}. +@end itemize + +@tip{It is important to always use these abstractions for any portions + of the DOM under control of this abstraction; + otherwise, assumptions used for caching may result in + unintended behavior.} + +Using DOM contexts, + DOM operations can be restricted to small windows (for example, + groups or tabs), + further reducing the impact of DOM queries. + +The @dfn{root context} is represented by + @srcrefjs{src/ui/context,RootDomContext}@mdash{ + }sub-contexts can be obtained by invoking @jsmethod{slice} on any + context, + which creates a new context from a subset of the parent. +Detaching a parent will detach all child contexts. + +Contexts can be manipulated in memory before being re-attached. +Detach a context from the DOM with @jsmethod{detach}, + and attach with@tie{}@jsmethod{attach}. +A context is aware of its parent and will re-attach itself to the DOM + in the correct place. +A child context always attaches to the parent, + and so will not be rendered until the parent attaches. + +@tip{Always detach from the DOM before performing extensive manipulations; + this prevents the need for expensive re-painting until + manipulation is done, + at which point the context can be re-attached.} + + +@menu +* Field Styling:: Styling @srcrefjs{src/ui/field,DomField}. +@end menu + + + +@node Field Styling +@subsubsection Field Styling +@cindex Field, Styling +@helpwanted + +@srcrefjs{src/ui/field,DomField} is styled using field stylers + (see @srcrefraw{src/ui/styler}). +The two most notable stylers are + @srcrefjs{src/ui/field/ErrorFieldStyler} and + @srcrefjs{src/ui/field/NaFieldStyler}, + which style fields in error and hide fields that are no applicable + respectively. + + @node Program XML @section Program XML @helpwanted @@ -301,6 +402,7 @@ There is no limit to the number of groups that can share the same link. fields in the link.} + @node Specifying Predicates @subsection Specifying Predicates