spud_core 0.7.5 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. data/app/assets/javascripts/spud/admin/application.js +8 -11
  2. data/app/assets/libs/bootstrap/css/bootstrap-responsive.css +686 -0
  3. data/app/assets/libs/bootstrap/css/bootstrap-responsive.min.css +12 -0
  4. data/app/assets/libs/bootstrap/css/bootstrap.css +3990 -0
  5. data/app/assets/libs/bootstrap/css/bootstrap.min.css +689 -0
  6. data/app/assets/libs/bootstrap/img/glyphicons-halflings-white.png +0 -0
  7. data/app/assets/libs/bootstrap/img/glyphicons-halflings.png +0 -0
  8. data/app/assets/libs/bootstrap/js/bootstrap.js +1726 -0
  9. data/app/assets/libs/bootstrap/js/bootstrap.min.js +6 -0
  10. data/app/assets/stylesheets/spud/admin/application.css +14 -120
  11. data/app/controllers/spud/application_controller.rb +9 -1
  12. data/app/controllers/spud/users_controller.rb +1 -1
  13. data/app/helpers/spud/admin/application_helper.rb +2 -2
  14. data/app/models/spud_user.rb +1 -1
  15. data/app/views/spud/admin/users/_edit.html.erb +4 -6
  16. data/app/views/spud/admin/users/_form.html.erb +68 -31
  17. data/app/views/spud/admin/users/_new.html.erb +5 -6
  18. data/app/views/spud/admin/users/index.html.erb +1 -1
  19. data/app/views/spud/setup/index.html.erb +36 -18
  20. data/app/views/spud/users/_form.html.erb +48 -24
  21. data/app/views/spud/users/settings.html.erb +4 -6
  22. data/db/migrate/20120327124229_add_time_zone_to_spud_user.rb +6 -0
  23. data/lib/spud_core/engine.rb +14 -13
  24. data/lib/spud_core/version.rb +1 -1
  25. data/lib/spud_core.rb +3 -4
  26. data/test/dummy/log/test.log +974 -0
  27. metadata +47 -135
  28. data/app/assets/javascripts/spud/admin/settings.js +0 -2
  29. data/app/assets/javascripts/spud/admin/users.js +0 -2
  30. data/app/assets/javascripts/spud/setup.js +0 -2
  31. data/app/assets/javascripts/spud/sitemaps.js +0 -2
  32. data/app/assets/javascripts/spud/user_sessions.js +0 -2
  33. data/app/assets/javascripts/spud/users.js +0 -2
  34. data/app/assets/javascripts/wymeditor/iframe/default/lbl-article.png +0 -0
  35. data/app/assets/javascripts/wymeditor/iframe/default/lbl-aside.png +0 -0
  36. data/app/assets/javascripts/wymeditor/iframe/default/lbl-blockquote.png +0 -0
  37. data/app/assets/javascripts/wymeditor/iframe/default/lbl-command.png +0 -0
  38. data/app/assets/javascripts/wymeditor/iframe/default/lbl-details.png +0 -0
  39. data/app/assets/javascripts/wymeditor/iframe/default/lbl-figcaption.png +0 -0
  40. data/app/assets/javascripts/wymeditor/iframe/default/lbl-figure.png +0 -0
  41. data/app/assets/javascripts/wymeditor/iframe/default/lbl-footer.png +0 -0
  42. data/app/assets/javascripts/wymeditor/iframe/default/lbl-h1.png +0 -0
  43. data/app/assets/javascripts/wymeditor/iframe/default/lbl-h2.png +0 -0
  44. data/app/assets/javascripts/wymeditor/iframe/default/lbl-h3.png +0 -0
  45. data/app/assets/javascripts/wymeditor/iframe/default/lbl-h4.png +0 -0
  46. data/app/assets/javascripts/wymeditor/iframe/default/lbl-h5.png +0 -0
  47. data/app/assets/javascripts/wymeditor/iframe/default/lbl-h6.png +0 -0
  48. data/app/assets/javascripts/wymeditor/iframe/default/lbl-header.png +0 -0
  49. data/app/assets/javascripts/wymeditor/iframe/default/lbl-hgroup.png +0 -0
  50. data/app/assets/javascripts/wymeditor/iframe/default/lbl-mark.png +0 -0
  51. data/app/assets/javascripts/wymeditor/iframe/default/lbl-meter.png +0 -0
  52. data/app/assets/javascripts/wymeditor/iframe/default/lbl-nav.png +0 -0
  53. data/app/assets/javascripts/wymeditor/iframe/default/lbl-p.png +0 -0
  54. data/app/assets/javascripts/wymeditor/iframe/default/lbl-pre.png +0 -0
  55. data/app/assets/javascripts/wymeditor/iframe/default/lbl-progress.png +0 -0
  56. data/app/assets/javascripts/wymeditor/iframe/default/lbl-rp.png +0 -0
  57. data/app/assets/javascripts/wymeditor/iframe/default/lbl-rt.png +0 -0
  58. data/app/assets/javascripts/wymeditor/iframe/default/lbl-ruby.png +0 -0
  59. data/app/assets/javascripts/wymeditor/iframe/default/lbl-section.png +0 -0
  60. data/app/assets/javascripts/wymeditor/iframe/default/lbl-summary.png +0 -0
  61. data/app/assets/javascripts/wymeditor/iframe/default/lbl-time.png +0 -0
  62. data/app/assets/javascripts/wymeditor/iframe/default/readme.md +0 -1
  63. data/app/assets/javascripts/wymeditor/iframe/default/wymiframe.css +0 -91
  64. data/app/assets/javascripts/wymeditor/iframe/default/wymiframe.html +0 -26
  65. data/app/assets/javascripts/wymeditor/jquery.wymeditor.js +0 -9983
  66. data/app/assets/javascripts/wymeditor/jquery.wymeditor.min.js +0 -34
  67. data/app/assets/javascripts/wymeditor/lang/bg.js +0 -45
  68. data/app/assets/javascripts/wymeditor/lang/ca.js +0 -45
  69. data/app/assets/javascripts/wymeditor/lang/cs.js +0 -45
  70. data/app/assets/javascripts/wymeditor/lang/cy.js +0 -45
  71. data/app/assets/javascripts/wymeditor/lang/de.js +0 -45
  72. data/app/assets/javascripts/wymeditor/lang/en.js +0 -45
  73. data/app/assets/javascripts/wymeditor/lang/es.js +0 -45
  74. data/app/assets/javascripts/wymeditor/lang/fa.js +0 -46
  75. data/app/assets/javascripts/wymeditor/lang/fi.js +0 -44
  76. data/app/assets/javascripts/wymeditor/lang/fr.js +0 -45
  77. data/app/assets/javascripts/wymeditor/lang/gl.js +0 -45
  78. data/app/assets/javascripts/wymeditor/lang/he.js +0 -45
  79. data/app/assets/javascripts/wymeditor/lang/hr.js +0 -45
  80. data/app/assets/javascripts/wymeditor/lang/hu.js +0 -45
  81. data/app/assets/javascripts/wymeditor/lang/it.js +0 -45
  82. data/app/assets/javascripts/wymeditor/lang/ja.js +0 -44
  83. data/app/assets/javascripts/wymeditor/lang/lt.js +0 -45
  84. data/app/assets/javascripts/wymeditor/lang/nb.js +0 -45
  85. data/app/assets/javascripts/wymeditor/lang/nl.js +0 -45
  86. data/app/assets/javascripts/wymeditor/lang/nn.js +0 -45
  87. data/app/assets/javascripts/wymeditor/lang/pl.js +0 -45
  88. data/app/assets/javascripts/wymeditor/lang/pt-br.js +0 -45
  89. data/app/assets/javascripts/wymeditor/lang/pt.js +0 -45
  90. data/app/assets/javascripts/wymeditor/lang/ru.js +0 -45
  91. data/app/assets/javascripts/wymeditor/lang/sv.js +0 -46
  92. data/app/assets/javascripts/wymeditor/lang/tr.js +0 -45
  93. data/app/assets/javascripts/wymeditor/lang/zh_cn.js +0 -47
  94. data/app/assets/javascripts/wymeditor/plugins/embed/jquery.wymeditor.embed.js +0 -82
  95. data/app/assets/javascripts/wymeditor/plugins/fullscreen/icon_fullscreen.gif +0 -0
  96. data/app/assets/javascripts/wymeditor/plugins/fullscreen/jquery.wymeditor.fullscreen.js +0 -124
  97. data/app/assets/javascripts/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js +0 -49
  98. data/app/assets/javascripts/wymeditor/plugins/list/jquery.wymeditor.list.js +0 -60
  99. data/app/assets/javascripts/wymeditor/plugins/rdfa/jquery.wymeditor.rdfa.js +0 -186
  100. data/app/assets/javascripts/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js +0 -77
  101. data/app/assets/javascripts/wymeditor/plugins/resizable/readme.txt +0 -124
  102. data/app/assets/javascripts/wymeditor/plugins/table/jquery.wymeditor.table.js +0 -721
  103. data/app/assets/javascripts/wymeditor/plugins/table/table_delete_column.png +0 -0
  104. data/app/assets/javascripts/wymeditor/plugins/table/table_delete_row.png +0 -0
  105. data/app/assets/javascripts/wymeditor/plugins/table/table_insert_column.png +0 -0
  106. data/app/assets/javascripts/wymeditor/plugins/table/table_insert_row.png +0 -0
  107. data/app/assets/javascripts/wymeditor/plugins/table/table_join_row.png +0 -0
  108. data/app/assets/javascripts/wymeditor/plugins/tidy/README +0 -19
  109. data/app/assets/javascripts/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js +0 -78
  110. data/app/assets/javascripts/wymeditor/plugins/tidy/tidy.php +0 -58
  111. data/app/assets/javascripts/wymeditor/plugins/tidy/wand.png +0 -0
  112. data/app/assets/javascripts/wymeditor/skins/compact/icons.png +0 -0
  113. data/app/assets/javascripts/wymeditor/skins/compact/skin.css +0 -134
  114. data/app/assets/javascripts/wymeditor/skins/compact/skin.js +0 -37
  115. data/app/assets/javascripts/wymeditor/skins/default/icons.png +0 -0
  116. data/app/assets/javascripts/wymeditor/skins/default/skin.css +0 -133
  117. data/app/assets/javascripts/wymeditor/skins/default/skin.js +0 -40
  118. data/app/assets/javascripts/wymeditor/skins/minimal/images/bg.header.gif +0 -0
  119. data/app/assets/javascripts/wymeditor/skins/minimal/images/bg.selector.silver.gif +0 -0
  120. data/app/assets/javascripts/wymeditor/skins/minimal/images/bg.wymeditor.png +0 -0
  121. data/app/assets/javascripts/wymeditor/skins/minimal/images/icons.silver.gif +0 -0
  122. data/app/assets/javascripts/wymeditor/skins/minimal/skin.css +0 -131
  123. data/app/assets/javascripts/wymeditor/skins/minimal/skin.js +0 -30
  124. data/app/assets/javascripts/wymeditor/skins/silver/COPYING +0 -674
  125. data/app/assets/javascripts/wymeditor/skins/silver/README +0 -27
  126. data/app/assets/javascripts/wymeditor/skins/silver/images/bg.header.gif +0 -0
  127. data/app/assets/javascripts/wymeditor/skins/silver/images/bg.selector.silver.gif +0 -0
  128. data/app/assets/javascripts/wymeditor/skins/silver/images/bg.wymeditor.png +0 -0
  129. data/app/assets/javascripts/wymeditor/skins/silver/images/icons.silver.gif +0 -0
  130. data/app/assets/javascripts/wymeditor/skins/silver/skin.css +0 -297
  131. data/app/assets/javascripts/wymeditor/skins/silver/skin.js +0 -61
  132. data/app/assets/javascripts/wymeditor/skins/twopanels/icons.png +0 -0
  133. data/app/assets/javascripts/wymeditor/skins/twopanels/skin.css +0 -134
  134. data/app/assets/javascripts/wymeditor/skins/twopanels/skin.js +0 -39
  135. data/app/assets/javascripts/wymeditor/skins/wymeditor_icon.png +0 -0
