Skip to content

Commit b4f4d5d

Browse files
committed
Convert JSON manipulation methods into XML ones
To be able to better manipulate the grid data, we'll always work with the XML grid, so all the manipulation methods now works with XML nodes instead of JSON ones.
1 parent 0c34130 commit b4f4d5d

File tree

2 files changed

+227
-200
lines changed

2 files changed

+227
-200
lines changed

app/Grid/Manipulator.js

Lines changed: 85 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,27 @@
33
var JXON = require('../../vendors/JXON.js');
44
var _ = require('lodash');
55

6-
/**
6+
/**
77
* Manipulates grid data
8+
*
89
* @namespace
910
*/
1011
var Manipulator = {
1112

13+
// Nodes types that can directly accept rows
1214
reGrid: /^(mainGrid|grid)$/,
15+
16+
// Allowed types of cell
1317
reType: /^(module|grid)$/,
1418

19+
// RegExp to match XML nodes that will always be converted as array in JSON
20+
reXMLNodesAsArray: /^(rows|cells)$/,
21+
1522
/**
1623
* Convert a Grid in JSON format to its XML representation
24+
*
1725
* @param {JSON} JSONGrid - The JSON Grid to represent in XML
26+
*
1827
* @returns {XML} - The XML representation of the JSON Grid
1928
*/
2029
JSONGridToXML: function(JSONGrid) {
@@ -23,7 +32,9 @@ var Manipulator = {
2332

2433
/**
2534
* Convert a Grid in XML format to its JSON representation
35+
*
2636
* @param {XML} XMLGrid - The XML Grid to represent in JSON
37+
*
2738
* @returns {JSON} - The JSON representation of the XML Grid
2839
*/
2940
XMLGridToJSON: function(XMLGrid) {
@@ -38,7 +49,9 @@ var Manipulator = {
3849

3950
/**
4051
* Render a Grid in JSON format to its stringified XML representation
52+
*
4153
* @param {JSON} JSONGrid - The JSON Grid to represent in a stringified XML
54+
*
4255
* @returns {string} - The stringified XML representation of the JSON Grid
4356
*/
4457
JSONGridToXMLString: function(JSONGrid) {
@@ -48,100 +61,120 @@ var Manipulator = {
4861

4962
/**
5063
* Convert a Grid in XML format to its stringified representation
64+
*
5165
* @param {XML} XMLGrid - The XML Grid to represent in in a stringified XML
66+
*
5267
* @returns {string} - The stringified XML representation of the XML Grid
5368
*/
5469
XMLGridToXMLString: function(XMLGrid) {
5570
return (new JXON.XMLSerializer()).serializeToString(XMLGrid);
5671
},
5772

5873
/**
59-
* Create a new grid from scratch
74+
* Create a new XML grid from scratch
75+
*
6076
* @param {string} name - The name of the new grid to create
6177
* @param {integer} [space=5] - The space between modules in the new grid
62-
* @return {JSON} - The JSON version of the new created grid
78+
*
79+
* @returns {XML} - The XML version of the new created grid
6380
*/
6481
createBaseGrid: function(name, space) {
65-
return {
82+
return this.JSONGridToXML({
6683
_name: name,
6784
_space: (space || 5) + 'px',
6885
_type: 'mainGrid',
6986
content: {}
70-
};
87+
});
7188
},
7289

7390
/**
74-
* Add a row to the given JSON grid node. Update the node in place.
91+
* Add a row to the given XML grid node. Update the node in place.
7592
* Will transform a non-grid node into a grid one, with a first row containing the actuel content
76-
* @param {object} node - The JSON grid node on which to add a row (should contain a "type")
77-
* @return {object} - The added row
93+
*
94+
* @param {XML} node - The XML grid node on which to add a row (should contain a "type", which must be "mainGrid" or "grid")
95+
*
96+
* @returns {XML} - The added row
7897
*/
7998
addRow: function(node) {
99+
// we insert the row in the content node
100+
var contentNode = node.querySelector(':scope > content');
80101
/* If this is not a grid node, create a first row this the actual
81102
* content in a cell */
82-
if (!this.reGrid.test(node._type)) {
83-
// keep node data to insert in cell later
84-
var cell_type = node._type;
85-
var cell_content = node.content;
103+
var nodeType = node.getAttribute('type');
104+
if (!this.reGrid.test(nodeType)) {
105+
// remove the node from its parent to move it into the future new cell
106+
node.removeChild(contentNode);
86107
// transform the current node into a grid one
87-
node._type = 'grid';
88-
node.content = {};
108+
node.setAttribute('type', 'grid');
109+
var newContentNode = node.ownerDocument.createElement('content');
110+
node.appendChild(newContentNode);
89111
// add a row to hold the cell with old node data
90-
var cell_row = this.addRow(node);
112+
var cellRow = this.addRow(node);
91113
// add the cell to hold the old node data
92-
var cell = this.addCell(cell_row, cell_type);
93-
cell.content = cell_content;
94-
}
95-
if (_.isUndefined(node.content.rows)) {
96-
node.content.rows = [];
97-
}
98-
var row = {};
99-
node.content.rows.push(row);
114+
var cell = this.addCell(cellRow, nodeType, contentNode);
115+
// it's here we'll attach the row
116+
contentNode = newContentNode;
117+
};
118+
var row = node.ownerDocument.createElement('rows');
119+
contentNode.appendChild(row);
100120
return row;
101121
},
102122

123+
124+
103125
/**
104-
* Add a cell to the given JSON grid row. Update the row in place.
105-
* @param {object} row - The JSON grid row on which to add a cell
106-
* @param {string} type - The type of cell to add: 'grid' or 'module'
107-
* @return {object} - The added cell, with the type and an empty 'content' object
126+
* Add a cell to the given XML grid row. Update the row in place.
127+
*
128+
* @param {XML} row - The XML grid row on which to add a cell
129+
* @param {string} type - The type of cell to add: "grid" or "module"
130+
* @param {XML} [contentNode] - The XML "content" node to insert in the cell.
131+
* If not given, a new empty "content" node will be created.
132+
*
133+
* @returns {XML} - The added cell (XML), with the type and a content.
108134
*/
109-
addCell: function(row, type) {
135+
addCell: function(row, type, contentNode) {
110136
if (!this.reType.test(type)) {
111137
throw "Invalid type <" + type + ">. Should be 'grid' or 'module'";
112138
}
113-
if (_.isUndefined(row.cells)) {
114-
row.cells = [];
139+
var cell = row.ownerDocument.createElement('cells');
140+
cell.setAttribute('type', type);
141+
if (!contentNode) {
142+
contentNode = row.ownerDocument.createElement('content');
115143
}
116-
var cell = {
117-
_type: type,
118-
content: {}
119-
};
120-
row.cells.push(cell);
144+
cell.appendChild(contentNode);
145+
row.appendChild(cell);
121146
return cell;
122147
},
123148

124149
/**
125-
* Convert a JSON node with only one row with only one cell, into a node without rows (only the type and content are copied)
126-
* row but only the content of the cell
127-
* @param {object} node - The JSON grid node to clean
150+
* Convert a XML grid node with only one row with only one cell, into a node
151+
* without rows (only the type and content are copied) but only the content of the cell
152+
*
153+
* @param {XML} node - The JSON grid node to clean
154+
*
155+
* @returns {} - Returns nothing
128156
*/
129157
cleanNode: function(node) {
130-
if (node._type == 'grid'
131-
&& node.content.rows
132-
&& node.content.rows.length == 1
133-
&& (!node.content.rows[0].cells || node.content.rows[0].cells.length == 1)) {
134-
if (!node.content.rows[0].cells || node.content.rows[0].cells.length < 1) {
135-
// manage the case of a row with no cells
136-
node._type = 'unknown';
137-
node.content = {};
138-
} else {
139-
var cell = node.content.rows[0].cells.shift();
140-
node._type = cell._type;
141-
node.content = cell.content;
142-
}
158+
if (node.getAttribute('type') != 'grid') { return }
159+
160+
var contentNode = node.querySelector(':scope > content');
161+
var rows = contentNode.querySelectorAll(':scope > rows');
162+
163+
if (rows.length != 1) { return }
164+
165+
var cells = rows[0].querySelectorAll(':scope > cells');
166+
167+
if (!cells.length) {
168+
// in theory this should not happen (not having any cell)
169+
node.setAttribute('type', 'unknown');
170+
node.removeChild(contentNode);
171+
node.appendChild(node.ownerDocument.createElement('content'));
172+
} else if (cells.length == 1) {
173+
node.setAttribute('type', cells[0].getAttribute('type'));
174+
node.removeChild(contentNode);
175+
node.appendChild(cells[0].querySelector(':scope > content'));
143176
}
144-
},
177+
}
145178
};
146179

147180
window.Manipulator = Manipulator;

0 commit comments

Comments
 (0)