PageSourceSearch

https://actionnetwork.org/includes/js/redactor_table.js?v=71

js actionnetwork.org collected 2026-09-24 07:04:07 UTC 9,686 bytes, 472 lines download raw bytes

1(function($)
2{
3	$.Redactor.prototype.table = function()
4	{
5		return {
6			langs: {
7				en: {
8					"table": "<span class='screen-reader'>Table</span> <i class='far fa-table'></i>",
9					"insert-table": "Insert table",
10					"insert-row-above": "Insert row above",
11					"insert-row-below": "Insert row below",
12					"insert-column-left": "Insert column left",
13					"insert-column-right": "Insert column right",
14					"add-head": "Add head",
15					"delete-head": "Delete head",
16					"delete-column": "Delete column",
17					"delete-row": "Delete row",
18					"delete-table": "Delete table"
19				}
20			},
21			init: function()
22			{
23				var dropdown = {};
24
25				dropdown.insert_table = {
26									title: this.lang.get('insert-table'),
27									func: this.table.insert,
28									observe: {
29										element: 'table',
30										in: {
31											attr: {
32												'class': 'redactor-dropdown-link-inactive',
33												'aria-disabled': true,
34											}
35										}
36									}
37								};
38
39				dropdown.insert_row_above = {
40									title: this.lang.get('insert-row-above'),
41									func: this.table.addRowAbove,
42									observe: {
43										element: 'table',
44										out: {
45											attr: {
46												'class': 'redactor-dropdown-link-inactive',
47												'aria-disabled': true,
48											}
49										}
50									}
51								};
52
53				dropdown.insert_row_below = {
54									title: this.lang.get('insert-row-below'),
55									func: this.table.addRowBelow,
56									observe: {
57										element: 'table',
58										out: {
59											attr: {
60												'class': 'redactor-dropdown-link-inactive',
61												'aria-disabled': true,
62											}
63										}
64									}
65								};
66
67				dropdown.insert_column_left = {
68									title: this.lang.get('insert-column-left'),
69									func: this.table.addColumnLeft,
70									observe: {
71										element: 'table',
72										out: {
73											attr: {
74												'class': 'redactor-dropdown-link-inactive',
75												'aria-disabled': true,
76											}
77										}
78									}
79								};
80
81				dropdown.insert_column_right = {
82									title: this.lang.get('insert-column-right'),
83									func: this.table.addColumnRight,
84									observe: {
85										element: 'table',
86										out: {
87											attr: {
88												'class': 'redactor-dropdown-link-inactive',
89												'aria-disabled': true,
90											}
91										}
92									}
93								};
94
95				dropdown.add_head = {
96									title: this.lang.get('add-head'),
97									func: this.table.addHead,
98									observe: {
99										element: 'table',
100										out: {
101											attr: {
102												'class': 'redactor-dropdown-link-inactive',
103												'aria-disabled': true,
104											}
105										}
106									}
107								};
108
109				dropdown.delete_head = {
110									title: this.lang.get('delete-head'),
111									func: this.table.deleteHead,
112									observe: {
113										element: 'table',
114										out: {
115											attr: {
116												'class': 'redactor-dropdown-link-inactive',
117												'aria-disabled': true,
118											}
119										}
120									}
121								};
122
123				dropdown.delete_column = {
124									title: this.lang.get('delete-column'),
125									func: this.table.deleteColumn,
126									observe: {
127										element: 'table',
128										out: {
129											attr: {
130												'class': 'redactor-dropdown-link-inactive',
131												'aria-disabled': true,
132											}
133										}
134									}
135								};
136
137				dropdown.delete_row = {
138									title: this.lang.get('delete-row'),
139									func: this.table.deleteRow,
140									observe: {
141										element: 'table',
142										out: {
143											attr: {
144												'class': 'redactor-dropdown-link-inactive',
145												'aria-disabled': true,
146											}
147										}
148									}
149								};
150
151				dropdown.delete_table = {
152									title: this.lang.get('delete-table'),
153									func: this.table.deleteTable,
154									observe: {
155										element: 'table',
156										out: {
157											attr: {
158												'class': 'redactor-dropdown-link-inactive',
159												'aria-disabled': true,
160											}
161										}
162									}
163								};
164
165
166				var button = this.button.addBefore('link', 'table', this.lang.get('table'));
167				button.attr('title', 'Table');
168				this.button.addDropdown(button, dropdown);
169			},
170			insert: function()
171			{
172				if (this.table.getTable())
173				{
174					return;
175				}
176
177				this.placeholder.hide();
178
179				var rows = 2;
180				var columns = 3;
181				var $tableBox = $('<div>');
182				var $table = $('<table />');
183
184
185				for (var i = 0; i < rows; i++)
186				{
187					var $row = $('<tr>');
188
189					for (var z = 0; z < columns; z++)
190					{
191						var $column = $('<td>' + this.opts.invisibleSpace + '</td>');
192
193						// set the focus to the first td
194						if (i === 0 && z === 0)
195						{
196							$column.append(this.marker.get());
197						}
198
199						$($row).append($column);
200					}
201
202					$table.append($row);
203				}
204
205				$tableBox.append($table);
206				var html = $tableBox.html();
207
208				this.buffer.set();
209
210				var current = this.selection.current();
211				if ($(current).closest('li').length !== 0)
212				{
213					$(current).closest('ul, ol').first().after(html);
214				}
215				else
216				{
217					this.air.collapsed();
218					this.insert.html(html);
219				}
220
221				this.selection.restore();
222				this.core.callback('insertedTable', $table);
223			},
224			getTable: function()
225			{
226				var $table = $(this.selection.current()).closest('table');
227
228				if (!this.utils.isRedactorParent($table))
229				{
230					return false;
231				}
232
233				if ($table.size() === 0)
234				{
235					return false;
236				}
237
238				return $table;
239			},
240			restoreAfterDelete: function($table)
241			{
242				this.selection.restore();
243				$table.find('span.redactor-selection-marker').remove();
244
245			},
246			deleteTable: function()
247			{
248				var $table = this.table.getTable();
249				if (!$table)
250				{
251					return;
252				}
253
254				this.buffer.set();
255
256
257				var $next = $table.next();
258				if (!this.opts.linebreaks && $next.length !== 0)
259				{
260					this.caret.start($next);
261				}
262				else
263				{
264					this.caret.after($table);
265				}
266
267
268				$table.remove();
269
270
271			},
272			deleteRow: function()
273			{
274				var $table = this.table.getTable();
275				if (!$table)
276				{
277					return;
278				}
279
280				var $current = $(this.selection.current());
281
282				this.buffer.set();
283
284				var $current_tr = $current.closest('tr');
285				var $focus_tr = $current_tr.prev().length ? $current_tr.prev() : $current_tr.next();
286				if ($focus_tr.length)
287				{
288					var $focus_td = $focus_tr.children('td, th').first();
289					if ($focus_td.length)
290					{
291						$focus_td.prepend(this.marker.get());
292					}
293				}
294
295				$current_tr.remove();
296				this.table.restoreAfterDelete($table);
297			},
298			deleteColumn: function()
299			{
300				var $table = this.table.getTable();
301				if (!$table)
302				{
303					return;
304				}
305
306				this.buffer.set();
307
308				var $current = $(this.selection.current());
309				var $current_td = $current.closest('td, th');
310				var index = $current_td[0].cellIndex;
311
312				$table.find('tr').each($.proxy(function(i, elem)
313				{
314					var $elem = $(elem);
315					var focusIndex = index - 1 < 0 ? index + 1 : index - 1;
316					if (i === 0)
317					{
318						$elem.find('td, th').eq(focusIndex).prepend(this.marker.get());
319					}
320
321					$elem.find('td, th').eq(index).remove();
322
323				}, this));
324
325				this.table.restoreAfterDelete($table);
326			},
327			addHead: function()
328			{
329				var $table = this.table.getTable();
330				if (!$table)
331				{
332					return;
333				}
334
335				this.buffer.set();
336
337				if ($table.find('thead').size() !== 0)
338				{
339					this.table.deleteHead();
340					return;
341				}
342
343				var tr = $table.find('tr').first().clone();
344				tr.find('td').replaceWith($.proxy(function()
345				{
346					return $('<th>').html(this.opts.invisibleSpace);
347				}, this));
348
349				$thead = $('<thead></thead>').append(tr);
350				$table.prepend($thead);
351
352
353
354			},
355			deleteHead: function()
356			{
357				var $table = this.table.getTable();
358				if (!$table)
359				{
360					return;
361				}
362
363				var $thead = $table.find('thead');
364				if ($thead.size() === 0)
365				{
366					return;
367				}
368
369				this.buffer.set();
370
371				$thead.remove();
372
373			},
374			addRowAbove: function()
375			{
376				this.table.addRow('before');
377			},
378			addRowBelow: function()
379			{
380				this.table.addRow('after');
381			},
382			addColumnLeft: function()
383			{
384				this.table.addColumn('before');
385			},
386			addColumnRight: function()
387			{
388				this.table.addColumn('after');
389			},
390			addRow: function(type)
391			{
392				var $table = this.table.getTable();
393				if (!$table)
394				{
395					return;
396				}
397
398				this.buffer.set();
399
400				var $current = $(this.selection.current());
401				var $current_tr = $current.closest('tr');
402				var new_tr = $current_tr.clone();
403
404				new_tr.find('th').replaceWith(function()
405				{
406					var $td = $('<td>');
407					$td[0].attributes = this.attributes;
408
409					return $td.append($(this).contents());
410				});
411
412				new_tr.find('td').html(this.opts.invisibleSpace);
413
414				if (type === 'after')
415				{
416					$current_tr.after(new_tr);
417				}
418				else
419				{
420					$current_tr.before(new_tr);
421				}
422
423
424			},
425			addColumn: function (type)
426			{
427				var $table = this.table.getTable();
428				if (!$table)
429				{
430					return;
431				}
432
433				var index = 0;
434				var current = $(this.selection.current());
435
436				this.buffer.set();
437
438				var $current_tr = current.closest('tr');
439				var $current_td = current.closest('td, th');
440
441				$current_tr.find('td, th').each($.proxy(function(i, elem)
442				{
443					if ($(elem)[0] === $current_td[0])
444					{
445						index = i;
446					}
447
448				}, this));
449
450				$table.find('tr').each($.proxy(function(i, elem)
451				{
452					var $current = $(elem).find('td, th').eq(index);
453
454					var td = $current.clone();
455					td.html(this.opts.invisibleSpace);
456
457					if (type === 'after')
458					{
459						$current.after(td);
460					}
461					else
462					{
463						$current.before(td);
464					}
465
466				}, this));
467
468
469			}
470		};
471	};
472})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.