From 4152170a78e43538ee75d563fa9b19c2cd283c9c Mon Sep 17 00:00:00 2001 From: Conrad Sollitt Date: Sun, 29 Jan 2023 22:27:19 -0800 Subject: [PATCH 01/23] =?UTF-8?q?=F0=9F=93=84=20Update=20docs=20for=20IE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/to-do-list.txt | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/docs/to-do-list.txt b/docs/to-do-list.txt index a4f44a8..64292f3 100644 --- a/docs/to-do-list.txt +++ b/docs/to-do-list.txt @@ -536,33 +536,6 @@ TODO List *) Create Unit Tests for the following functions: Controller.onRouteUnload -*) Improve Unit tests for IE 11 - - Typically they work about 50% of the time, however several routes have an - issue related to calls for [tester.pageTester2] - - It appears that [app.onUpdateViewComplete] is being called twice the first time - that it should be called. The reason for this is not yet known. - - It's not yet determine if this is a bug or related to IE behavior. Regardless - DataFormsJS has been used extensively with IE Users for many years before it was - released so it's known to work well with IE. - - To test the issue find and update the following code in [dataformsjs\test\js\unit-testing-core.js]: - // After checking the 'Page is Loading' message define a new - // [onUpdateViewComplete] function to check the final response. - app.onUpdateViewComplete = function () { - // Now check the 2nd state (usually after a web service response) - assert.equal(window.location.hash, hash, 'Hash Check - ' + hash); - if (expectHtml2 !== null) { - //// **** This block is the section to add for manual testing. - if (hash === '#/page-json-data-load-only-once' || hash === '#/page-reload-json-data' || hash === '#/missing-page-json-data') { - var html = document.getElementById('view').textContent.trim(); - if (html !== expectHtml2) { - console.log(hash); - console.log(expectHtml2); - console.log(html); - } - } - tester.checkElement('view', expectHtml2, assert); - } - *) Additional Unit Testing for the following functions, props, etc: data-engine: Validate error message in [app.setup()] at [(viewEngine === ViewEngines.Unknown)] From 199e74ed98376d4577bfbe87e1af2cb66f9d9d45 Mon Sep 17 00:00:00 2001 From: Conrad Sollitt Date: Sun, 29 Jan 2023 22:31:38 -0800 Subject: [PATCH 02/23] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Rename=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ js/web-components/filter-service.js | 4 ++-- js/web-components/input-filter.js | 4 ++-- js/web-components/utils.js | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cb4fa5..b0f5ae6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ DataFormsJS uses [Semantic Versioning](https://docs.npmjs.com/about-semantic-ver Overall the core Framework files, React Components, and Web Components and API are expected to remain stable however the version number is expected to increase to much larger numbers in the future due to the changes to smaller scripts and components. This change log includes all npm release history and new website features or major changes. +## 5.14.2 (Next Release) + +* Web Components - Renamed function `[utils.js].isAttachedToDom()` to `[utils.js].isDomAttached()` because the text string `ToDom` would show up when searching source code for case-insensitive `todo`. This is a minor update but prevents the files from showing up in external projects by accident. This could be considered a breaking change if an app calls the function but that is unlikely the case and it's mostly an internal function because it's undocumented outside of the changelog; that is the reason why a patch version is being released. + ## 5.14.1 (Dec 7, 2022) * Fixed a bug in Web Component `` that was introduced on the previous build where `format.{func}` was not working in `[data-show]` attributes. diff --git a/js/web-components/filter-service.js b/js/web-components/filter-service.js index 0be7300..316a5e8 100644 --- a/js/web-components/filter-service.js +++ b/js/web-components/filter-service.js @@ -38,7 +38,7 @@ /* jshint esversion:8, loopfunc:true */ import { WebComponentService } from './WebComponentService.js'; -import { isAttachedToDom } from './utils.js'; +import { isDomAttached } from './utils.js'; // Supported Operators when using [data-filter-operator] with [data-filter-value] const _operators = ['excludes', 'excludes_list', '!==', '===']; @@ -211,7 +211,7 @@ class FilterService extends WebComponentService { window.clearInterval(interval); interval = null; // For SPA's make sure the same page is still open - if (isAttachedToDom(firstFilterEl)) { + if (isDomAttached(firstFilterEl)) { this.setup(rootElement); } }, 100); diff --git a/js/web-components/input-filter.js b/js/web-components/input-filter.js index c591cd8..2ee2548 100644 --- a/js/web-components/input-filter.js +++ b/js/web-components/input-filter.js @@ -18,7 +18,7 @@ /* eslint-disable no-console */ import { - isAttachedToDom, + isDomAttached, defineExtendsPolyfill } from './utils.js'; @@ -74,7 +74,7 @@ class InputFilter extends HTMLInputElement { } window.clearInterval(this.interval); this.interval = null; - if (isAttachedToDom(this)) { + if (isDomAttached(this)) { this.filter(); } }, 100); diff --git a/js/web-components/utils.js b/js/web-components/utils.js index 9d99925..cdae4c6 100755 --- a/js/web-components/utils.js +++ b/js/web-components/utils.js @@ -507,7 +507,7 @@ export function componentsAreDefined(element, selector = '') { * * @param {HTMLElement} element */ -export function isAttachedToDom(element) { +export function isDomAttached(element) { let node = element.parentNode; while (node !== null) { node = node.parentNode; From 815d4392f7414771e43d29195222a68e6e653c31 Mon Sep 17 00:00:00 2001 From: Conrad Sollitt Date: Sun, 29 Jan 2023 22:33:32 -0800 Subject: [PATCH 03/23] =?UTF-8?q?=F0=9F=9A=80=20Release=205.14.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 +- js/DataFormsJS.js | 2 +- js/DataFormsJS.min.js | 4 ++-- js/react/es5/DataFormsJS.js | 2 +- js/react/es5/DataFormsJS.min.js | 2 +- js/react/es6/DataFormsJS.min.js | 2 +- js/react/jsxLoader.js | 2 +- js/react/jsxLoader.min.js | 4 ++-- js/web-components/filter-service.min.js | 2 +- js/web-components/input-filter.min.js | 2 +- js/web-components/json-data.min.js | 2 +- js/web-components/url-router.min.js | 2 +- js/web-components/utils.min.js | 2 +- package.json | 2 +- 14 files changed, 16 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0f5ae6..31dbee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ DataFormsJS uses [Semantic Versioning](https://docs.npmjs.com/about-semantic-ver Overall the core Framework files, React Components, and Web Components and API are expected to remain stable however the version number is expected to increase to much larger numbers in the future due to the changes to smaller scripts and components. This change log includes all npm release history and new website features or major changes. -## 5.14.2 (Next Release) +## 5.14.2 (Jan 29, 2023) * Web Components - Renamed function `[utils.js].isAttachedToDom()` to `[utils.js].isDomAttached()` because the text string `ToDom` would show up when searching source code for case-insensitive `todo`. This is a minor update but prevents the files from showing up in external projects by accident. This could be considered a breaking change if an app calls the function but that is unlikely the case and it's mostly an internal function because it's undocumented outside of the changelog; that is the reason why a patch version is being released. diff --git a/js/DataFormsJS.js b/js/DataFormsJS.js index 43cc40d..794e2fa 100644 --- a/js/DataFormsJS.js +++ b/js/DataFormsJS.js @@ -3391,7 +3391,7 @@ // Add Build Version // For new releases this gets updated automatically by [scripts/build.js]. - Object.defineProperty(app, 'version', { value: '5.14.1', enumerable: true }); + Object.defineProperty(app, 'version', { value: '5.14.2', enumerable: true }); // Assign [DataFormsJS] and [app] to the global variable space window.DataFormsJS = app; diff --git a/js/DataFormsJS.min.js b/js/DataFormsJS.min.js index b1700b7..f8e16e7 100644 --- a/js/DataFormsJS.min.js +++ b/js/DataFormsJS.min.js @@ -1,5 +1,5 @@ // @link https://www.dataformsjs.com -// @version 5.14.1 +// @version 5.14.2 // @author Conrad Sollitt (https://conradsollitt.com) // @license MIT -!function(){"use strict";var h,g={NotSet:"Not Set",Unknown:"Unknown",Mixed:"Mixed",Handlebars:"Handlebars",Vue:"Vue",Nunjucks:"Nunjucks",Underscore:"Underscore",Text:"Text"},c=g.NotSet,p=[g.Handlebars,g.Vue,g.Nunjucks,g.Underscore,g.Text],m=!1,f=!1,v=!1,C=null,E=0,t=null,w=!1,b=0,n=-1!==navigator.userAgent.indexOf("Trident/"),y=null,a=!1;function l(e,t,o,r){if(typeof e!==t)throw console.log(e),new TypeError("["+o+"] was not defined as a "+t+" when the function "+r+" was called")}function s(e,t,o){if(void 0===e)throw new TypeError("["+t+"] must first be defined before the function "+o+" is called");if("object"!=typeof e)throw console.log(e),new TypeError("["+t+"] was not defined as an object when the function "+o+" was called")}function i(e,t,o){if(""===e)throw new TypeError("["+t+"] must have a value when defined when the function "+o+" is called")}function d(e,t,o){if(void 0!==e[o])throw console.log(e),new TypeError("["+t+"."+o+"] is already defined")}function T(e,t,o,r){for(var n=0,a=r.length;n - "),n}catch(e){return console.error(e),n}}function r(e,t,o){e=document.createElement(e);return e.textContent=t,o&&(e.className=o),e}function L(e,t){console.error(e),window.setTimeout(function(){t&&null===t.parentNode&&((document.querySelector("body")||document.documentElement).appendChild(t),h.activeTemplate&&(h.activeTemplate.error=!0,h.activeTemplate.errorMessage=e.toString())),h.showError(t,e)},500)}function R(e,t,o){var r,n,a=null,l=null,i=null,s=null,d=null;if(null===t)i=e.getAttribute("data-template-id"),s=e.getAttribute("data-template-url"),null!==h.activeController&&(d=h.activeController.viewEngine);else{if(i=t.viewId,s=t.viewUrl,void 0!==t.viewEngine&&(d=t.viewEngine),void 0===s&&(s=null),null!==(i=void 0===i?null:i)&&null!==s)return void o(u(null,i,s,d,!0,"A controller must have either [viewId] or [viewUrl] defined but not both properties. This error is not possible when calling the [addController()] so one or more of the properties were modified by JavaScript code after the controller was already added."));if(null===i&&null===s)return"function"==typeof t.onRouteLoad||"function"==typeof t.onBeforeRender||"function"==typeof t.onRendered?void o(null):void o(u(null,i,s,d,!0,"A controller must have either [viewId] or [viewUrl] defined but neither property is defined. This error is not possible when calling the [addController()] so one or more of the properties were modified by JavaScript code after the controller was already added."))}for(r=0,n=h.compiledTemplates.length;r')}}catch(e){s=!(i=l=null),d=e}t={id:t,url:o,type:r,engine:l,html:i,error:n||s,errorMessage:n?a:d};return h.compiledTemplates.push(t),t}function U(t,o,e,r){var n="";try{if(e.error)return void h.showError(t,A(t,o)+e.errorMessage);switch(e.type){case g.Handlebars:case g.Underscore:n=e.engine(r);break;case g.Nunjucks:n=e.engine.render(r);break;case g.Text:case g.Vue:n=e.html;break;default:throw new TypeError("Unsupported or Unknown Template View Engine: "+e.type)}null===t.getAttribute("data-set-text-content")?t.innerHTML=n:t.textContent=n,h.updateTemplatesForIE(t)}catch(e){h.showError(t,A(t,o)+e)}}function V(){var e,s,d,t,o,r,n,u,a,l,p,i="hash"===y?window.location.hash:window.location.pathname,c=null,f=-1;if(200 element or [Controller] defined. Check to make sure that a controller or script for default route ["+h.settings.defaultRoute+"] exists.",h.showError(document.querySelector(h.settings.viewSelector),r)),v=!1}else h.activeController=c,u=function(){var e,t,o,r,n,a=c;if(a.modelName)h.activeModel=h.models[a.modelName];else{if(a.pageType&&void 0!==(o=h.pages[a.pageType]))if(a.viewEngine===g.Vue)if(e={},a.methods=void 0===a.methods?{}:a.methods,"function"==typeof o){e=new o;for(var l=h.getClassFunctionNames(o),i=["constructor","onRouteLoad","onBeforeRender","onRendered","onRouteUnload"],s=0;s tags are allowed."))),l=n.settings.lazyLoad.split(",").map(function(e){return e.trim()}),p=[],l.forEach(function(e){void 0===h.lazyLoad[e]?console.error("Missing [app.LazyLoad] scripts for: "+e):p.push(h.loadScripts(h.lazyLoad[e]))}),Promise.all(p).finally(function(){P(n),u()})):(P(n),u())}function P(e){if(null!==e.pageType&&void 0!==e.pageType&&void 0===e._pageCopied){var t=null;if(void 0===h.pages[e.pageType]?t="The page ["+e.pageType+"] has not been loaded for Controller[path="+e.path+"].":"object"==typeof h.pages[e.pageType]&&"object"!=typeof h.pages[e.pageType].model&&(t="Error - The [model] property for page object ["+e.pageType+"] must be a valid JavaScript Object."),null!==t)return e.settings=e.settings||{},e.settings.errorMessage=t,e.settings.hasError=!0,void h.showErrorAlert(t);var o=h.pages[e.pageType];if("function"==typeof o)for(var r=h.getClassFunctionNames(o),n=["onRouteLoad","onBeforeRender","onRendered","onRouteUnload"],a=0;a/g,">")},fetch:function(t,e,o){var r=h.deepClone({},h.settings.fetchOptions);return r.headers=h.getRequestHeaders(t),e&&(Object.assign(r,e),void 0!==e.headers&&(r.headers=Object.assign({},h.getRequestHeaders(t),e.headers))),!n||void 0!==r.method&&"GET"!==r.method&&"HEAD"!==r.method||"no-store"!==r.cache&&"no-cache"!==r.cache||((e=/([?&])_=[^&]*/).test(t)?t=t.replace(e,"$1_="+(new Date).getTime()):t+=(/\?/.test(t)?"&":"?")+"_="+(new Date).getTime()),fetch(t,r).then(function(e){return h.settings.logFetchRequests&&h.events&&"function"==typeof h.events.dispatch&&h.events.dispatch("fetch",{url:t,status:e.status}),Promise.resolve(e)}).then(function(e){var t=e.status;return 200<=t&&t<300||304===t?Promise.resolve(e):(t="Error loading data. Server Response Code: "+t+", Response Text: "+e.statusText,Promise.reject(t))}).then(function(e){var t=void 0===o?"application/json":o;return 0===(t=e.headers.has("Content-Type")?e.headers.get("Content-Type"):t).indexOf("application/json")?e.json():e.text()})},routingMode:function(){return y},changeRoute:function(e){if("string"!=typeof e)throw new TypeError("Expected string for app.changeRoute(path)");"history"===y?(window.history.pushState(null,null,e),V()):window.location.hash=0===e.indexOf("#")?e:"#"+e},pushStateClick:function(e){if(!0!==e.ctrlKey&&!e.metaKey)return e.preventDefault(),e.stopPropagation(),e.currentTarget.href?h.changeRoute(e.currentTarget.href):console.error("app.pushStateClick() called for an unknown link"),!1},addPage:function(e,t){var o,r=["onRouteLoad","onBeforeRender","onRendered","onRouteUnload"],n=(l(e,"string","name","app.addPage()"),i(e,"name","app.addPage()"),!1);if("object"==typeof t)o=t,n=!0;else{if("function"!=typeof t||"class"!==t.toString().substring(0,5))throw new TypeError("Page ["+e+"] must be defined as an object or a class when the function app.addPage() is called");o=t.prototype}return T(o,e,"page",r),r.pop(),S(o,e,"page",r),n&&s(t.model,"page."+e+".model","app.addPage()"),d(this.pages,"app.pages",e),this.pages[e]=t,this},addPlugin:function(e,t){function o(){"function"==typeof this.onRouteUnload&&this.onRouteUnload(),this.onRendered()}if(l(e,"string","name","app.addPlugin()"),i(e,"name","app.addPlugin()"),d(this.plugins,"app.plugins",e),"function"==typeof(t="function"==typeof t&&"class"===t.toString().substring(0,5)?new t:t))return this.plugins[e]={onRendered:t,reload:o},this;var r=["onRouteLoad","onBeforeRender","onRendered","onRouteUnload"];return l(t,"object","plugin","app.addPlugin()"),T(t,e,"plugin",r),r.pop(),S(t,e,"plugin",r),void 0===t.reload&&(t.reload=o),this.plugins[e]=t,this},addControl:function(e,t){if(l(e,"string","name","app.addControl()"),i(e,"name","app.addControl()"),e!==e.toLowerCase())throw new TypeError("Control names must be all lower-case. [app.addControl()] was called with: ["+e+"]");if(-1===e.indexOf("-"))throw new TypeError("Control names must contain a dash [-] character. [app.addControl()] was called with: ["+e+"]");if(-1!==e.indexOf(" "))throw new TypeError("Control names cannot contain a space. [app.addControl()] was called with: ["+e+"]");if(!1!==/[&<>"'/]/.test(e))throw new TypeError("Control names cannot contain HTML characters that need to be escaped. Invalid characters are [& < > \" ' /]. [app.addControl()] was called with: ["+e+"]");l(t,"object","control","app.addControl()"),void 0!==t.css&&l(t.css,"string","control.css","app.addControl()");var o=["onLoad","html","onUnload"];return S(t,e,"control",o),T(t,e,"control",o),o.pop(),S(t,e,"control",o),d(this.controls,"app.controls",e),this.controls[e]=t,this},addModel:function(e,t){return l(e,"string","name","app.addModel()"),i(e,"name","app.addModel()"),l(t,"object","model","app.addModel()"),d(this.models,"app.models",e),this.models[e]=t,this},addController:function(t){var e,o=["onRouteLoad","onBeforeRender","onRendered","onRouteUnload"];if(l(t,"object","controller","app.addController()"),l(t.path,"string","controller.path","app.addController()"),i(t.path,"controller.path","app.addController()"),this.controllers.forEach(function(e){if(e.path===t.path)throw new TypeError("[app.controllers(path="+t.path+")] is already defined")}),e="app.addController(path="+t.path+")",void 0===t.viewId)t.viewId=null;else{l(t.viewId,"string","controller.viewId",e),i(t.viewId,"controller.viewId",e);var r=t.viewId,n="controller.viewId",a=e;if(null===document.getElementById(r))throw new TypeError("An element was not found on the page with ["+n+"][id="+r+"] when the function "+a+" was called")}if(void 0===t.viewUrl?t.viewUrl=null:(l(t.viewUrl,"string","controller.viewUrl",e),i(t.viewUrl,"controller.viewUrl",e)),null!==t.viewId&&null!==t.viewUrl)throw new TypeError("A controller cannot have both [viewId] and [viewUrl] defined when calling "+e);if(void 0!==t.viewEngine){if(null===t.viewId&&null===t.viewUrl)throw new TypeError("When a controller uses the [viewEngine] property either [viewId] or [viewUrl] must also be defined when calling "+e);if(-1===p.indexOf(t.viewEngine))throw new TypeError("Invalid [viewEngine] property when calling "+e+". Valid values are: "+p.join(", "))}return null!==t.modelName&&void 0!==t.modelName&&(l(t.modelName,"string","controller.modelName",e),i(t.modelName,"controller.modelName",e),s(this.models[t.modelName],"app.models."+t.modelName,e)),null!==t.pageType&&void 0!==t.pageType&&(l(t.pageType,"string","controller.pageType",e),i(t.pageType,"controller.pageType",e)),T(t,t.path,"controller",o),null!==t.pageType&&void 0!==t.pageType||(o.pop(),o.push("viewId"),o.push("viewUrl"),S(t,t.path,"controller",o)),this.controllers.push(t),this},controller:function(e){for(var t=0,o=this.controllers.length;t or