From e31a8b8a52c7ed46580f0791f0e4556a198f1dd8 Mon Sep 17 00:00:00 2001 From: Brian Baker Date: Thu, 22 Jul 2021 13:27:42 -0600 Subject: [PATCH] fix: move isNativeDOMNode and other private utilities to their own files so they aren't included in the public API --- src/appHandlers.js | 5 +- src/constants/appHandlers.js | 2 +- src/container.js | 9 ++- src/utils/dom.js | 23 ++++++ src/{utils.js => utils/index.js} | 122 +------------------------------ src/utils/uri.js | 110 ++++++++++++++++++++++++++++ 6 files changed, 145 insertions(+), 126 deletions(-) create mode 100644 src/utils/dom.js rename src/{utils.js => utils/index.js} (56%) create mode 100644 src/utils/uri.js diff --git a/src/appHandlers.js b/src/appHandlers.js index b017b58a..1b5abbce 100644 --- a/src/appHandlers.js +++ b/src/appHandlers.js @@ -1,3 +1,4 @@ +import dom from './utils/dom'; import domify from 'domify'; import utils from './utils'; @@ -21,7 +22,7 @@ var _defaultMethods = { appRender: function(appConfig, appHtml) { // if no app root is defined use the app's outer most node - if(!utils.isNativeDOMNode(appConfig.root)) + if(!dom.isNativeNode(appConfig.root)) { appConfig.root = domify(appHtml); } @@ -63,7 +64,7 @@ var _createHandler = function(token, sNamespace, func_or_element, bDomNodeApprop var handler = { func: (typeof(func_or_element)) ? func_or_element : null, namespace: sNamespace, - domNode: (utils.isNativeDOMNode(func_or_element)) ? func_or_element : null + domNode: (dom.isNativeNode(func_or_element)) ? func_or_element : null }; if(!handler.func && !handler.domNode) diff --git a/src/constants/appHandlers.js b/src/constants/appHandlers.js index 0c7d8d2a..643562f8 100644 --- a/src/constants/appHandlers.js +++ b/src/constants/appHandlers.js @@ -82,7 +82,7 @@ module.exports = {             *       function(appConfig, appHtml)             *       {             *           // if no app root is defined use the app's outer most node -            *           if(!F2.isNativeDOMNode(appConfig.root)) +            *           if(!appConfig.root)             *           {             *               appConfig.root = domify(appHtml);                                            *           } diff --git a/src/container.js b/src/container.js index a573a69b..41c16664 100644 --- a/src/container.js +++ b/src/container.js @@ -3,6 +3,7 @@ import appClasses from './apps'; import classes from './classes'; import cloneDeep from 'lodash.clonedeep'; import constants from './constants'; +import dom from './utils/dom'; import domify from 'domify'; import events from './events'; import utils from './utils'; @@ -175,7 +176,7 @@ var _initContainerEvents = function() { */ var _isPlaceholderElement = function(node) { return ( - utils.isNativeDOMNode(node) && + dom.isNativeNode(node) && !_hasNonTextChildNodes(node) && !!node.getAttribute('data-f2-appid') && !!node.getAttribute('data-f2-manifesturl') @@ -529,7 +530,7 @@ var _loadApps = function(appConfigs, appManifest) { appConfigs[i] // the app config ); - if (!utils.isNativeDOMNode(root)) { + if (!dom.isNativeNode(root)) { throw ('App root for ' + appId + ' must be a native DOM element. Check your AppHandler callbacks to ensure you have set app root to a native DOM element.'); } } @@ -698,7 +699,7 @@ export default { } }; - if (!!parentNode && !utils.isNativeDOMNode(parentNode)) { + if (!!parentNode && !dom.isNativeNode(parentNode)) { throw ('"parentNode" must be null or a DOM node'); } @@ -886,7 +887,7 @@ export default { // If the root property is defined then this app is considered to be preloaded and we will // run it through that logic. if (a.root && !_isPlaceholderElement(a.root)) { - if ((!a.root && typeof(a.root) != 'string') && !utils.isNativeDOMNode(a.root)) { + if ((!a.root && typeof(a.root) != 'string') && !dom.isNativeNode(a.root)) { utils.log('AppConfig invalid for pre-load, not a valid string and not dom node'); utils.log('AppConfig instance:', a); throw ('Preloaded appConfig.root property must be a native dom node or a string representing a sizzle selector. Please check your inputs and try again.'); diff --git a/src/utils/dom.js b/src/utils/dom.js new file mode 100644 index 00000000..7693e041 --- /dev/null +++ b/src/utils/dom.js @@ -0,0 +1,23 @@ +/** + * Utility method to determine whether or not the argument passed in is or is not a native dom node. + * @method isNativeNode + * @param {object} testObject The object you want to check as native dom node. + * @return {bool} Returns true if the object passed is a native dom node. + */ +function isNativeNode(testObject) { + var bIsNode = ( + typeof Node === 'object' ? testObject instanceof Node : + testObject && typeof testObject === 'object' && typeof testObject.nodeType === 'number' && typeof testObject.nodeName === 'string' + ); + + var bIsElement = ( + typeof HTMLElement === 'object' ? testObject instanceof HTMLElement : //DOM2 + testObject && typeof testObject === 'object' && testObject.nodeType === 1 && typeof testObject.nodeName === 'string' + ); + + return (bIsNode || bIsElement); +} + +export default { + isNativeNode +}; \ No newline at end of file diff --git a/src/utils.js b/src/utils/index.js similarity index 56% rename from src/utils.js rename to src/utils/index.js index a003bd38..c0f67fd8 100644 --- a/src/utils.js +++ b/src/utils/index.js @@ -1,64 +1,4 @@ -/** - * Abosolutizes a relative URL - * @method _absolutizeURI - * @private - * @param {e.g., location.href} base - * @param {URL to absolutize} href - * @return {string} URL - * Source: https://gist.github.com/Yaffle/1088850 - * Tests: http://skew.org/uri/uri_tests.html - */ - var _absolutizeURI = function(base, href) {// RFC 3986 - - function removeDotSegments(input) { - var output = []; - input.replace(/^(\.\.?(\/|$))+/, '') - .replace(/\/(\.(\/|$))+/g, '/') - .replace(/\/\.\.$/, '/../') - .replace(/\/?[^\/]*/g, function (p) { - if (p === '/..') { - output.pop(); - } else { - output.push(p); - } - }); - return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); - } - - href = _parseURI(href || ''); - base = _parseURI(base || ''); - - return !href || !base ? null : (href.protocol || base.protocol) + - (href.protocol || href.authority ? href.authority : base.authority) + - removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) + - (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + - href.hash; -}; - -/** - * Parses URI - * @method _parseURI - * @private - * @param {The URL to parse} url - * @return {Parsed URL} string - * Source: https://gist.github.com/Yaffle/1088850 - * Tests: http://skew.org/uri/uri_tests.html - */ -var _parseURI = function(url) { - var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); - // authority = '//' + user + ':' + pass '@' + hostname + ':' port - return (m ? { - href : m[0] || '', - protocol : m[1] || '', - authority: m[2] || '', - host : m[3] || '', - hostname : m[4] || '', - port : m[5] || '', - pathname : m[6] || '', - search : m[7] || '', - hash : m[8] || '' - } : null); -}; +import uri from './uri'; export default { /** @@ -127,67 +67,11 @@ export default { }, /** * Tests a URL to see if it's on the same domain (local) or not - * @method isLocalRequest + * @method isLocal * @param {URL to test} url * @return {bool} Whether the URL is local or not - * Derived from: https://github.com/jquery/jquery/blob/master/src/ajax.js */ - isLocalRequest: function(url){ - var rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, - urlLower = url.toLowerCase(), - parts = rurl.exec( urlLower ), - ajaxLocation, - ajaxLocParts; - - try { - ajaxLocation = location.href; - } catch( e ) { - // Use the href attribute of an A element - // since IE will modify it given document.location - ajaxLocation = document.createElement('a'); - ajaxLocation.href = ''; - ajaxLocation = ajaxLocation.href; - } - - ajaxLocation = ajaxLocation.toLowerCase(); - - // uh oh, the url must be relative - // make it fully qualified and re-regex url - if (!parts){ - urlLower = _absolutizeURI(ajaxLocation,urlLower).toLowerCase(); - parts = rurl.exec( urlLower ); - } - - // Segment location into parts - ajaxLocParts = rurl.exec( ajaxLocation ) || []; - - // do hostname and protocol and port of manifest URL match location.href? (a "local" request on the same domain) - var matched = !(parts && - (parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || - (parts[ 3 ] || (parts[ 1 ] === 'http:' ? '80' : '443')) !== - (ajaxLocParts[ 3 ] || (ajaxLocParts[ 1 ] === 'http:' ? '80' : '443')))); - - return matched; - }, - /** - * Utility method to determine whether or not the argument passed in is or is not a native dom node. - * @method isNativeDOMNode - * @param {object} testObject The object you want to check as native dom node. - * @return {bool} Returns true if the object passed is a native dom node. - */ - isNativeDOMNode: function(testObject) { - var bIsNode = ( - typeof Node === 'object' ? testObject instanceof Node : - testObject && typeof testObject === 'object' && typeof testObject.nodeType === 'number' && typeof testObject.nodeName === 'string' - ); - - var bIsElement = ( - typeof HTMLElement === 'object' ? testObject instanceof HTMLElement : //DOM2 - testObject && typeof testObject === 'object' && testObject.nodeType === 1 && typeof testObject.nodeName === 'string' - ); - - return (bIsNode || bIsElement); - }, + isLocalRequest: uri.isLocal, /** * A utility logging function to write messages or objects to the browser console. This is a proxy for the [`console` API](https://developers.google.com/chrome-developer-tools/docs/console). * @method log diff --git a/src/utils/uri.js b/src/utils/uri.js new file mode 100644 index 00000000..15f0a743 --- /dev/null +++ b/src/utils/uri.js @@ -0,0 +1,110 @@ +/** + * Tests a URL to see if it's on the same domain (local) or not + * @method isLocal + * @param {URL to test} url + * @return {bool} Whether the URL is local or not + * Derived from: https://github.com/jquery/jquery/blob/master/src/ajax.js + */ +function isLocal(url){ + var rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + urlLower = url.toLowerCase(), + parts = rurl.exec( urlLower ), + ajaxLocation, + ajaxLocParts; + + try { + ajaxLocation = location.href; + } catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement('a'); + ajaxLocation.href = ''; + ajaxLocation = ajaxLocation.href; + } + + ajaxLocation = ajaxLocation.toLowerCase(); + + // uh oh, the url must be relative + // make it fully qualified and re-regex url + if (!parts){ + urlLower = toAbsolute(ajaxLocation,urlLower).toLowerCase(); + parts = rurl.exec( urlLower ); + } + + // Segment location into parts + ajaxLocParts = rurl.exec( ajaxLocation ) || []; + + // do hostname and protocol and port of manifest URL match location.href? (a "local" request on the same domain) + var matched = !(parts && + (parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + (parts[ 3 ] || (parts[ 1 ] === 'http:' ? '80' : '443')) !== + (ajaxLocParts[ 3 ] || (ajaxLocParts[ 1 ] === 'http:' ? '80' : '443')))); + + return matched; +} + +/** + * Parses URI + * @method parse + * @param {The URL to parse} url + * @return {Parsed URL} string + * Source: https://gist.github.com/Yaffle/1088850 + * Tests: http://skew.org/uri/uri_tests.html + */ +function parse(url) { + var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/); + // authority = '//' + user + ':' + pass '@' + hostname + ':' port + return (m ? { + href : m[0] || '', + protocol : m[1] || '', + authority: m[2] || '', + host : m[3] || '', + hostname : m[4] || '', + port : m[5] || '', + pathname : m[6] || '', + search : m[7] || '', + hash : m[8] || '' + } : null); +} + +/** + * Abosolutizes a relative URL + * @method toAbsolute + * @param {e.g., location.href} base + * @param {URL to absolutize} href + * @return {string} URL + * Source: https://gist.github.com/Yaffle/1088850 + * Tests: http://skew.org/uri/uri_tests.html + */ +function toAbsolute(base, href) {// RFC 3986 + + function removeDotSegments(input) { + var output = []; + input.replace(/^(\.\.?(\/|$))+/, '') + .replace(/\/(\.(\/|$))+/g, '/') + .replace(/\/\.\.$/, '/../') + .replace(/\/?[^\/]*/g, function (p) { + if (p === '/..') { + output.pop(); + } else { + output.push(p); + } + }); + return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : ''); + } + + href = parse(href || ''); + base = parse(base || ''); + + return !href || !base ? null : (href.protocol || base.protocol) + + (href.protocol || href.authority ? href.authority : base.authority) + + removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) + + (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) + + href.hash; +} + +export default { + isLocal, + parse, + toAbsolute +}; \ No newline at end of file