3
3
var JXON = require ( '../../vendors/JXON.js' ) ;
4
4
var _ = require ( 'lodash' ) ;
5
5
6
- /**
6
+ /**
7
7
* Manipulates grid data
8
+ *
8
9
* @namespace
9
10
*/
10
11
var Manipulator = {
11
12
13
+ // Nodes types that can directly accept rows
12
14
reGrid : / ^ ( m a i n G r i d | g r i d ) $ / ,
15
+
16
+ // Allowed types of cell
13
17
reType : / ^ ( m o d u l e | g r i d ) $ / ,
14
18
19
+ // RegExp to match XML nodes that will always be converted as array in JSON
20
+ reXMLNodesAsArray : / ^ ( r o w s | c e l l s ) $ / ,
21
+
15
22
/**
16
23
* Convert a Grid in JSON format to its XML representation
24
+ *
17
25
* @param {JSON } JSONGrid - The JSON Grid to represent in XML
26
+ *
18
27
* @returns {XML } - The XML representation of the JSON Grid
19
28
*/
20
29
JSONGridToXML : function ( JSONGrid ) {
@@ -23,7 +32,9 @@ var Manipulator = {
23
32
24
33
/**
25
34
* Convert a Grid in XML format to its JSON representation
35
+ *
26
36
* @param {XML } XMLGrid - The XML Grid to represent in JSON
37
+ *
27
38
* @returns {JSON } - The JSON representation of the XML Grid
28
39
*/
29
40
XMLGridToJSON : function ( XMLGrid ) {
@@ -38,7 +49,9 @@ var Manipulator = {
38
49
39
50
/**
40
51
* Render a Grid in JSON format to its stringified XML representation
52
+ *
41
53
* @param {JSON } JSONGrid - The JSON Grid to represent in a stringified XML
54
+ *
42
55
* @returns {string } - The stringified XML representation of the JSON Grid
43
56
*/
44
57
JSONGridToXMLString : function ( JSONGrid ) {
@@ -48,100 +61,120 @@ var Manipulator = {
48
61
49
62
/**
50
63
* Convert a Grid in XML format to its stringified representation
64
+ *
51
65
* @param {XML } XMLGrid - The XML Grid to represent in in a stringified XML
66
+ *
52
67
* @returns {string } - The stringified XML representation of the XML Grid
53
68
*/
54
69
XMLGridToXMLString : function ( XMLGrid ) {
55
70
return ( new JXON . XMLSerializer ( ) ) . serializeToString ( XMLGrid ) ;
56
71
} ,
57
72
58
73
/**
59
- * Create a new grid from scratch
74
+ * Create a new XML grid from scratch
75
+ *
60
76
* @param {string } name - The name of the new grid to create
61
77
* @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
63
80
*/
64
81
createBaseGrid : function ( name , space ) {
65
- return {
82
+ return this . JSONGridToXML ( {
66
83
_name : name ,
67
84
_space : ( space || 5 ) + 'px' ,
68
85
_type : 'mainGrid' ,
69
86
content : { }
70
- } ;
87
+ } ) ;
71
88
} ,
72
89
73
90
/**
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.
75
92
* 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
78
97
*/
79
98
addRow : function ( node ) {
99
+ // we insert the row in the content node
100
+ var contentNode = node . querySelector ( ':scope > content' ) ;
80
101
/* If this is not a grid node, create a first row this the actual
81
102
* 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 ) ;
86
107
// 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 ) ;
89
111
// add a row to hold the cell with old node data
90
- var cell_row = this . addRow ( node ) ;
112
+ var cellRow = this . addRow ( node ) ;
91
113
// 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 ) ;
100
120
return row ;
101
121
} ,
102
122
123
+
124
+
103
125
/**
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.
108
134
*/
109
- addCell : function ( row , type ) {
135
+ addCell : function ( row , type , contentNode ) {
110
136
if ( ! this . reType . test ( type ) ) {
111
137
throw "Invalid type <" + type + ">. Should be 'grid' or 'module'" ;
112
138
}
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' ) ;
115
143
}
116
- var cell = {
117
- _type : type ,
118
- content : { }
119
- } ;
120
- row . cells . push ( cell ) ;
144
+ cell . appendChild ( contentNode ) ;
145
+ row . appendChild ( cell ) ;
121
146
return cell ;
122
147
} ,
123
148
124
149
/**
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
128
156
*/
129
157
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' ) ) ;
143
176
}
144
- } ,
177
+ }
145
178
} ;
146
179
147
180
window . Manipulator = Manipulator ;
0 commit comments