| <!-- The <textarea-numbers-sk> custom element declaration. |
| |
| Wraps a textarea and adds line numbers and error locations. |
| |
| Attributes: |
| None. |
| |
| Events: |
| None. |
| |
| Methods: |
| clearErrors - Removes all error line annotations. |
| |
| setErrorLine(n) - Indicates there is an error on line n. |
| |
| setCursor(row, col) - Indicates there is an error at |
| row and column. |
| |
| textAreaChanged() - Call if the textarea content was set |
| programmatically. |
| |
| --> |
| |
| <dom-module id="textarea-numbers-sk"> |
| <style> |
| :host { |
| display: block; |
| position: relative; |
| overflow: hidden; |
| background: #ddd; |
| font-family: monospace; |
| font-size: 13px; |
| width: 70em; |
| } |
| |
| #numbers { |
| position: absolute; |
| top: 0; |
| left: 0; |
| font-family: monospace; |
| font-size: 13px; |
| padding: 0.5em; |
| text-align: right; |
| background: #ddd; |
| width: 3em; |
| } |
| |
| #numbers .err { |
| background-color: #f88; |
| } |
| |
| #numbers div { |
| padding: 0 1em 0 1em; |
| } |
| </style> |
| <template> |
| <content></content> |
| <div id=numbers> |
| <template is="dom-repeat" items="{{rows}}"> |
| <div id="L{{item}}">{{item}}</div> |
| </template> |
| </div> |
| </template> |
| </dom-module> |
| |
| <script> |
| Polymer({ |
| is: "textarea-numbers-sk", |
| |
| properties: { |
| rows: { |
| type: Array, |
| value: function() { return []; }, |
| reflectToAttribute: false, |
| }, |
| }, |
| |
| ready: function() { |
| this._hasErrors = true; |
| this._textarea = $$$('textarea', this); |
| this.textAreaChanged(); |
| this._textarea.addEventListener("change", this.textAreaChanged.bind(this)); |
| this._textarea.addEventListener("paste", this.textAreaChanged.bind(this)); |
| this._textarea.addEventListener("input", this.textAreaChanged.bind(this)); |
| }, |
| |
| textAreaChanged: function() { |
| var n = this._textarea.value.split("\n").length; |
| this._textarea.rows = n; |
| r = []; |
| for (var i = 0; i < n ; i++) { |
| r.push(i+1); |
| } |
| this.set('rows', r); |
| this.clearErrors(); |
| }, |
| |
| clearErrors: function() { |
| if (this._hasErrors) { |
| $$('#numbers div').forEach(function(ele) { |
| ele.classList.remove("err"); |
| }); |
| } |
| this._hasErrors = false; |
| }, |
| |
| setErrorLine: function(n) { |
| var ele = $$$("#L" + n); |
| if (ele) { |
| ele.classList.add("err"); |
| this._hasErrors = true; |
| } |
| }, |
| |
| setCursor: function(row, col) { |
| var lines = this._textarea.value.split("\n"); |
| var total = 0; |
| for (var i = 0; i < row-1; i++) { |
| total += lines[i].length+1; |
| } |
| total += col; |
| this._textarea.setSelectionRange(total-1, total); |
| }, |
| |
| }); |
| </script> |