| OLD | NEW |
| (Empty) |
| 1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> | |
| 2 <html> | |
| 3 <head> | |
| 4 <script src="../../resources/js-test.js"></script> | |
| 5 </head> | |
| 6 <body> | |
| 7 <p id="description"></p> | |
| 8 <div id="console"></div> | |
| 9 <script> | |
| 10 description('Tests for HTMLTextAreaElement.maxLength behaviors.'); | |
| 11 | |
| 12 var textArea = document.createElement('textarea'); | |
| 13 document.body.appendChild(textArea); | |
| 14 | |
| 15 // No maxlength attribute | |
| 16 shouldBe('textArea.maxLength', '-1'); | |
| 17 | |
| 18 // Invalid maxlength attributes | |
| 19 textArea.setAttribute('maxlength', '-3'); | |
| 20 shouldBe('textArea.maxLength', '-1'); | |
| 21 textArea.setAttribute('maxlength', 'xyz'); | |
| 22 shouldBe('textArea.maxLength', '-1'); | |
| 23 | |
| 24 // Leading whitespaces in maxlength attributes | |
| 25 textArea.setAttribute('maxlength', '\t \n\r1'); | |
| 26 shouldBe('textArea.maxLength', '1'); | |
| 27 textArea.setAttribute('maxlength', "\u20021"); | |
| 28 shouldBe('textArea.maxLength', '-1'); | |
| 29 textArea.setAttribute('maxlength', "\u20091"); | |
| 30 shouldBe('textArea.maxLength', '-1'); | |
| 31 | |
| 32 // Valid maxlength attributes | |
| 33 textArea.setAttribute('maxlength', '1'); | |
| 34 shouldBe('textArea.maxLength', '1'); | |
| 35 textArea.setAttribute('maxlength', '256'); | |
| 36 shouldBe('textArea.maxLength', '256'); | |
| 37 | |
| 38 // Set values to .maxLength | |
| 39 textArea.maxLength = 13; | |
| 40 shouldBe('textArea.getAttribute("maxlength")', '"13"'); | |
| 41 | |
| 42 shouldThrow('textArea.maxLength = -1', '"IndexSizeError: Failed to set the \'max
Length\' property on \'HTMLTextAreaElement\': The value provided (-1) is not pos
itive or 0."'); | |
| 43 shouldBe('textArea.getAttribute("maxlength")', '"13"'); // Not changed | |
| 44 textArea.minLength = 11; | |
| 45 shouldThrow('textArea.maxLength = 10', '"IndexSizeError: Failed to set the \'max
Length\' property on \'HTMLTextAreaElement\': The maxLength provided (10) is les
s than the minimum bound (11)."'); | |
| 46 shouldBe('textArea.getAttribute("maxlength")', '"13"'); // Not changed | |
| 47 shouldBe('textArea.maxLength = 11; textArea.getAttribute("maxlength")', '"11"'); | |
| 48 textArea.minLength = 0; // Remove the minlength value to get it out of the way
of subsequent tests | |
| 49 | |
| 50 textArea.maxLength = null; | |
| 51 shouldBe('textArea.maxLength', '0'); | |
| 52 shouldBe('textArea.getAttribute("maxlength")', '"0"'); | |
| 53 | |
| 54 // maxLength doesn't truncate the default value. | |
| 55 textArea = document.createElement('textarea'); | |
| 56 textArea.setAttribute('maxlength', '3'); | |
| 57 textArea.innerHTML = 'abcd'; | |
| 58 document.body.appendChild(textArea); | |
| 59 shouldBe('textArea.value', '"abcd"'); | |
| 60 | |
| 61 // maxLength doesn't truncate .value | |
| 62 textArea.maxLength = 3; | |
| 63 textArea.value = 'abcde'; | |
| 64 shouldBe('textArea.value', '"abcde"'); | |
| 65 | |
| 66 // Set up for user-input tests | |
| 67 function createFocusedTextAreaWithMaxLength(maxLength) { | |
| 68 if (textArea) | |
| 69 document.body.removeChild(textArea); | |
| 70 textArea = document.createElement('textarea'); | |
| 71 textArea.setAttribute('maxlength', maxLength); | |
| 72 document.body.appendChild(textArea); | |
| 73 textArea.focus(); | |
| 74 } | |
| 75 | |
| 76 // Insert text of which length is maxLength. | |
| 77 createFocusedTextAreaWithMaxLength(3); | |
| 78 document.execCommand('insertText', false, 'abc'); | |
| 79 shouldBe('textArea.value', '"abc"'); | |
| 80 | |
| 81 // Try to add characters to maxLength characters. | |
| 82 createFocusedTextAreaWithMaxLength(3); | |
| 83 textArea.value = 'abc'; | |
| 84 document.execCommand('insertText', false, 'def'); | |
| 85 shouldBe('textArea.value', '"abc"'); | |
| 86 | |
| 87 // Replace text | |
| 88 createFocusedTextAreaWithMaxLength(3); | |
| 89 textArea.value = 'abc'; | |
| 90 document.execCommand('selectAll'); | |
| 91 document.execCommand('insertText', false, 'def'); | |
| 92 shouldBe('textArea.value', '"def"'); | |
| 93 | |
| 94 // Existing value is longer than maxLength. We can't add text. | |
| 95 createFocusedTextAreaWithMaxLength(3); | |
| 96 textArea.value = 'abcdef'; | |
| 97 document.execCommand('insertText', false, 'ghi'); | |
| 98 shouldBe('textArea.value', '"abcdef"'); | |
| 99 | |
| 100 // We can delete a character in the longer value. | |
| 101 createFocusedTextAreaWithMaxLength(3); | |
| 102 textArea.value = 'abcdef'; | |
| 103 document.execCommand('delete'); | |
| 104 shouldBe('textArea.value', '"abcde"'); | |
| 105 | |
| 106 // A linebreak is 1 character. | |
| 107 createFocusedTextAreaWithMaxLength(4); | |
| 108 document.execCommand('insertText', false, 'A'); | |
| 109 document.execCommand('insertLineBreak'); | |
| 110 document.execCommand('insertText', false, 'B'); | |
| 111 shouldBe('textArea.value', '"A\\nB"'); | |
| 112 | |
| 113 // Confirms correct count for close linebreaks inputs. | |
| 114 createFocusedTextAreaWithMaxLength(3); | |
| 115 textArea.innerHTML = 'a\n\n'; | |
| 116 document.execCommand('insertLineBreak'); | |
| 117 shouldBe('textArea.value', '"a\\n\\n"'); | |
| 118 | |
| 119 // Confirms correct count for open consecutive linebreaks inputs. | |
| 120 createFocusedTextAreaWithMaxLength(6); | |
| 121 document.execCommand('insertLineBreak'); | |
| 122 document.execCommand('insertLineBreak'); | |
| 123 document.execCommand('insertLineBreak'); | |
| 124 document.execCommand('insertLineBreak'); | |
| 125 shouldBe('textArea.value', '"\\n\\n\\n"'); | |
| 126 | |
| 127 // According to the HTML5 specification, maxLength is code-point length. | |
| 128 // Blink follows it though WebKit handles it as grapheme length. | |
| 129 | |
| 130 // fancyX should be treated as 1 grapheme. | |
| 131 var fancyX = "x\u0305\u0332";// + String.fromCharCode(0x305) + String.fromCharCo
de(0x332); | |
| 132 // u10000 is one character consisted of a surrogate pair. | |
| 133 var u10000 = "\ud800\udc00"; | |
| 134 | |
| 135 debug('Inserts 2 normal characters + a combining letter with 3 code points into
a maxlength=3 element.') | |
| 136 createFocusedTextAreaWithMaxLength(3); | |
| 137 document.execCommand('insertText', false, 'AB' + fancyX); | |
| 138 shouldBeEqualToString('textArea.value', 'ABx'); | |
| 139 shouldBe('textArea.value.length', '3'); | |
| 140 | |
| 141 createFocusedTextAreaWithMaxLength(3); | |
| 142 textArea.value = 'AB' + fancyX; | |
| 143 textArea.setSelectionRange(2, 5); // Select fancyX | |
| 144 document.execCommand('insertText', false, 'CDE'); | |
| 145 shouldBe('textArea.value', '"ABC"'); | |
| 146 | |
| 147 debug('Inserts 2 normal characters + one surrogate pair into a maxlength=3 eleme
nt'); | |
| 148 createFocusedTextAreaWithMaxLength(3); | |
| 149 document.execCommand('insertText', false, 'AB' + u10000); | |
| 150 shouldBeEqualToString('textArea.value', 'AB'); | |
| 151 shouldBe('textArea.value.length', '2'); | |
| 152 | |
| 153 createFocusedTextAreaWithMaxLength(3); | |
| 154 textArea.value = 'AB' + u10000; | |
| 155 textArea.setSelectionRange(2, 4); // Select u10000 | |
| 156 document.execCommand('insertText', false, 'CDE'); | |
| 157 shouldBe('textArea.value', '"ABC"'); | |
| 158 | |
| 159 // In the case maxlength=0 | |
| 160 createFocusedTextAreaWithMaxLength(0); | |
| 161 textArea.value = ''; | |
| 162 document.execCommand('insertText', false, 'ABC'); | |
| 163 shouldBe('textArea.value', '""'); | |
| 164 | |
| 165 // In the case maxlength='' | |
| 166 createFocusedTextAreaWithMaxLength(''); | |
| 167 textArea.value = ''; | |
| 168 document.execCommand('insertText', false, 'ABC'); | |
| 169 shouldBe('textArea.value', '"ABC"'); | |
| 170 | |
| 171 // In the case maxlength='invalid' | |
| 172 createFocusedTextAreaWithMaxLength('invalid'); | |
| 173 textArea.value = ''; | |
| 174 document.execCommand('insertText', false, 'ABC'); | |
| 175 shouldBe('textArea.value', '"ABC"'); | |
| 176 </script> | |
| 177 </body> | |
| 178 </html> | |
| OLD | NEW |