@@ -1,721 +0,0 @@
1
- /**
2
- * Copyright (c) 2011 PolicyStat LLC.
3
- * MIT licensed (MIT-license.txt)
4
- *
5
- * @author Wes Winham (winhamwr@gmail.com)
6
- */
7
-
8
- // Fugue icons by Yusuke Kamiyamane http://p.yusukekamiyamane.com/
9
- // and licensed under Creative Commons Attribution
10
-
11
- /**
12
- * A Table editing plugin that gives the user ability to add and remove
13
- * rows and columns as well as merge rows and columns.
14
- *
15
- * @param options A configuration object.
16
- * @param wym The WYMeditor instance to which the TableEditor should attach.
17
- * @class
18
- */
19
- function TableEditor(options, wym) {
20
- options = jQuery.extend({
21
- sMergeRowButtonHtml: String() +
22
- '<li class="wym_tools_merge_row">' +
23
- '<a name="merge_row" href="#" title="Merge Cells" ' +
24
- 'style="background-image: ' +
25
- "url('" + wym._options.basePath +
26
- "plugins/table/table_join_row.png')" + '">' +
27
- 'Merge Table Row' +
28
- '</a>' +
29
- '</li>',
30
-
31
- sMergeRowButtonSelector: "li.wym_tools_merge_row a",
32
-
33
- sAddRowButtonHtml: String() +
34
- "<li class='wym_tools_add_row'>" +
35
- "<a name='add_row' href='#' " +
36
- "title='Add Row' " +
37
- "style='background-image:" +
38
- " url(" + wym._options.basePath +
39
- "plugins/table/table_insert_row.png)'>" +
40
- "Add Table Row" +
41
- "</a>" +
42
- "</li>",
43
- sAddRowButtonSelector: "li.wym_tools_add_row a",
44
-
45
- sRemoveRowButtonHtml: String() +
46
- "<li class='wym_tools_remove_row'>" +
47
- "<a name='remove_row' href='#' " +
48
- "title='Remove Row' " +
49
- "style='background-image: " +
50
- "url(" + wym._options.basePath +
51
- "plugins/table/table_delete_row.png)'>" +
52
- "Remove Table Row" +
53
- "</a>" +
54
- "</li>",
55
- sRemoveRowButtonSelector: "li.wym_tools_remove_row a",
56
-
57
- sAddColumnButtonHtml: String() +
58
- "<li class='wym_tools_add_column'>" +
59
- "<a name='add_column' href='#' " +
60
- "title='Add Column' " +
61
- "style='background-image: " +
62
- "url(" + wym._options.basePath +
63
- "plugins/table/table_insert_column.png)'>" +
64
- "Add Table Column" +
65
- "</a>" +
66
- "</li>",
67
- sAddColumnButtonSelector: "li.wym_tools_add_column a",
68
-
69
- sRemoveColumnButtonHtml: String() +
70
- "<li class='wym_tools_remove_column'>" +
71
- "<a name='remove_column' href='#' " +
72
- "title='Remove Column' " +
73
- "style='background-image: " +
74
- "url(" + wym._options.basePath +
75
- "plugins/table/table_delete_column.png)'>" +
76
- "Remove Table Column" +
77
- "</a>" +
78
- "</li>",
79
- sRemoveColumnButtonSelector: "li.wym_tools_remove_column a",
80
-
81
- enableCellTabbing: true
82
-
83
- }, options);
84
-
85
- this._options = options;
86
- this._wym = wym;
87
-
88
- this.init();
89
- }
90
-
91
- /**
92
- * Construct and return a table objects using the given options object.
93
- *
94
- * @param options The configuration object.
95
- */
96
- WYMeditor.editor.prototype.table = function (options) {
97
- var tableEditor = new TableEditor(options, this);
98
- this.tableEditor = tableEditor;
99
-
100
- return tableEditor;
101
- };
102
-
103
- /**
104
- * Initialize the TableEditor object by adding appropriate toolbar buttons and
105
- * binding any required event listeners.
106
- */
107
- TableEditor.prototype.init = function () {
108
- var wym = this._wym,
109
- tableEditor = this,
110
- // Add the tool panel buttons
111
- tools = $(wym._box).find(
112
- wym._options.toolsSelector + wym._options.toolsListSelector
113
- );
114
-
115
- tools.append(tableEditor._options.sMergeRowButtonHtml);
116
- tools.append(tableEditor._options.sAddRowButtonHtml);
117
- tools.append(tableEditor._options.sRemoveRowButtonHtml);
118
- tools.append(tableEditor._options.sAddColumnButtonHtml);
119
- tools.append(tableEditor._options.sRemoveColumnButtonHtml);
120
-
121
- tableEditor.bindEvents();
122
- rangy.init();
123
- };
124
-
125
- /**
126
- * Bind all required event listeners, including button listeners and support for
127
- * tabbing through table cells if enableCellTabbing is true.
128
- */
129
- TableEditor.prototype.bindEvents = function () {
130
- var wym = this._wym,
131
- tableEditor = this;
132
-
133
- // Handle tool button click
134
- $(wym._box).find(tableEditor._options.sMergeRowButtonSelector).click(function () {
135
- var sel = rangy.getIframeSelection(wym._iframe);
136
- tableEditor.mergeRow(sel);
137
- return false;
138
- });
139
- $(wym._box).find(tableEditor._options.sAddRowButtonSelector).click(function () {
140
- return tableEditor.addRow(wym.selected());
141
- });
142
- $(wym._box).find(tableEditor._options.sRemoveRowButtonSelector).click(function () {
143
- return tableEditor.removeRow(wym.selected());
144
- });
145
- $(wym._box).find(tableEditor._options.sAddColumnButtonSelector).click(function () {
146
- return tableEditor.addColumn(wym.selected());
147
- });
148
- $(wym._box).find(tableEditor._options.sRemoveColumnButtonSelector).click(function () {
149
- return tableEditor.removeColumn(wym.selected());
150
- });
151
-
152
- // Handle tab clicks
153
- if (tableEditor._options.enableCellTabbing) {
154
- $(wym._doc).bind('keydown', tableEditor.keyDown);
155
- }
156
- };
157
-
158
- /**
159
- * Get the number of columns in a given tr element, accounting for colspan and
160
- * rowspan. This function assumes that the table structure is valid, and will
161
- * return incorrect results for uneven tables.
162
- *
163
- * @param tr The <tr> node whose number of columns we need to count.
164
- *
165
- * @returns {Number} The number of columns in the given tr, accounting for
166
- * colspan and rowspan.
167
- */
168
- TableEditor.prototype.getNumColumns = function (tr) {
169
- var wym = this._wym,
170
- numColumns = 0,
171
- table,
172
- firstTr;
173
-
174
- table = wym.findUp(tr, 'table');
175
- firstTr = $(table).find('tr:eq(0)');
176
-
177
- // Count the tds and ths in the FIRST ROW of this table, accounting for
178
- // colspan. We count the first td because it won't have any rowspan's before
179
- // it to complicate things
180
- $(firstTr).children('td,th').each(function (index, elmnt) {
181
- numColumns += TableEditor.GET_COLSPAN_PROP(elmnt);
182
- });
183
-
184
- return numColumns;
185
- };
186
-
187
- /**
188
- TableEditor.GET_COLSPAN_PROP
189
- ============================
190
-
191
- Get the integer value of the inferred colspan property on the given cell in
192
- a cross-browser compatible way that's also compatible across jquery versions.
193
-
194
- jquery 1.6 changed the way .attr works, which affected certain browsers
195
- differently with regard to colspan and rowspan for cells that didn't explcility
196
- have that attribue set.
197
- */
198
- TableEditor.GET_COLSPAN_PROP = function (cell) {
199
- var colspan = $(cell).attr('colspan');
200
- if (typeof colspan === 'undefined') {
201
- colspan = 1;
202
- }
203
- return parseInt(colspan, 10);
204
- };
205
-
206
- /**
207
- TableEditor.GET_ROWSPAN_PROP
208
- ============================
209
-
210
- Get the integer value of the inferred rowspan property on the given cell in
211
- a cross-browser compatible way that's also compatible across jquery versions.
212
-
213
- See GET_COLSPAN_PROP for details
214
- */
215
- TableEditor.GET_ROWSPAN_PROP = function (cell) {
216
- var rowspan = $(cell).attr('rowspan');
217
- if (typeof rowspan === 'undefined') {
218
- rowspan = 1;
219
- }
220
- return parseInt(rowspan, 10);
221
- };
222
- /**
223
- * Get the X grid index of the given td or th table cell (0-indexed). This takes
224
- * in to account all colspans and rowspans.
225
- *
226
- * @param cell The td or th node whose X index we're returning.
227
- */
228
- TableEditor.prototype.getCellXIndex = function (cell) {
229
- var tableEditor = this,
230
- i,
231
- parentTr,
232
- baseRowColumns,
233
- rowColCount,
234
- missingCells,
235
- rowspanIndexes,
236
- checkTr,
237
- rowOffset,
238
- trChildren,
239
- elmnt,
240
- colspan,
241
- indexCounter,
242
- cellIndex;
243
- parentTr = $(cell).parent('tr')[0];
244
-
245
- baseRowColumns = this.getNumColumns(parentTr);
246
-
247
- // Figure out how many explicit cells are missing which is how many rowspans
248
- // we're affected by
249
- rowColCount = 0;
250
- $(parentTr).children('td,th').each(function (index, elmnt) {
251
- rowColCount += TableEditor.GET_COLSPAN_PROP(elmnt);
252
- });
253
-
254
- missingCells = baseRowColumns - rowColCount;
255
- rowspanIndexes = [];
256
- checkTr = parentTr;
257
- rowOffset = 1;
258
-
259
- // If this cell is affected by a rowspan from farther up the table,
260
- // we need to take in to account any possible colspan attributes on that
261
- // cell. Store the real X index of the cells to the left of our cell to use
262
- // in the colspan calculation.
263
- while (missingCells > 0) {
264
- checkTr = $(checkTr).prev('tr');
265
- rowOffset += 1;
266
- trChildren = $(checkTr).children('td,th');
267
- for (i = 0; i < trChildren.length; i++) {
268
- elmnt = trChildren[i];
269
- if (TableEditor.GET_ROWSPAN_PROP(elmnt) >= rowOffset) {
270
- // Actually affects our source row
271
- missingCells -= 1;
272
- colspan = TableEditor.GET_COLSPAN_PROP(elmnt);
273
- rowspanIndexes[tableEditor.getCellXIndex(elmnt)] = colspan;
274
- }
275
- }
276
- }
277
-
278
- indexCounter = 0;
279
- cellIndex = null;
280
- // Taking in to account the real X indexes of all of the columns to the left
281
- // of this cell, determine the real X index.
282
- $(parentTr).children('td,th').each(function (index, elmnt) {
283
- if (cellIndex !== null) {
284
- // We've already iterated to the cell we're checking
285
- return;
286
- }
287
- // Account for an inferred colspan created by a rowspan from above
288
- while (typeof rowspanIndexes[indexCounter] !== 'undefined') {
289
- indexCounter += parseInt(rowspanIndexes[indexCounter], 10);
290
- }
291
- if (elmnt === cell) {
292
- // We're at our cell, no need to keep moving to the right.
293
- // Signal this by setting the cellIndex
294
- cellIndex = indexCounter;
295
- return;
296
- }
297
- // Account for an explicit colspan on this cell
298
- indexCounter += TableEditor.GET_COLSPAN_PROP(elmnt);
299
- });
300
-
301
- if (cellIndex === null) {
302
- // Somehow, we never found the cell when iterating over its row.
303
- throw "Cell index not found";
304
- }
305
- return cellIndex;
306
- };
307
-
308
- /**
309
- * Get the number of columns represented by the given array of contiguous cell
310
- * (td/th) nodes.
311
- * Accounts for colspan and rowspan attributes.
312
- *
313
- * @param cells An array of td/th nodes whose total column span we're checking.
314
- *
315
- * @return {Number} The number of columns represented by the "cells"
316
- */
317
- TableEditor.prototype.getTotalColumns = function (cells) {
318
- var tableEditor = this,
319
- rootTr = this.getCommonParentTr(cells),
320
- baseRowColumns,
321
- colspanCount,
322
- rowColCount;
323
-
324
- if (rootTr === null) {
325
- // Non-contiguous columns
326
- throw "getTotalColumns only allowed for contiguous cells";
327
- }
328
-
329
- baseRowColumns = this.getNumColumns(rootTr);
330
-
331
- // Count the number of simple columns, not accounting for rowspans
332
- colspanCount = 0;
333
- $(cells).each(function (index, elmnt) {
334
- colspanCount += TableEditor.GET_COLSPAN_PROP(elmnt);
335
- });
336
-
337
- // Determine if we're affected by rowspans. If the number of simple columns
338
- // in the row equals the number of columns in the first row, we don't have
339
- // any rowspans
340
- rowColCount = 0;
341
- $(rootTr).children('td,th').each(function (index, elmnt) {
342
- rowColCount += TableEditor.GET_COLSPAN_PROP(elmnt);
343
- });
344
-
345
- if (rowColCount === baseRowColumns) {
346
- // Easy case. No rowspans to deal with
347
- return colspanCount;
348
- } else {
349
- if (cells.length === 1) {
350
- // Easy. Just the colspan
351
- return TableEditor.GET_COLSPAN_PROP(cells[0]);
352
- } else {
353
- var lastCell = $(cells).eq(cells.length - 1)[0],
354
- firstCell = $(cells).eq(0)[0];
355
- // On jQuery 1.4 upgrade, $(cells).eq(-1)
356
- return 1 + tableEditor.getCellXIndex(lastCell) -
357
- tableEditor.getCellXIndex(firstCell);
358
- }
359
- }
360
- };
361
-
362
- /**
363
- * Merge the table cells in the given selection using a colspan.
364
- *
365
- * @param sel A rangy selection object across which to row merge.
366
- *
367
- * @return {Boolean} true if changes are made, false otherwise
368
- */
369
- TableEditor.prototype.mergeRow = function (sel) {
370
- var wym = this._wym,
371
- tableEditor = this,
372
- i,
373
- // Get all of the affected nodes in the range
374
- nodes = [],
375
- range = null,
376
- cells,
377
- rootTr,
378
- mergeCell,
379
- $elmnt,
380
- rowspanProp;
381
-
382
- for (i = 0; i < sel.rangeCount; i++) {
383
- range = sel.getRangeAt(i);
384
- nodes = nodes.concat(range.getNodes(false));
385
- }
386
-
387
- // Just use the td and th nodes
388
- cells = $(nodes).filter('td,th');
389
- if (cells.length === 0) {
390
- return false;
391
- }
392
-
393
- // If the selection is across multiple tables, don't merge
394
- rootTr = tableEditor.getCommonParentTr(cells);
395
- if (rootTr === null) {
396
- return false;
397
- }
398
-
399
- mergeCell = cells[0];
400
- // If any of the cells have a rowspan, create the inferred cells
401
- $(cells).each(function (i, elmnt) {
402
- $elmnt = $(elmnt);
403
- rowspanProp = TableEditor.GET_ROWSPAN_PROP(elmnt);
404
- if (rowspanProp <= 1) {
405
- // We don't care about cells without a rowspan
406
- return;
407
- }
408
-
409
- // This cell has an actual rowspan, we need to account for it
410
- // Figure out the x index for this cell in the table grid
411
- var prevCells = $elmnt.prevAll('td,th'),
412
- index = tableEditor.getCellXIndex(elmnt),
413
- // Create the previously-inferred cell in the appropriate index
414
- // with one less rowspan
415
- newRowspan = rowspanProp - 1,
416
- newTd;
417
- if (newRowspan === 1) {
418
- newTd = '<td>' + $elmnt.html() + '</td>';
419
- } else {
420
- newTd = String() +
421
- '<td rowspan="' + newRowspan + '">' +
422
- $elmnt.html() +
423
- '</td>';
424
- }
425
- if (index === 0) {
426
- $elmnt.parent('tr')
427
- .next('tr')
428
- .prepend(newTd);
429
- } else {
430
- // TODO: account for colspan/rowspan with insertion
431
- // Account for colspan/rowspan by walking from right to left looking
432
- // for the cell closest to the desired index to APPEND to
433
- var insertionIndex = index - 1,
434
- insertionCells = $elmnt.parent('tr').next('tr')
435
- .find('td,th'),
436
- cellInserted = false;
437
- for (i = insertionCells.length - 1; i >= 0; i--) {
438
- var xIndex = tableEditor.getCellXIndex(insertionCells[i]);
439
- if (xIndex <= insertionIndex) {
440
- $(insertionCells[i]).append(newTd);
441
- cellInserted = true;
442
- break;
443
- }
444
- }
445
- if (!cellInserted) {
446
- // Bail out now before we clear HTML and break things
447
- throw "Cell rowspan invalid";
448
- }
449
- }
450
-
451
- // Clear the cell's html, since we just moved it down
452
- $elmnt.html('');
453
- });
454
-
455
- // Remove any rowspan from the mergecell now that we've shifted rowspans
456
- // down
457
- // ie fails when we try to remove a rowspan for some reason
458
- try {
459
- $(mergeCell).removeAttr('rowspan');
460
- } catch (err) {
461
- $(mergeCell).attr('rowspan', 1);
462
- }
463
-
464
- // Build the content of the new combined cell from all of the included cells
465
- var newContent = '';
466
- $(cells).each(function (index, elmnt) {
467
- newContent += $(elmnt).html();
468
- });
469
-
470
- // Add a colspan to the farthest-left cell
471
- var combinedColspan = this.getTotalColumns(cells);
472
- if ($.browser.msie) {
473
- // jQuery.attr doesn't work for colspan in ie
474
- mergeCell.colSpan = combinedColspan;
475
- } else {
476
- $(mergeCell).attr('colspan', combinedColspan);
477
- }
478
-
479
- // Delete the rest of the cells
480
- $(cells).each(function (index, elmnt) {
481
- if (index !== 0) {
482
- $(elmnt).remove();
483
- }
484
- });
485
-
486
- // Change the content in our newly-merged cell
487
- $(mergeCell).html(newContent);
488
-
489
- tableEditor.selectElement(mergeCell);
490
-
491
- return true;
492
- };
493
-
494
- /**
495
- * Add a row to the given elmnt (representing a <tr> or a child of a <tr>).
496
- *
497
- * @param The node which will have a row appended after its parent row.
498
- */
499
- TableEditor.prototype.addRow = function (elmnt) {
500
- var wym = this._wym,
501
- tr = this._wym.findUp(elmnt, 'tr'),
502
- numColumns,
503
- tdHtml,
504
- i;
505
-
506
- if (tr === null) {
507
- return false;
508
- }
509
-
510
- numColumns = this.getNumColumns(tr);
511
-
512
- tdHtml = '';
513
- for (i = 0; i < numColumns; i++) {
514
- tdHtml += '<td>&nbsp;</td>';
515
- }
516
- $(tr).after('<tr>' + tdHtml + '</tr>');
517
-
518
- return false;
519
- };
520
-
521
- /**
522
- * Remove the given table if it doesn't have any rows/columns.
523
- *
524
- * @param table The table to delete if it is empty.
525
- */
526
- TableEditor.prototype.removeEmptyTable = function (table) {
527
- var cells = $(table).find('td,th');
528
- if (cells.length === 0) {
529
- $(table).remove();
530
- }
531
- };
532
-
533
- /**
534
- * Remove the row for the given element (representing a <tr> or a child
535
- * of a <tr>).
536
- *
537
- * @param elmnt The node whose parent tr will be removed.
538
- */
539
- TableEditor.prototype.removeRow = function (elmnt) {
540
- var wym = this._wym,
541
- tr = this._wym.findUp(elmnt, 'tr'),
542
- table;
543
-
544
- if (tr === null) {
545
- return false;
546
- }
547
- table = wym.findUp(elmnt, 'table');
548
- $(tr).remove();
549
- this.removeEmptyTable(table);
550
-
551
- return false;
552
- };
553
-
554
- /**
555
- * Add a column to the given elmnt (representing a <td> or a child of a <td>).
556
- *
557
- * @param elmnt The node which will have a column appended afterward.
558
- */
559
- TableEditor.prototype.addColumn = function (elmnt) {
560
- var wym = this._wym,
561
- td = this._wym.findUp(elmnt, ['td', 'th']),
562
- prevTds,
563
- tdIndex,
564
- tr,
565
- newTd = '<td>&nbsp;</td>',
566
- newTh = '<th>&nbsp;</th>',
567
- insertionElement;
568
-
569
- if (td === null) {
570
- return false;
571
- }
572
- prevTds = $(td).prevAll();
573
- tdIndex = prevTds.length;
574
-
575
- tr = wym.findUp(td, 'tr');
576
- $(tr).siblings('tr').andSelf().each(function (index, element) {
577
- insertionElement = newTd;
578
- if ($(element).find('th').length > 0) {
579
- // The row has a TH, so insert a th
580
- insertionElement = newTh;
581
- }
582
-
583
- $(element).find('td,th').eq(tdIndex).after(insertionElement);
584
- });
585
-
586
- return false;
587
- };
588
-
589
- /**
590
- * Remove the column to the right of the given elmnt (representing a <td> or a
591
- * child of a <td>).
592
- */
593
- TableEditor.prototype.removeColumn = function (elmnt) {
594
- var wym = this._wym,
595
- td = this._wym.findUp(elmnt, ['td', 'th']),
596
- table,
597
- prevTds,
598
- tdIndex,
599
- tr;
600
- if (td === null) {
601
- return false;
602
- }
603
- table = wym.findUp(elmnt, 'table');
604
- prevTds = $(td).prevAll();
605
- tdIndex = prevTds.length;
606
-
607
- tr = wym.findUp(td, 'tr');
608
- $(tr).siblings('tr').each(function (index, element) {
609
- $(element).find('td,th').eq(tdIndex).remove();
610
- });
611
- $(td).remove();
612
- this.removeEmptyTable(table);
613
-
614
- return false;
615
- };
616
-
617
- /**
618
- * keyDown event handler used for consistent tab key cell movement.
619
- */
620
- TableEditor.prototype.keyDown = function (evt) {
621
- //'this' is the doc
622
- var wym = WYMeditor.INSTANCES[this.title],
623
- tableEditor = wym.tableEditor;
624
-
625
- if (evt.keyCode === WYMeditor.KEY.TAB) {
626
- return tableEditor.selectNextCell(wym.selected());
627
- }
628
-
629
- return null;
630
- };
631
-
632
- /**
633
- * Move the focus to the next cell.
634
- */
635
- TableEditor.prototype.selectNextCell = function (elmnt) {
636
- var wym = this._wym,
637
- tableEditor = this,
638
- cell = wym.findUp(elmnt, ['td', 'th']),
639
- nextCells,
640
- tr,
641
- nextRows;
642
-
643
- if (cell === null) {
644
- return null;
645
- }
646
-
647
- // Try moving to the next cell to the right
648
- nextCells = $(cell).next('td,th');
649
- if (nextCells.length > 0) {
650
- tableEditor.selectElement(nextCells[0]);
651
- return false;
652
- }
653
-
654
- // There was no cell to the right, use the first cell in the next row
655
- tr = wym.findUp(cell, 'tr');
656
- nextRows = $(tr).next('tr');
657
- if (nextRows.length !== 0) {
658
- nextCells = $(nextRows).children('td,th');
659
- if (nextCells.length > 0) {
660
- tableEditor.selectElement(nextCells[0]);
661
- return false;
662
- }
663
- }
664
-
665
- // There is no next row. Do a normal tab
666
- return null;
667
- };
668
-
669
- /**
670
- * Select the given element using rangy selectors.
671
- */
672
- TableEditor.prototype.selectElement = function (elmnt) {
673
- var sel = rangy.getIframeSelection(this._wym._iframe),
674
- range = rangy.createRange(this._wym._doc);
675
-
676
- range.setStart(elmnt, 0);
677
- range.setEnd(elmnt, 0);
678
- range.collapse(false);
679
-
680
- try {
681
- sel.setSingleRange(range);
682
- } catch (err) {
683
- // ie8 can raise an "unkown runtime error" trying to empty the range
684
- }
685
- // IE selection hack
686
- if ($.browser.msie) {
687
- this._wym.saveCaret();
688
- }
689
- };
690
-
691
- /**
692
- * Get the common parent tr for the given table cell nodes. If the closest parent
693
- * tr for each cell isn't the same, returns null.
694
- */
695
- TableEditor.prototype.getCommonParentTr = function (cells) {
696
- var firstCell,
697
- parentTrList,
698
- rootTr;
699
-
700
- cells = $(cells).filter('td,th');
701
- if (cells.length === 0) {
702
- return null;
703
- }
704
- firstCell = cells[0];
705
- parentTrList = $(firstCell).parent('tr');
706
-
707
- if (parentTrList.length === 0) {
708
- return null;
709
- }
710
- rootTr = parentTrList[0];
711
-
712
- // Ensure that all of the cells have the same parent tr
713
- $(cells).each(function (index, elmnt) {
714
- parentTrList = $(elmnt).parent('tr');
715
- if (parentTrList.length === 0 || parentTrList[0] !== rootTr) {
716
- return null;
717
- }
718
- });
719
-
720
- return rootTr;
721
- };