From b15338b964b5e2afdffd82d0a4a1a015041d5c31 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 5 Jul 2016 18:56:51 -0400 Subject: [PATCH 1/4] Use local jxon --- Makefile | 1 - index.html | 1 - js/lib/id/index.js | 143 +++++++++++++++++++++++++++++++ modules/core/connection.js | 1 + modules/modes/save.js | 1 + {js/lib => modules/util}/jxon.js | 3 +- test/index.html | 1 - 7 files changed, 147 insertions(+), 4 deletions(-) rename {js/lib => modules/util}/jxon.js (99%) diff --git a/Makefile b/Makefile index a5e68bcfd..c9f42b8cb 100644 --- a/Makefile +++ b/Makefile @@ -72,7 +72,6 @@ dist/iD.js: \ js/lib/d3.curtain.js \ js/lib/d3.value.js \ js/lib/diff3.js \ - js/lib/jxon.js \ js/lib/lodash.js \ js/id/start.js \ js/id/id.js \ diff --git a/index.html b/index.html index 3abdee528..1e95973ab 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,6 @@ - diff --git a/js/lib/id/index.js b/js/lib/id/index.js index 3f26856bf..62605ce67 100644 --- a/js/lib/id/index.js +++ b/js/lib/id/index.js @@ -4191,6 +4191,149 @@ var osmAuth = (index && typeof index === 'object' && 'default' in index ? index['default'] : index); + const JXON = new (function () { + var + sValueProp = "keyValue", sAttributesProp = "keyAttributes", sAttrPref = "@", /* you can customize these values */ + aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i; + + function parseText (sValue) { + if (rIsNull.test(sValue)) { return null; } + if (rIsBool.test(sValue)) { return sValue.toLowerCase() === "true"; } + if (isFinite(sValue)) { return parseFloat(sValue); } + if (isFinite(Date.parse(sValue))) { return new Date(sValue); } + return sValue; + } + + function EmptyTree () { } + EmptyTree.prototype.toString = function () { return "null"; }; + EmptyTree.prototype.valueOf = function () { return null; }; + + function objectify (vValue) { + return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue); + } + + function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) { + var + nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(), + bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2); + + var + sProp, vContent, nLength = 0, sCollectedTxt = "", + vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true; + + if (bChildren) { + for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) { + oNode = oParentNode.childNodes.item(nItem); + if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is "CDATASection" (4) */ + else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is "Text" (3) */ + else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is "Element" (1) */ + } + } + + var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt); + + if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; } + + for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) { + sProp = aCache[nElId].nodeName.toLowerCase(); + vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr); + if (vResult.hasOwnProperty(sProp)) { + if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; } + vResult[sProp].push(vContent); + } else { + vResult[sProp] = vContent; + nLength++; + } + } + + if (bAttributes) { + var + nAttrLen = oParentNode.attributes.length, + sAPrefix = bNesteAttr ? "" : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult; + + for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) { + oAttrib = oParentNode.attributes.item(nAttrib); + oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim()); + } + + if (bNesteAttr) { + if (bFreeze) { Object.freeze(oAttrParent); } + vResult[sAttributesProp] = oAttrParent; + nLength -= nAttrLen - 1; + } + } + + if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) { + vResult[sValueProp] = vBuiltVal; + } else if (!bHighVerb && nLength === 0 && sCollectedTxt) { + vResult = vBuiltVal; + } + + if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); } + + aCache.length = nLevelStart; + + return vResult; + } + + function loadObjTree (oXMLDoc, oParentEl, oParentObj) { + var vValue, oChild; + + if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) { + oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */ + } else if (oParentObj.constructor === Date) { + oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString())); + } + + for (var sName in oParentObj) { + vValue = oParentObj[sName]; + if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */ + if (sName === sValueProp) { + if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); } + } else if (sName === sAttributesProp) { /* verbosity level is 3 */ + for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); } + } else if (sName.charAt(0) === sAttrPref) { + oParentEl.setAttribute(sName.slice(1), vValue); + } else if (vValue.constructor === Array) { + for (var nItem = 0; nItem < vValue.length; nItem++) { + oChild = oXMLDoc.createElement(sName); + loadObjTree(oXMLDoc, oChild, vValue[nItem]); + oParentEl.appendChild(oChild); + } + } else { + oChild = oXMLDoc.createElement(sName); + if (vValue instanceof Object) { + loadObjTree(oXMLDoc, oChild, vValue); + } else if (vValue !== null && vValue !== true) { + oChild.appendChild(oXMLDoc.createTextNode(vValue.toString())); + } + oParentEl.appendChild(oChild); + } + } + } + + this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) { + var _nVerb = arguments.length > 1 && typeof nVerbosity === "number" ? nVerbosity & 3 : /* put here the default verbosity level: */ 1; + return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3); + }; + + this.unbuild = function (oObjTree) { + var oNewDoc = document.implementation.createDocument("", "", null); + loadObjTree(oNewDoc, oNewDoc, oObjTree); + return oNewDoc; + }; + + this.stringify = function (oObjTree) { + return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree)); + }; + })(); + + // var myObject = JXON.build(doc); + // we got our javascript object! try: alert(JSON.stringify(myObject)); + + // var newDoc = JXON.unbuild(myObject); + // we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc)); + function Connection(useHttps) { if (typeof useHttps !== 'boolean') { useHttps = window.location.protocol === 'https:'; diff --git a/modules/core/connection.js b/modules/core/connection.js index 8d138fd57..a8b509921 100644 --- a/modules/core/connection.js +++ b/modules/core/connection.js @@ -4,6 +4,7 @@ import { Relation } from './relation'; import { Node } from './node'; import { Extent } from '../geo/index'; import osmAuth from 'osm-auth'; +import { JXON } from '../util/jxon'; export function Connection(useHttps) { if (typeof useHttps !== 'boolean') { diff --git a/modules/modes/save.js b/modules/modes/save.js index 1fa2dc353..5e507f7f2 100644 --- a/modules/modes/save.js +++ b/modules/modes/save.js @@ -3,6 +3,7 @@ import { displayName, displayType } from '../util/index'; import { Browse } from './index'; import { DiscardTags, Noop, MergeRemoteChanges, Revert } from '../actions/index'; import { Commit, Loading, Success, Conflicts } from '../ui/index'; +import { JXON } from '../util/jxon'; export function Save(context) { var ui = Commit(context) diff --git a/js/lib/jxon.js b/modules/util/jxon.js similarity index 99% rename from js/lib/jxon.js rename to modules/util/jxon.js index ea29658d7..e29a5fa67 100644 --- a/js/lib/jxon.js +++ b/modules/util/jxon.js @@ -1,4 +1,4 @@ -var JXON = new (function () { +export const JXON = new (function () { var sValueProp = "keyValue", sAttributesProp = "keyAttributes", sAttrPref = "@", /* you can customize these values */ aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i; @@ -134,6 +134,7 @@ var JXON = new (function () { return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree)); }; })(); + // var myObject = JXON.build(doc); // we got our javascript object! try: alert(JSON.stringify(myObject)); diff --git a/test/index.html b/test/index.html index 54da88c65..1fd3d6bd3 100644 --- a/test/index.html +++ b/test/index.html @@ -24,7 +24,6 @@ - From 1ef83b925c361cff9401223d1fd431ddbb71f502 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 5 Jul 2016 19:12:33 -0400 Subject: [PATCH 2/4] Make JXON pass style check --- js/lib/id/index.js | 20 ++++++++++---------- modules/util/jxon.js | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/js/lib/id/index.js b/js/lib/id/index.js index 62605ce67..87556ac69 100644 --- a/js/lib/id/index.js +++ b/js/lib/id/index.js @@ -4193,19 +4193,19 @@ const JXON = new (function () { var - sValueProp = "keyValue", sAttributesProp = "keyAttributes", sAttrPref = "@", /* you can customize these values */ + sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */ aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i; function parseText (sValue) { if (rIsNull.test(sValue)) { return null; } - if (rIsBool.test(sValue)) { return sValue.toLowerCase() === "true"; } + if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; } if (isFinite(sValue)) { return parseFloat(sValue); } if (isFinite(Date.parse(sValue))) { return new Date(sValue); } return sValue; } function EmptyTree () { } - EmptyTree.prototype.toString = function () { return "null"; }; + EmptyTree.prototype.toString = function () { return 'null'; }; EmptyTree.prototype.valueOf = function () { return null; }; function objectify (vValue) { @@ -4218,15 +4218,15 @@ bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2); var - sProp, vContent, nLength = 0, sCollectedTxt = "", + sProp, vContent, nLength = 0, sCollectedTxt = '', vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true; if (bChildren) { for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) { oNode = oParentNode.childNodes.item(nItem); - if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is "CDATASection" (4) */ - else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is "Text" (3) */ - else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is "Element" (1) */ + if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */ + else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */ + else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */ } } @@ -4249,7 +4249,7 @@ if (bAttributes) { var nAttrLen = oParentNode.attributes.length, - sAPrefix = bNesteAttr ? "" : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult; + sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult; for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) { oAttrib = oParentNode.attributes.item(nAttrib); @@ -4313,12 +4313,12 @@ } this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) { - var _nVerb = arguments.length > 1 && typeof nVerbosity === "number" ? nVerbosity & 3 : /* put here the default verbosity level: */ 1; + var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1; return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3); }; this.unbuild = function (oObjTree) { - var oNewDoc = document.implementation.createDocument("", "", null); + var oNewDoc = document.implementation.createDocument('', '', null); loadObjTree(oNewDoc, oNewDoc, oObjTree); return oNewDoc; }; diff --git a/modules/util/jxon.js b/modules/util/jxon.js index e29a5fa67..14523d3b1 100644 --- a/modules/util/jxon.js +++ b/modules/util/jxon.js @@ -1,18 +1,18 @@ export const JXON = new (function () { var - sValueProp = "keyValue", sAttributesProp = "keyAttributes", sAttrPref = "@", /* you can customize these values */ + sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */ aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i; function parseText (sValue) { if (rIsNull.test(sValue)) { return null; } - if (rIsBool.test(sValue)) { return sValue.toLowerCase() === "true"; } + if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; } if (isFinite(sValue)) { return parseFloat(sValue); } if (isFinite(Date.parse(sValue))) { return new Date(sValue); } return sValue; } function EmptyTree () { } - EmptyTree.prototype.toString = function () { return "null"; }; + EmptyTree.prototype.toString = function () { return 'null'; }; EmptyTree.prototype.valueOf = function () { return null; }; function objectify (vValue) { @@ -25,15 +25,15 @@ export const JXON = new (function () { bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2); var - sProp, vContent, nLength = 0, sCollectedTxt = "", + sProp, vContent, nLength = 0, sCollectedTxt = '', vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true; if (bChildren) { for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) { oNode = oParentNode.childNodes.item(nItem); - if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is "CDATASection" (4) */ - else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is "Text" (3) */ - else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is "Element" (1) */ + if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */ + else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */ + else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */ } } @@ -56,7 +56,7 @@ export const JXON = new (function () { if (bAttributes) { var nAttrLen = oParentNode.attributes.length, - sAPrefix = bNesteAttr ? "" : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult; + sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult; for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) { oAttrib = oParentNode.attributes.item(nAttrib); @@ -120,12 +120,12 @@ export const JXON = new (function () { } this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) { - var _nVerb = arguments.length > 1 && typeof nVerbosity === "number" ? nVerbosity & 3 : /* put here the default verbosity level: */ 1; + var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1; return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3); }; this.unbuild = function (oObjTree) { - var oNewDoc = document.implementation.createDocument("", "", null); + var oNewDoc = document.implementation.createDocument('', '', null); loadObjTree(oNewDoc, oNewDoc, oObjTree); return oNewDoc; }; From d3348a87297f9daf28029162b8c583a1efc355cb Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 5 Jul 2016 19:13:25 -0400 Subject: [PATCH 3/4] Remove no longer used globals --- .eslintrc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.eslintrc b/.eslintrc index 46c4a8250..6c0f7c340 100644 --- a/.eslintrc +++ b/.eslintrc @@ -56,10 +56,6 @@ "t": false, "bootstrap": false, "Diff3": false, - "JXON": false, - "osmAuth": false, - "toGeoJSON": false, - "marked": false, "Mapillary": false, }, From ecea55ba00c821eea2889b188e8e390cf642d062 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 5 Jul 2016 21:44:00 -0400 Subject: [PATCH 4/4] Const is verboten --- js/lib/id/index.js | 2 +- modules/util/jxon.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/lib/id/index.js b/js/lib/id/index.js index 87556ac69..aedeaea74 100644 --- a/js/lib/id/index.js +++ b/js/lib/id/index.js @@ -4191,7 +4191,7 @@ var osmAuth = (index && typeof index === 'object' && 'default' in index ? index['default'] : index); - const JXON = new (function () { + var JXON = new (function () { var sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */ aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i; diff --git a/modules/util/jxon.js b/modules/util/jxon.js index 14523d3b1..714d06d9d 100644 --- a/modules/util/jxon.js +++ b/modules/util/jxon.js @@ -1,4 +1,4 @@ -export const JXON = new (function () { +export var JXON = new (function () { var sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */ aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;