Adding a Regular Expression Editor (Grid) binding.
2 <!-- ***** BEGIN LICENSE BLOCK *****
3 - Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 - The contents of this file are subject to the Mozilla Public License Version
6 - 1.1 (the "License"); you may not use this file except in compliance with
7 - the License. You may obtain a copy of the License at
8 - http://www.mozilla.org/MPL/
10 - Software distributed under the License is distributed on an "AS IS" basis,
11 - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 - for the specific language governing rights and limitations under the
15 - The Original Code is XUL Menudeck Widget.
17 - The Initial Developer of the Original Code is
18 - Alexander J. Vincent <ajvincent@gmail.com>.
19 - Portions created by the Initial Developer are Copyright (C) 2004-2005
20 - the Initial Developer. All Rights Reserved.
24 - Alternatively, the contents of this file may be used under the terms of
25 - either the GNU General Public License Version 2 or later (the "GPL"), or
26 - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 - in which case the provisions of the GPL or the LGPL are applicable instead
28 - of those above. If you wish to allow use of your version of this file only
29 - under the terms of either the GPL or the LGPL, and not to allow others to
30 - use your version of this file under the terms of the MPL, indicate your
31 - decision by deleting the provisions above and replace them with the notice
32 - and other provisions required by the LGPL or the GPL. If you do not delete
33 - the provisions above, a recipient may use your version of this file under
34 - the terms of any one of the MPL, the GPL or the LGPL.
36 - ***** END LICENSE BLOCK ***** -->
38 <!ENTITY % namespaces.dtd SYSTEM "chrome://xulwidgets/content/namespaces.dtd">
41 <bindings xmlns="&XBL_NS;"
44 xmlns:html="&XHTML_NS;"
46 <binding id="regexp-cell">
48 <method name="getAnonElement">
49 <parameter name="id"/>
51 return document.getAnonymousElementByAttribute(this, "anonid", id);
55 <property name="grid" readonly="true">
59 node = node.parentNode;
62 } while ((node.namespaceURI != this.namespaceURI) ||
63 (node.localName != "regexp-grid"));
70 <binding id="regexp-column"
71 extends="chrome://verbosio/content/bindings/regexp.xml#regexp-cell"
75 <xul:textbox anonid="source"/>
76 <xul:hbox anonclass="checkboxes">
77 <xul:checkbox label="g" anonid="g"/>
78 <xul:checkbox label="i" anonid="i"/>
79 <xul:checkbox label="m" anonid="m"/>
81 <xul:description anonid="result"/>
83 <xul:button anonid="removeButton">Remove column</xul:button>
89 this.getAnonElement("source");
92 this.getAnonElement("g");
95 this.getAnonElement("i");
98 this.getAnonElement("m");
100 <field name="result">
101 this.getAnonElement("result");
103 <field name="removeButton">
104 this.getAnonElement("removeButton");
107 <property name="flags" readonly="true">
110 const flagsList = ["g", "i", "m"];
111 for each (var item in flagsList)
113 if (this[item].checked)
120 <field name="regexp">null</field>
122 <method name="getRegExp">
125 return new RegExp(this.source.value, this.flags);
132 <method name="update">
134 this.regexp = this.getRegExp();
135 this.result.value = this.regexp ? this.regexp.toString() : "";
136 this.grid.updateColumn(this);
140 <method name="initialize">
141 <parameter name="source"/>
142 <parameter name="flags"/>
144 this.source.value = source;
145 this.flags.value = flags;
151 var columnCell = this;
152 this.removeButton.addEventListener("command", function(aEvt) {
153 columnCell.grid.removeRegExp(columnCell);
154 aEvt.stopPropagation();
155 aEvt.preventDefault();
161 <handler event="command"><![CDATA[
164 <handler event="input"><![CDATA[
170 <binding id="regexp-text"
171 extends="chrome://verbosio/content/bindings/regexp.xml#regexp-cell"
175 <xul:textbox multiline="true"
180 <xul:button anonid="delete-row">Delete row</xul:button>
185 <method name="update">
187 this.grid.updateRow(this.parentNode);
191 <field name="deleteRow">
192 this.getAnonElement("delete-row")
196 this.getAnonElement("data")
201 this.deleteRow.addEventListener("command", function(aEvt) {
202 rowCell.grid.removeTextRow(rowCell.parentNode);
203 aEvt.stopPropagation();
204 aEvt.preventDefault();
207 this.data.addEventListener("input", function(aEvt) {
215 <binding id="regexp-exec"
216 extends="chrome://verbosio/content/bindings/regexp.xml#regexp-cell"
219 <html:pre anonid="data"/>
223 this.getAnonElement("data");
225 <method name="setValue">
226 <parameter name="value"/>
228 if (!this.data.firstChild)
230 var data = document.createCDATASection(value);
231 this.data.appendChild(data);
234 this.data.firstChild.nodeValue = value;
238 <parameter name="regexp"/>
239 <parameter name="text"/>
241 if (!regexp || !text) {
247 var results = regexp.exec(text);
258 if (results instanceof Array)
260 for (var i = 0; i < results.length; i++)
261 value += i + ": " + results[i] + "\n";
262 value = value.substr(0, value.length - 1);
264 value = results.toString();
265 this.setValue(value);
271 <binding id="regexp-grid">
281 <grid xmlns="&XUL_NS;" anonid="grid">
287 <row anonid="regexp-row">
290 <button anonid="add-column">Add Column</button>
293 <row anonid="last-row">
295 <button anonid="add-row">Add Row</button>
303 <method name="getAnonElement">
304 <parameter name="id"/>
306 return document.getAnonymousElementByAttribute(this, "anonid", id);
310 this.getAnonElement("grid");
313 <field name="regexpRow">
314 this.getAnonElement("regexp-row");
317 <field name="lastRow">
318 this.getAnonElement("last-row");
321 <property name="columns" readonly="true">
323 return this.regexpRow.getElementsByTagNameNS(
330 <property name="rows" readonly="true">
332 var nodes = this.lastRow.parentNode.childNodes;
334 for (var i = 1; i < nodes.length - 1; i++)
340 <field name="gridCells">([/* (columns, rows) */])</field>
342 <method name="getGridCell">
343 <parameter name="columnIndex"/>
344 <parameter name="rowIndex"/>
346 while (columnIndex >= this.columns.length)
347 this.addRegExp(null, null);
349 while (columnIndex >= this.gridCells.length)
350 this.gridCells.push([]);
352 var gridColumn = this.gridCells[columnIndex];
354 while (rowIndex >= this.rows.length)
357 while (rowIndex >= gridColumn.length) {
358 var cell = document.createElementNS(this.namespaceURI, "regexp-exec");
359 var insertIndex = gridColumn.length;
360 this.rows[insertIndex].appendChild(cell);
361 gridColumn.push(cell);
364 return gridColumn[rowIndex];
368 <method name="removeGridCell">
369 <parameter name="columnIndex"/>
370 <parameter name="rowIndex"/>
372 var gridColumn = this.gridCells[columnIndex];
373 var gridCell = gridColumn[rowIndex];
374 gridColumn.splice(rowIndex, 1);
375 gridCell.parentNode.removeChild(gridCell);
379 <method name="updateCell">
380 <parameter name="columnIndex"/>
381 <parameter name="rowIndex"/>
383 var cell = this.getGridCell(columnIndex, rowIndex);
384 var node = this.rows[rowIndex];
385 node = node.getElementsByTagNameNS(this.namespaceURI, "regexp-text")[0];
387 var text = node.data.value;
388 var regexp = this.columns[columnIndex].regexp;
389 cell.exec(regexp, text);
393 <method name="updateColumn">
394 <parameter name="columnCell"/>
396 var columns = this.columns;
397 for (var i = 0; i < columns.length; i++)
399 if (columns[i] != columnCell)
401 var rows = this.rows;
402 for (var j = 0; j < rows.length; j++)
403 this.updateCell(i, j);
409 <method name="updateRow">
410 <parameter name="rowElement"/>
412 var rows = this.rows;
413 for (var i = 0; i < rows.length; i++)
415 if (rows[i] != rowElement)
417 var columns = this.columns;
418 for (var j = 0; j < columns.length; j++)
419 this.updateCell(j, i);
425 <method name="addRegExp">
426 <parameter name="regexpSrc"/>
427 <parameter name="regexpFlags"/>
428 <parameter name="childFragment"/>
430 var columnCell = document.createElementNS(this.namespaceURI,
432 if (childFragment instanceof Components.interfaces.nsIDOMDocumentFragment)
433 columnCell.appendChild(childFragment.cloneNode(true));
435 this.regexpRow.insertBefore(columnCell, this.regexpRow.lastChild);
436 columnCell.initialize(regexpSrc, regexpFlags);
438 this.updateColumn(columnCell);
442 <method name="addTextRow">
443 <parameter name="value"/>
445 var newRow = document.createElementNS(this.namespaceURI, "xul:row");
446 var text = document.createElementNS(this.namespaceURI, "xul:regexp-text");
447 newRow.appendChild(text);
448 this.lastRow.parentNode.insertBefore(newRow, this.lastRow);
451 this.updateRow(newRow);
455 <method name="removeRegExp">
456 <parameter name="columnElement"/>
458 var columns = this.columns;
459 for (var i = 0; i < columns.length; i++) {
460 if (columns[i] != columnElement)
463 var rows = this.rows;
464 for (var j = 0; j < rows.length; j++)
465 this.removeGridCell(i, j);
466 columnElement.parentNode.removeChild(columnElement);
472 <method name="removeTextRow">
473 <parameter name="rowElement"/>
475 var rows = this.rows;
476 for (var i = 0; i < rows.length; i++)
478 if (rows[i] != rowElement)
481 var columns = this.columns;
482 for (var j = 0; j < columns.length; j++)
483 this.removeGridCell(j, i);
484 rowElement.parentNode.removeChild(rowElement);
491 <field name="addRowButton">
492 this.getAnonElement("add-row");
495 <field name="addColumnButton">
496 this.getAnonElement("add-column");
499 <constructor><![CDATA[
502 this.addRowButton.addEventListener("command", function() {
506 this.addColumnButton.addEventListener("command", function() {
507 grid.addRegExp(null, null);