From 3684a399a587d48a334c4afe02a0a86573df513a Mon Sep 17 00:00:00 2001 From: LucasC Date: Wed, 3 Jul 2024 17:50:57 +0200 Subject: [PATCH 1/5] XWIKI-22280: Object editor dropdowns are not keyboard accessible * Added translations for the hint of the dropdowns * Updated the DOM generated for the class and object editors to be more precise and correct on semantics. * Updated the .js to take those changes into account. * Updated the styles to take those changes into account * Improved organization in dataeditors.css * Added a transition on the caret rotations. TODO: * remove the value from the titles, the punctuation doesn't match the use * Accessibility of the reordering feature --- .../src/main/resources/flamingo/editclass.vm | 23 ++- .../src/main/resources/flamingo/editobject.vm | 35 ++-- .../resources/ApplicationResources.properties | 3 + .../js/xwiki/editors/dataeditors.css | 151 ++++++++++-------- .../resources/js/xwiki/editors/dataeditors.js | 4 +- 5 files changed, 127 insertions(+), 89 deletions(-) diff --git a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editclass.vm b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editclass.vm index 9722e77f9047..ddd0c07b9172 100644 --- a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editclass.vm +++ b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editclass.vm @@ -60,12 +60,16 @@ $xwiki.jsfx.use('js/xwiki/editors/dataeditors.js', true)## #macro (displayProperty $field)
- $services.icon.renderHTML('caret-down') -

