Sunday, July 11, 2021

XSLT 1.0 in-browser Q&A

  • How to get XSLT path?

<xsl:value-of select="substring-before(substring-after(/processing-instruction('xml-stylesheet'),'href=&quot;'),'&quot;')"/>

XML: <?xml-stylesheet type="text/xsl" href="../AsTable.xsl" ?>

Gives: ../AsTable.xsl

  • How to get relative URL of  specific XSLT from XML?

<xsl:value-of select="substring-before(substring-after(/processing-instruction('xml-stylesheet'),'href=&quot;'),'AsTable.xsl&quot;')"/>

    Gives: ../


    • How to get Javascript URL relative to XSLT applied to XML as processing instruction?
    XSLT:
    <xsl:param name="baseUrl" select="substring-before(substring-after(/processing-instruction('xml-stylesheet'),'href=&quot;'),'AsTable.xsl&quot;')"  />
    <script type="module" src="{$baseUrl}XmlView.js">/**/</script> 

    Gives: ../XmlView.js


      • list of unique children tags (each last)
      *[ not( name() = name(following-sibling::*) ) ]

      Thursday, April 15, 2021

      Semantic Theming - indexed palette

      There are many articles on palette categorizations online, I would skip to semantic relation of palettes to UX elements. 

      Usually palette is selected from basic branded colors base. Usually 2 or 3 is sufficient, perhaps it relates to the heraldic symbols and colors. Remaining colors are chosen with keeping the base ones and emotional palette in mind. 

      There is a catch on selection enterprise and government designs are facing: color set should be "accessible" for various cohorts of people: color blind, light sensitive, etc. Adobe has given a nice tool to help with accessible palette creation. In regards to color "accessible" means that close colors should be distinctive enough even for people with color challenges or in applicable conditions of low/bright light.

      The palettes would have various colors but some of them have to be in straight color transition like bright to dim. Why you would need a color sequence? The answer resides in various states UX component are presented during interaction with UI. Those states are used in sequence: normal follows hovered, which followed "active"(pressed) , the disables should be least noticeable and resides in the end of color sequence. See Buttons and Actions states


      How many color sequences you would need? It depends on how many color variations your application supports: light, dark, high contrast for each, grayscale for ePaper devices, etc. Another factor is munber of variations for UX components. As in Buttons and Actions there are 5 variations proposed, will be more for other types of UX components. Each need to have own entry in one of indexed palettes. 

      While same palette could be reused for different UX components variations, it is better to choose a significantly distinctive different entry point in palette for inside of same color theme variation. 

      For UX components single palette is not sufficient. The indexed palettes usually come in more than one color per row. You would need to make colors as for background as foreground/text, for outline, and for other sub-elements. For action it would be 3 colors: background, text, outline/border. The 4rth is assumed to come from theme variation background which is a basis for selecting proper entry within indexed palette. In this sample you could see the need to alter the text color due to background change:



      Now to the meat of subject. The indexed palette become semantic when one of its entries is associated with one of semantic UX element variation. 




      Semantic theming - buttons and actions states

       While W3C button attributes and CSS has given straight forward combination of possible appearance of actions/buttons, not all have a "semantic" meaning for the user. There is a proposal for state sequence in colors escalation order ( see indexed palette article ).

      NORMAL  (default)

      FOCUSED  :focus css selector

      SELECTED attribute on some elements like OPTION 

      HOVER  :hover

      ACTIVE :active

      DISABLED attribute, not available on A element

      Not all states would affect background and not on all action variations: focused is usually leaves the current appearance with outline, in ghost variation the background by default would be transparent still for accessibility reasons keeping palette changes for other states.





      Sunday, March 7, 2021

      CDN deployment for JS modules - missing pieces

      There are multiple CDNs which support mirroring the NPM and GitHub sourced modules. They support the semantic versioning of your modules and a bit of additional services for modules owner. The services for web developers at the moment are quite limited and need to be extended in order to support modern web application development and delivery stack. 

      From security point we need assurance of content genuity  which is supported by resource integrity attribute , sufficient to replicate the binary build log, cross-reference to versioned source location. 

      The security scan reports from one or several vendors is essential for keeping the publicly reused code safe. Publishing security scan reports along with binaries would enable transparent review across all modules used in the page without exceptions making 100% coverage as for own content as for dependencies from 3rd parties.

      Test coverage is a significant criteria  of application reliability. In the world of Web 3.0 where apps from different vendors are met on same browser page the page owner does not have any assurance on quality of service overall unless able to review test coverage for all including 3rd party code. By deploying versioned binaries on CDN along with complimentary test coverage report the web application owner and consumer will acquire ability to check and if not satisfied to eliminate/substitute unreliable versions. 

      Licensing transparency.  While legal reuse and re-distribution questions are  boring and complex, publishing the licensing info along with published on CDN binaries would give ability to check whole dependencies tree on subject of (in-) compatible licensing of whole dependencies tree. That would be important for applications vendors, corporate consumers and final users who do not want to support pirating.

      Developers support. When dealing with binaries it is difficult to troubleshoot the internals of published in CDN module. The source map could be published on CDN next to binaries to help the development community and clients who are willing to troubleshoot themselves.  The original source version is also a subject to be mirrored on CDN.

      Build stack with target of CDN publishing would eliminate the need for keeping dependencies in bundles making the build lighting fast as dependencies and own code which already published on CDN does not need to be recompiled/verified/published.

      My goal is to support above features and make given stack available for applications developers.

      Cross-posted on Patreon

      Thursday, January 21, 2021

      Data layer development via ORM and API Gateway

      Not sure what pushed me to this direction but search "DB with graphql" lead to https://www.prisma.io/ - a tool for auto-generation GraphQL endpoints for DB schemas without programming. Open Surce, Apache 2 licence, MySQL/PostgreSQL capable.

      Prisma is a next-generation ORM that can be used to build GraphQL servers, REST APIs, microservices & more. (222 kB)

      For me DB-first approach is essential . The schema change is reflected in code just by re-generating code by CLI, no coding involved. Of course the discipline of migration for DB schema itself is still in place.


      And last peace of back-end puzzle: ORM integration with API gateway( will serve security, authentication, licensing, analytics ) : Prisma + Apollo https://www.howtographql.com/graphql-js/5-connecting-s
      erver-and-database/

      The generated classes out of DB schema could(and should) be reused as on back-end as in front-end code via versioned (npm?) package.

      Saturday, November 7, 2020

      Semantic theming - buttons and actions

      In semantic vocabulary the "button" is a wrong term which belongs rather to UI components. Button-like UI component could be presented as tabs, links, etc. There is common quality for all of them: the goal. Which is ACTION

      There are PRIMARY actions which serve the main flow with one DEFAULT variation. Default action is emphasized in UI to highlight what would happen if you hit ENTER key or say "Submit", in the scope of current form or document. There is usually only one primary action on page/form/section.

      NORMAL actions are serving various usual routine flows in app. On page usually there is more than one action. Usually it is implemented as a button.

      ALTERNATIVE actions meant to swing the flow from usual. Often used for closing dialogs or cancel the multi-step flow.


      DANGEROUS actions would need emphasizing of  potential danger for the flow they trigger. Often in red spectrum text, outline or even background. Delete, change the password or access key would be good samples for this kind of action. 


      GHOST. The least important, de-emphasized in comparison with NORMAL. Often does not have own background and outline. Toolbar buttons are usual sample for such.



      Synonyms and mixing up terms:

      PRIMARY often used as a term for default action. In such case the "secondary" is used as a surrogate for primary and "tertiary" as surrogate for alternative.

      ALTERNATIVE called a "secondary".

      "info", "success", "warning", "danger" - all referring to different specialized flows. Which could be justified if your application has many flow "flavors" and some are common. In usual application there is no need for such generalization as flows actually meant to be limited and clear in understanding. 

      HTML elements for actions

      There are semantic HTML tags which match the proposed actions categorization. 

      PRIMARY 

          button type="submit"
          input type="submit"
          input type="image"

      NORMAL

          button
          button type="button"
          button type="reset"  
          input type="reset"
          input type="button"

      Among other popular surrogates for buttons are A, LI, even DIV. 

      NOTE: using unconventional HTML tags when there is a normal one in standard would break accessibility and user convenience. It would lead to warnings in most of developer`s IDE.

      The rule of thumb for substitution of button with A hyperlink would be the missing onClick handler and URL in href.

      CSS properties

      Width and height are dictated by usability requirements: it should be distinctive enough among page elements, be large enough to be clickable by mouse pointer and comfortably tappable by finger.  That defines minimal dimensions. 

      Do not define width or height directly! It is a dangerous technique. The text inside would either be trimmed or overflow the action area. Even if you do not have that effect on your screen, on some user environments the text could be completely different due to translator, text size customization by device and/or by user. If you could not omit defining the action UI outer dimensions be polite and use min-width and min-height instead. But in usual app it is enough to use padding and inherit the text size.

      Font size & line height. Better to be left unchanged for the reasons of respecting the device manufacturer and user choice. The line height is good when it matches the font. There is no need to define line-height manually but if you want to override some 3rd party lib, there is no better value than 1EM. Otherwise on some devices user would see the text cut-off. The ideal value for font-size would be 1REM.

      Padding is the primary property to define action UI dimensions. With 1REM as ideal value, there are some cases when it should be tuned up: icons and images would use more vertical space than text. The text button takes 3REM: 1REM for text 1 REM for top and bottom padding. As icon meant to be 2x larger of text, the padding for iconized button would be .5REM. For image there is no need for padding as whole image would fill the space of 3REM. 


      TBD:

      • relation of action types with emotional and branded palette. 
      • CSS properties example with dark/light variations 

      Saturday, October 10, 2020

      Web Components Selenium test automation

      The one of strengths of Web Components is shadow DOM. It allows to insulate the css rules scoping to own content, allows efficient memory use by sharing DOM, etc... But for QA folks it could make a challenge as usual CSS and XPath selectors would not work anymore. There is a way around.

      Elements in Shadow DOM are not available via direct CSS or XPath. Instead you could use JS selector via "Copy JS path":

      In this case the full selector is

      full selector
      document.querySelector("#container-a593f6c588 > div > div > div > div > div > shopping-list")
      .shadowRoot.querySelector("div.padded > vaadin-combo-box")
      .shadowRoot.querySelector("#input")
      .shadowRoot.querySelector("#vaadin-text-field-label-0")

      which could be shortened to 

      trimmed selector
      document.querySelector("shopping-list")
      .shadowRoot.querySelector("vaadin-combo-box")
      .shadowRoot.querySelector("#input")
      .shadowRoot.querySelector("#vaadin-text-field-label-0")


      For simplification in styles tables the series of CSS selectors and shadowRoot could be swapped with :shadow-root pseudoselector. CSS handler in this case should convert the string bello to JS above:

      pseudo selector :shadow-root
      jkp-shop-plans :shadow-root vaadin-combo-box :shadow-root #input :shadow-root #vaadin-text-field-label-0

      the "Element locator" css should sniff for ":shadow-root" sub-string and replace with JS sequence above returning JS object. WebDriver has a By.js locator only in JS webdriver implementation. In Java you have to simulate it yourself. Fortunately that is easy via js Executor:

      1. String javascript = "document.querySelector('vaadin-combo-box').shadowRoot.querySelector('#input').shadowRoot.querySelector('#vaadin-text-field-label-0')";  
      2. JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;  
      3. WebElement element = (WebElement) jsExecutor.executeScript(javascript);