mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 21:48:20 +02:00
Initial serialization in JS
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
<body>
|
||||
<script type="text/javascript" src="js/lib/underscore-min.js"></script>
|
||||
<script type="text/javascript" src="js/lib/d3.v2.js"></script>
|
||||
<script type="text/javascript" src="js/lib/jxon.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/iD/id.js"></script>
|
||||
<script type="text/javascript" src="js/iD/actions/UndoStack.js"></script>
|
||||
@@ -34,6 +35,7 @@
|
||||
|
||||
<script type="text/javascript" src="js/iD/Entity.js"></script>
|
||||
<script type="text/javascript" src="js/iD/GeoJSON.js"></script>
|
||||
<script type="text/javascript" src="js/iD/XML.js"></script>
|
||||
<script type="text/javascript" src="js/iD/Node.js"></script>
|
||||
<script type="text/javascript" src="js/iD/Relation.js"></script>
|
||||
<script type="text/javascript" src="js/iD/Way.js"></script>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
iD.XML = {
|
||||
mapping: function(entity) {
|
||||
if (this.mappings[entity.type]) {
|
||||
return this.mappings[entity.type](entity);
|
||||
}
|
||||
},
|
||||
mappings: {
|
||||
node: function(entity) {
|
||||
/*
|
||||
return {
|
||||
type: 'Feature',
|
||||
properties: entity.tags,
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [entity.lon, entity.lat]
|
||||
}
|
||||
};
|
||||
*/
|
||||
},
|
||||
way: function(entity) {
|
||||
return (new XMLSerializer()).serializeToString(
|
||||
JXON.unbuild({
|
||||
way: {
|
||||
'@id': entity.id,
|
||||
'nd': entity.children.map(function(e) {
|
||||
return {
|
||||
keyAttributes: {
|
||||
ref: e.id
|
||||
}
|
||||
};
|
||||
})
|
||||
}
|
||||
})).replace(/>/g,'>').
|
||||
replace(/</g,'<').
|
||||
replace(/"/g,'"');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -20,6 +20,15 @@ iD.Inspector = function(graph) {
|
||||
d.type + '/' + d.id)
|
||||
.text('OSM');
|
||||
|
||||
head.append('a')
|
||||
.attr('class', 'permalink')
|
||||
.attr('href', '#')
|
||||
.text('XML')
|
||||
.on('click', function() {
|
||||
d3.event.stopPropagation();
|
||||
iD.Util.codeWindow(iD.XML.mapping(graph.fetch(d.id)));
|
||||
});
|
||||
|
||||
head.append('a')
|
||||
.attr('class', 'permalink')
|
||||
.attr('href', '#')
|
||||
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
const JXON = new (function () {
|
||||
const
|
||||
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) {
|
||||
const
|
||||
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) */
|
||||
}
|
||||
}
|
||||
|
||||
const 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) {
|
||||
const
|
||||
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 */) {
|
||||
const _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) {
|
||||
const oNewDoc = document.implementation.createDocument("", "", null);
|
||||
loadObjTree(oNewDoc, oNewDoc, oObjTree);
|
||||
return oNewDoc;
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
// 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));
|
||||
Reference in New Issue
Block a user