- $!escapetool.xml($doc.displayView($field.xWikiClass.get('prettyName'), "${field.name}_" , $field)) - ($doc.displayView($field.xWikiClass.get('name'), "${field.name}_" , $field): +

+

+ +
#set ($deletePropURL = $doc.getURL('propdelete', $escapetool.url({ 'propname': $field.name, @@ -176,8 +180,13 @@ $xwiki.jsfx.use('js/xwiki/editors/dataeditors.js', true)##
- $services.icon.renderHTML('caret-down') -

${escapetool.xml($class.name)}

+

+ +

#addPropertyForm()
diff --git a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm index 4efda110a452..d3064fda972e 100644 --- a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm +++ b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm @@ -39,13 +39,17 @@
#getFieldSummary($obj $firstField $firstFieldSummary)
- $services.icon.renderHTML('caret-down') -

#cleanClassname(${class.name}) ${obj.number}#if ($firstField): $firstFieldSummary#end - $services.icon.renderHTML('cross') - #if (!$hasCustomObject) - $services.icon.renderHTML('pencil') - #end +

+

+ $services.icon.renderHTML('cross') + #if (!$hasCustomObject) + $services.icon.renderHTML('pencil') + #end
#if ($isNew == "true") @@ -152,8 +156,13 @@ #set ($object = $doc.getObject($class.name, $customObject)) #if ($object)
- $services.icon.renderHTML('caret-down') -

${escapetool.xml($class.name)}

+

+ +

#displayObject($object $class $props $titleField) @@ -173,9 +182,13 @@ #end #set ($objectCount = $objects.size())
- $services.icon.renderHTML('caret-down') -

$services.localization.render('core.editors.object.objectsForClass', [${escapetool.xml($class.name)}]) - ($objectCount) +

+

diff --git a/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/ApplicationResources.properties b/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/ApplicationResources.properties index a3b07050e5af..6cf267a4030a 100644 --- a/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/ApplicationResources.properties +++ b/xwiki-platform-core/xwiki-platform-oldcore/src/main/resources/ApplicationResources.properties @@ -1295,6 +1295,7 @@ core.editors.object.newObjectForClass.tooltip=New {0} object core.editors.object.editAllObjects=\u00ABEdit all the objects defined in this page core.editors.object.editSingleObject=[Edit only this object] core.editors.object.editSingleObject.tooltip=Edit only this object +core.editors.object.toggleDisplay.tooltip=Toggle detail displaying for the object: core.editors.object.removeObject=[Remove this object] core.editors.object.removeObject.tooltip=Remove this object core.editors.object.invalidPropertyName=No such property: {0} @@ -1318,6 +1319,8 @@ core.editors.object.removeDeprecatedProperties.failed=Failed to remove deprecate core.editors.class.title=Editing class {0} core.editors.class.switchClass=Edit another class core.editors.class.switchClass.confirm=Do you want to save this class before leaving the editor? +core.editors.class.toggleDisplay.tooltip=Toggle detail displaying for the class: +core.editors.class.property.toggleDisplay.tooltip=Toggle detail displaying for the property: core.editors.class.addProperty.name.label=Add new property core.editors.class.addProperty.type.label=Type core.editors.class.addProperty.submit=Add diff --git a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.css b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.css index 099b50c55639..c73bc2c6f5b9 100644 --- a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.css +++ b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.css @@ -13,13 +13,6 @@ color: $theme.textPrimaryColor; } -#body .xclass-title h2 span { - border: none; - color: inherit; - display: inline; - margin: 0; - position: static; -} div#xwikiobjects input[type="checkbox"], div#xwikiclassproperties input[type="checkbox"], div#xwikiobjects input[type="radio"], div#xwikiclassproperties input[type="radio"] { @@ -35,11 +28,13 @@ div#xwikiobjects input[type="radio"], div#xwikiclassproperties input[type="radio /* Generic links */ .more-actions { padding: 8px 2px; + display: flex; + align-items: center; } .more-actions .edit-all { display: block; - padding: 2px 18px; + padding: .2rem .5rem; } /* Object editor */ @@ -56,10 +51,6 @@ div#xwikiobjects input[type="radio"], div#xwikiclassproperties input[type="radio padding: 0; } -.xclass-content .xobject-title h3 { - padding: 0; -} - .xclass-content { margin: 0 0 0 16px; } @@ -72,12 +63,6 @@ div#xwikiobjects input[type="radio"], div#xwikiclassproperties input[type="radio background: transparent; } -.xobject:hover .xobject-title, -.xproperty:hover .xproperty-title { - background-color: $theme.highlightColor; - color: $theme.textPrimaryColor; -} - .xobject-title h3 { border: none; font-size: 100%; @@ -94,28 +79,18 @@ div#xwikiobjects input[type="radio"], div#xwikiclassproperties input[type="radio margin-bottom: 2px; } -/* XProperty */ -.xobject dl, .xproperty dl { - margin: 0; -} - -.xobject-title:hover, .xclass-title:hover, .xproperty-title:hover { - cursor: default; -} - -.xobject-action { - display: block; - position: absolute; - top: 2px; -} - .xobject-title .delete { - right: 0; color: $theme.notificationErrorColor; } -.xobject-title .edit { - right: 16px; +.xobject-content xdt { + font-size: 75%; + font-weight: bold; +} + +/* XProperty and XObjects */ +.xobject dl, .xproperty dl { + margin: 0; } /* XProperty definition */ @@ -143,20 +118,35 @@ div#xwikiobjects input[type="radio"], div#xwikiclassproperties input[type="radio width: 2em; } -.xproperty-title h2 { +.xproperty-title h3 { display: block; padding: 2px 20px 2px 18px; margin: 0; font-size: 1em; font-weight: 100; + min-height: 16px; +} + +/* We want to keep the property displays relatively compact. We reduce the default padding and margins. */ +.xproperty-title h3 button { + padding-bottom: 0; + padding-top: 0; + margin-bottom: 0; + margin-top: 0; +} + +/* Default state for the icon representing the property. */ +.xproperty-title h3 button .iconHolder { background: transparent url("$xwiki.getSkinFile('icons/datamodel/propertyType-Generic.png')") 0 center no-repeat; + display: inline-block; + min-width: 16px; min-height: 16px; - flex-grow: 1; + vertical-align: middle; } .xproperty-title label { font-size: 60%; - line-height: 1em; + line-height: 1rem; } .xproperty-content { @@ -168,21 +158,45 @@ div#xwikiobjects input[type="radio"], div#xwikiclassproperties input[type="radio clear: both; } -.xobject-content xdt { - font-size: 75%; - font-weight: bold; -} - /* Expand/collapse */ /* We need to increase the priority of the rule in order to override Toucan styles */ -#body .xobject > .xobject-title, #body .xclass > .xclass-title, +#body .xobject > .xobject-title, #body .xproperty > .xproperty-title { display: flex; gap: .5em; align-items: baseline; } +.xclass-title h2, +.xclass-content .xobject-title h3, +.xproperty .xproperty-title h3 { + flex-grow: 1; + padding: 0; +} + +.xclass-title h2 button, +.xobject-title h3 button, +.xproperty-title h3 button { + border: none; + background: transparent; + width: 100%; + text-align: left; +} + +.xclass-title h2 button:hover, +.xobject .xobject-title h3 button:hover, +.xproperty .xproperty-title h3 button:hover { + background-color: $theme.highlightColor; + color: $theme.textPrimaryColor; +} + +.xclass-title h2 button:active, +.xobject .xobject-title h3 button:active, +.xproperty .xproperty-title h3 button:active { + box-shadow: none; +} + /* Before Javascript, the collapsable and collapsed classes are not here. In order to avoid flickering, we need to take into account this initial state in the style rulesets. The default state is collapsed for xobjects and xproperties, but expanded for xclasses. */ @@ -198,16 +212,18 @@ The default state is collapsed for xobjects and xproperties, but expanded for xc display: inherit; } -.xclass.collapsed > .xclass-title > .toggle-collapsable > *, -.xobject > .xobject-title > .toggle-collapsable > *, -.xproperty > .xproperty-title > .toggle-collapsable > * { +.xclass.collapsed > .xclass-title .toggle-collapsable > *, +.xobject > .xobject-title .toggle-collapsable > *, +.xproperty > .xproperty-title .toggle-collapsable > * { transform: rotate(-90deg); + transition: transform .2s ease-out; } -.xclass.collapsable:not(.collapsed) > .xclass-title > .toggle-collapsable > *, -.xobject.collapsable:not(.collapsed) > .xobject-title > .toggle-collapsable > *, -.xproperty.collapsable:not(.collapsed) > .xproperty-title > .toggle-collapsable > * { +.xclass.collapsable:not(.collapsed) > .xclass-title .toggle-collapsable > *, +.xobject.collapsable:not(.collapsed) > .xobject-title .toggle-collapsable > *, +.xproperty.collapsable:not(.collapsed) > .xproperty-title .toggle-collapsable > * { transform: rotate(0); + transition: transform .2s ease-out; } /* Disabled/Deprecated */ @@ -219,7 +235,9 @@ The default state is collapsed for xobjects and xproperties, but expanded for xc font-style: italic; } -.disabled .xproperty-title h2, #body #xwikiclassproperties .disabled dt label, #body #xwikiobjects dt.disabled label { +.disabled .xproperty-title h3, +#body #xwikiclassproperties .disabled dt label, +#body #xwikiobjects dt.disabled label { color: $theme.textColor; } @@ -234,14 +252,9 @@ The default state is collapsed for xobjects and xproperties, but expanded for xc font-weight: 900; } -.xproperty-title .tools { - align-self: center; -} - .xproperty-title .tools .tool { width: 16px; height: 16px; - float: left; background: transparent none center no-repeat; } @@ -259,51 +272,51 @@ The default state is collapsed for xobjects and xproperties, but expanded for xc } /* Property type icons */ -.StringClass h2 { +.StringClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/string.png')"); } -.DateClass h2 { +.DateClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/calendar.png')"); } -.TextAreaClass h2 { +.TextAreaClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/textarea.png')"); } -.NumberClass h2 { +.NumberClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/number.png')"); } -.BooleanClass h2 { +.BooleanClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/boolean.png')"); } -.StaticListClass h2 { +.StaticListClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/staticlist.png')"); } -.GroupsClass h2 { +.GroupsClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/groups.png')"); } -.UsersClass h2 { +.UsersClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/users.png')"); } -.LevelsClass h2 { +.LevelsClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/rights.png')"); } -.DBListClass h2 { +.DBListClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/database.png')"); } -.DBTreeListClass h2 { +.DBTreeListClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/tree.png')"); } -.PasswordClass h2 { +.PasswordClass h3 button .iconHolder { background-image: url("$xwiki.getSkinFile('icons/datamodel/password.png')"); } diff --git a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.js b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.js index 9b3b0b38196a..7020f831ab1e 100644 --- a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.js +++ b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.js @@ -652,10 +652,10 @@ editors.XDataEditors = Class.create({ if (objectContent.childElementCount === 0) { object.addClassName('collapsed'); } - var objectTitle = object.down('.xobject-title'); + var objectToggle = object.down('.xobject-title h3 button'); var xclassName = this.getXClassNameFromXObjectId(object.id); var xObjectNumber = this.getXObjectNumberFromXObjectId(object.id); - objectTitle.observe('click', function(event) { + objectToggle.observe('click', function() { var isAlreadyLoaded = objectContent.childElementCount > 0; if (!isAlreadyLoaded && !object.hasClassName('loading')) { object.addClassName('loading'); From e030e846a6bcee63159c9eb38d8830b13f2474d3 Mon Sep 17 00:00:00 2001 From: LucasC Date: Fri, 5 Jul 2024 15:28:45 +0200 Subject: [PATCH 2/5] XWIKI-22280: Object editor dropdowns are not keyboard accessible * Added basic keyboard support to the reorder tool as an alternative to drag and drop * Removed titles from the toggling buttons, they only conveyed repetitive info and would need some additional (very similar) translations * Updated style to use current bootstrap button styles (btn-default instead of btn-secondary...) * Refined a bit more the style to fit better with what it used to be and better UI navigability. * Updated translation to reflect the new functionality of the reorder button. --- .../src/main/resources/flamingo/editclass.vm | 4 +-- .../src/main/resources/flamingo/editobject.vm | 6 ++-- .../resources/ApplicationResources.properties | 2 +- .../js/xwiki/editors/dataeditors.css | 22 +++++++++--- .../resources/js/xwiki/editors/dataeditors.js | 34 +++++++++++++++++-- 5 files changed, 54 insertions(+), 14 deletions(-) diff --git a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editclass.vm b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editclass.vm index ddd0c07b9172..43f7fb7cd406 100644 --- a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editclass.vm +++ b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editclass.vm @@ -61,7 +61,7 @@ $xwiki.jsfx.use('js/xwiki/editors/dataeditors.js', true)##

-

diff --git a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm index f75ccba13011..6c850fc5277b 100644 --- a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm +++ b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm @@ -46,7 +46,7 @@ #cleanClassname(${class.name}) ${obj.number}#if ($firstField): $firstFieldSummary#end - $services.icon.renderHTML('cross') + $services.icon.renderHTML('trash') #if (!$hasCustomObject) $services.icon.renderHTML('pencil') #end From f8c46688ddbbb182e55d04411b9159a6836f2c61 Mon Sep 17 00:00:00 2001 From: LucasC Date: Fri, 4 Oct 2024 17:00:31 +0200 Subject: [PATCH 4/5] XWIKI-22280: Object editor dropdowns are not keyboard accessible * Added escaping for the titles --- .../src/main/resources/flamingo/editobject.vm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm index 6c850fc5277b..9c53fcc7ae73 100644 --- a/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm +++ b/xwiki-platform-core/xwiki-platform-flamingo/xwiki-platform-flamingo-skin/xwiki-platform-flamingo-skin-resources/src/main/resources/flamingo/editobject.vm @@ -46,9 +46,9 @@ #cleanClassname(${class.name}) ${obj.number}#if ($firstField): $firstFieldSummary#end - $services.icon.renderHTML('trash') + $services.icon.renderHTML('trash') #if (!$hasCustomObject) - $services.icon.renderHTML('pencil') + $services.icon.renderHTML('pencil') #end
@@ -93,7 +93,7 @@
+ title="$escapetool.xml($services.localization.render('core.editors.object.removeDeprecatedProperties.link.tooltip'))"> $services.icon.renderHTML('cross') $services.localization.render('core.editors.object.removeDeprecatedProperties.link') @@ -208,7 +208,7 @@ #macro(displayAddObject $class) #end @@ -260,7 +260,7 @@ #if ($mustSync) #end #end ## checkPropertyDeprecation @@ -368,7 +368,7 @@ #set ($fullEditorURL = "$doc.getURL('edit', 'editor=object')") #end #set ($redirect = $xwiki.relativeRequestURL) From ebc45866813fa2cd3c1aad6c0042c92862209911 Mon Sep 17 00:00:00 2001 From: LucasC Date: Fri, 4 Oct 2024 17:25:22 +0200 Subject: [PATCH 5/5] XWIKI-22280: Object editor dropdowns are not keyboard accessible * Added comments --- .../main/webapp/resources/js/xwiki/editors/dataeditors.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.js b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.js index 334fdad62d0a..9d0a466d7265 100644 --- a/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.js +++ b/xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war/src/main/webapp/resources/js/xwiki/editors/dataeditors.js @@ -764,12 +764,15 @@ editors.XDataEditors = Class.create({ }.bindAsEventListener()); // Extend the Sortable items with arrow keys support movebutton.observe('keydown', function(event){ + // We only do something when the key is ArrowUp (keyCode: 38) or ArrowDown (keyCode: 40) if (![38, 40].includes(event.keyCode)) { return; } var sequence = Sortable.sequence($('xclassContent')); var sequenceLength = sequence.length; var item = event.target.parentElement.parentElement.parentElement; /* We need to recompute the name of the entry similarly to what's done in scriptaculous - to make sure it matches the one we get in the sequence. */ + to make sure it matches the one we get in the sequence. + See https://github.com/madrobby/scriptaculous/blob/b0a8422f7f6f2e2e17f0d5ddfef1d9a6f5428472/src/dragdrop.js#L592 + for the source of the format regex. */ let format = /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/; let currentElementName = item.id.match(format) ? item.id.match(format)[1] : ''; let currentElementIndex = sequence.indexOf(currentElementName);