/[suikacvs]/www/test/html/progress/reqs/test.html
Suika

Contents of /www/test/html/progress/reqs/test.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download) (as text)
Sun Oct 18 07:44:15 2009 UTC (15 years, 9 months ago) by wakaba
Branch: MAIN
File MIME type: text/html
New

1 <!DOCTYPE HTML>
2 <title>&lt;progress> processing and authoring requirements</title>
3
4 <script>
5
6 // Web Applications 1.0 Revision 4116, 12 October 2009
7
8 var whiteSpace = /\s/; // XXX White_Space != \s
9 var denominatorPunctuationCharacter = /[\u0025\u066A\uFE6A\uFF05\u2030\u2031]/;
10
11 function findingOneOrTwoNumbersOfARatioInAString (string) {
12 // 1. If the string is empty, then return nothing and abort these steps.
13 if (string == '') {
14 return {isNothing: true, step: 1};
15 }
16
17 // 2. Find a number in the string according to the algorithm below, starting at the start of the string.
18 var position = 0;
19 var s2 = findANumber (string, position);
20
21 // 3. If the sub-algorithm in step 2 returned nothing or returned an error condition, return nothing and abort these steps.
22 if (s2.isNothing || s2.isError) {
23 return {isNothing: true, step: 3};
24 }
25
26 // 4. Set number1 to the number returned by the sub-algorithm in step 2.
27 var number1 = s2.number;
28
29 // 5. Starting with the character immediately after the last one examined by the sub-algorithm in step 2, skip all White_Space characters in the string (this might match zero characters).
30 position = s2.position;
31 while (position < string.length && string.charAt (position).match (whiteSpace)) {
32 position++;
33 }
34
35 // 6. If there are still further characters in the string, and the next character in the string is a valid denominator punctuation character, set denominator to that character.
36 var denominator = null;
37 if (position < string.length && string.charAt (position).match (denominatorPunctuationCharacter)) {
38 denominator = string.charAt (position);
39 }
40
41 // 7. If the string contains any other characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), but denominator was given a value in the step 6, return nothing and abort these steps.
42 if (string.substring (position).match (/[0-9]/) && denominator != null) {
43 return {isNothing: true, step: 7};
44 }
45
46 // 8. Otherwise, if denominator was given a value in step 6, return number1 and denominator and abort these steps.
47 if (denominator != null) {
48 return {number1: number1, denominator: denominator, step: 8};
49 }
50
51 // 9. Find a number in the string again, starting immediately after the last character that was examined by the sub-algorithm in step 2.
52 var s9 = findANumber (string, position);
53
54 // 10. If the sub-algorithm in step 9 returned nothing or an error condition, return number1 and abort these steps.
55 if (s9.isNothing || s9.isError) {
56 return {number1: number1, step: 10};
57 }
58
59 // 11. Set number2 to the number returned by the sub-algorithm in step 9.
60 var number2 = s9.number;
61
62 // 12. Starting with the character immediately after the last one examined by the sub-algorithm in step 9, skip all White_Space characters in the string (this might match zero characters).
63 position = s9.position;
64 while (position < string.length && string.charAt (position).match (whiteSpace)) {
65 position++;
66 }
67
68 // 13. If there are still further characters in the string, and the next character in the string is a valid denominator punctuation character, return nothing and abort these steps.
69 if (position < string.length && string.charAt (position).match (denominatorPunctuationCharacter)) {
70 return {isNothing: true, step: 13};
71 }
72
73 // 14. If the string contains any other characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), return nothing and abort these steps.
74 if (string.substring (position).match (/[0-9]/)) {
75 return {isNothing: true, step: 14};
76 }
77
78 // 15. Otherwise, return number1 and number2.
79 return {number1: number1, number2: number2, step: 15};
80 } // findingOneOrTwoNumbersOfARatioInAString
81
82 function findANumber (givenString, position) {
83 // 1. Starting at the given starting position, ignore all characters in the given string until the first character that is either a U+002E FULL STOP or one of the ten characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9).
84 while (position < givenString.length && !givenString.charAt (position).match (/[0-9.]/)) {
85 position++;
86 }
87
88 // 2. If there are no such characters, return nothing and abort these steps.
89 if (position < givenString.length && givenString.charAt (position).match (/[0-9.]/)) {
90 //
91 } else {
92 return {isNothing: true, position: position};
93 }
94
95 // 3. Starting with the character matched in step 1, collect all the consecutive characters that are either a U+002E FULL STOP or one of the ten characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), and assign this string of one or more characters to string.
96 var string = '';
97 while (position < givenString.length && givenString.charAt (position).match (/[0-9.]/)) {
98 string += givenString.charAt (position);
99 position++;
100 }
101
102 // 4. If string consists of just a single U+002E FULL STOP character or if it contains more than one U+002E FULL STOP character then return an error condition and abort these steps.
103 if (string == '.' || string.match (/\..*\./)) {
104 return {isError: true, position: position};
105 }
106
107 // 5. Parse string according to the rules for parsing floating point number values, to obtain number. This step cannot fail (string is guaranteed to be a valid floating point number).
108 var s5 = parseFloatingPointNumberValue (string);
109 var number = s5.value;
110
111 // 6. Return number.
112 return {number: number, position: position};
113 } // findANumber
114
115 function parseFloatingPointNumberValue (input) {
116 // 1. Let input be the string being parsed.
117 //
118
119 // 2. Let position be a pointer into input, initially pointing at the start of the string.
120 var position = 0;
121
122 // 3. Let value have the value 1.
123 var value = 1;
124
125 // 4. Let divisor have the value 1.
126 var divisor = 1;
127
128 // 5. Let exponent have the value 1.
129 var exponent = 1;
130
131 // 6. Skip whitespace.
132 var s6 = skipWhitespace (input, position);
133 position = s6.position;
134
135 // 7. If position is past the end of input, return an error.
136 if (position >= input.length) {
137 return {isError: true};
138 }
139
140 // 8. If the character indicated by position is a U+002D HYPHEN-MINUS character (-):
141 if (input.charAt (position) == '-') {
142 // 1. Change value and divisor to −1.
143 value = -1;
144 divisor = -1;
145
146 // 2. Advance position to the next character.
147 position++;
148
149 // 3. If position is past the end of input, return an error.
150 if (position >= input.length) {
151 return {isError: true};
152 }
153 }
154
155 // 9. If the character indicated by position is not one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then return an error.
156 if (!input.charAt (position).match (/[0-9]/)) {
157 return {isError: true};
158 }
159
160 // 10. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), and interpret the resulting sequence as a base-ten integer. Multiply value by that integer.
161 var s10 = collectASequenceOfCharacters (/[0-9]/, input, position);
162 position = s10.position;
163 value *= parseInt (s10.result);
164
165 // 11. If position is past the end of input, return value.
166 if (position >= input.length) {
167 return {value: value};
168 }
169
170 // 12. If the character indicated by position is a U+002E FULL STOP (.), run these substeps:
171 if (input.charAt (position) == '.') {
172 // 1. Advance position to the next character.
173 position++;
174
175 // 2. If position is past the end of input, or if the character indicated by position is not one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then return value.
176 if (position >= input.length ||
177 !input.charAt (position).match (/[0-9]/)) {
178 return {value: value};
179 }
180
181 // 3. Fraction loop: Multiply divisor by ten.
182 var fractionLoop = true;
183 while (fractionLoop) {
184 divisor *= 10;
185
186 // 4. Add the value of the current character interpreted as a base-ten digit (0..9) divided by divisor, to value.
187 value += parseInt (input.charAt (position)) / divisor;
188
189 // 5. Advance position to the next character.
190 position++;
191
192 // 6. If position is past the end of input, then return value.
193 if (position >= input.length) {
194 return {value: value};
195 }
196
197 // 7. If the character indicated by position is one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), return to the step labeled fraction loop in these substeps.
198 if (input.charAt (position).match (/[0-9]/)) {
199 fractionLoop = true;
200 } else {
201 fractionLoop = false;
202 }
203 }
204 }
205
206 // 13. If the character indicated by position is a U+0065 LATIN SMALL LETTER E character (e) or a U+0045 LATIN CAPITAL LETTER E character (E), run these substeps:
207 if (input.charAt (position).match (/[eE]/)) {
208 // 1. Advance position to the next character.
209 position++;
210
211 // 2. If position is past the end of input, then return value.
212 if (position >= input.length) {
213 return {value: value};
214 }
215
216 // 3. If the character indicated by position is a U+002D HYPHEN-MINUS character (-):
217 if (input.charAt (position) == '-') {
218 // 1. Change exponent to −1.
219 exponent = -1;
220
221 // 2. Advance position to the next character.
222 position++;
223
224 // 3. If position is past the end of input, then return value.
225 if (position >= input.length) {
226 return {value: value};
227 }
228
229 // Otherwise, if the character indicated by position is a U+002B PLUS SIGN character (+):
230 } else if (input.charAt (position) == '+') {
231 // 1. Advance position to the next character.
232 position++;
233
234 // 2. If position is past the end of input, then return value.
235 if (position >= input.length) {
236 return {value: value};
237 }
238 }
239
240 // 4. If the character indicated by position is not one of U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then return value.
241 if (!input.charAt (position).match (/[0-9]/)) {
242 return {value: value};
243 }
244
245 // 5. Collect a sequence of characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), and interpret the resulting sequence as a base-ten integer. Multiply exponent by that integer.
246 var s13_5 = collectASequenceOfCharacters (/[0-9]/, input, position);
247 position = s13_5.position;
248 exponent *= parseInt (s13_5.result);
249
250 // 6. Multiply value by ten raised to the exponentth power.
251 value *= Math.pow (10, exponent);
252 }
253
254 // 14. Return value.
255 return {value: value};
256 } // parseFloatingPointNumberValue
257
258 function skipWhitespace (input, position) {
259 return collectASequenceOfCharacters (/[\u0009\u000A\u000C\u000D\u0020]/, input, position);
260 } // skipWhitespace
261
262 function collectASequenceOfCharacters (characters, input, position) {
263 // 1. Let input and position be the same variables as those of the same name in the algorithm that invoked these steps.
264 //
265
266 // 2. Let result be the empty string.
267 var result = '';
268
269 // 3. While position doesn't point past the end of input and the character at position is one of the characters, append that character to the end of result and advance position to the next character in input.
270 while (position < input.length && input.charAt (position).match (characters)) {
271 result += input.charAt (position);
272 position++;
273 }
274
275 // 4. Return result.
276 return {result: result, position: position};
277 } // collectASequenceOfCharacters
278
279 function tokenizeProgressContent (string) {
280 var position = 0;
281 var tokens = [];
282 var lastToken = {type: 'initial', value: ''};
283 while (position < string.length) {
284 var char = string.charAt (position);
285 var tokenType;
286 if (char.match (/[0-9]/)) {
287 tokenType = 'number';
288 } else if (char.match (/\./)) {
289 if (lastToken.type == 'number' && !lastToken.value.match (/\./)) {
290 tokenType = 'number';
291 } else {
292 tokenType = 'dot';
293 }
294 } else if (char.match (whiteSpace)) {
295 if (lastToken.type == 'number' || lastToken.type == 'whitespace') {
296 tokenType = 'whitespace';
297 } else {
298 tokenType = 'string';
299 }
300 } else if (char.match (denominatorPunctuationCharacter) && (lastToken.type == 'whitespace' || lastToken.type == 'number')) {
301 tokenType = 'denominator';
302 } else {
303 tokenType = 'string';
304 }
305 if (tokenType == lastToken.type) {
306 lastToken.value += char;
307 } else {
308 lastToken = {type: tokenType, value: char};
309 tokens.push (lastToken);
310 }
311 position++;
312 }
313
314 return tokens;
315 } // tokenizeProgressContent
316
317 function extractNumbersFromTokens (tokens) {
318 var number1 = undefined;
319 var number2 = undefined;
320 var denominator = undefined;
321 for (var i = 0; i < tokens.length; i++) {
322 var token = tokens[i];
323 if (token.type == 'number') {
324 if (number1 == undefined) {
325 number1 = parseFloat (token.value);
326 } else if (denominator != undefined) {
327 return {isNothing: true};
328 } else if (number2 == undefined) {
329 number2 = parseFloat (token.value);
330 } else {
331 return {isNothing: true};
332 }
333 } else if (token.type == 'denominator') {
334 if (number2 != undefined) {
335 return {isNothing: true};
336 } else {
337 denominator = token.value;
338 }
339 } else if (token.type == 'dot') {
340 return {isNothing: true};
341 }
342 }
343
344 if (number1 == undefined) {
345 return {isNothing: true};
346 } else {
347 return {number1: number1, number2: number2, denominator: denominator};
348 }
349 } // extractNumbersFromTokens
350
351 function objectToString (object) {
352 return self.JSON ? JSON.stringify (object) : object.toSource ? object.toSource () : object.toString ();
353 } // objectToString
354
355 function processProgressContent (string) {
356 var result = {};
357
358 var ua = findingOneOrTwoNumbersOfARatioInAString (string);
359 for (var i in ua) {
360 result['ua-' + i] = ua[i];
361 }
362
363 var tokens = tokenizeProgressContent (string);
364 result['author-tokens'] = objectToString (tokens);
365 var author = extractNumbersFromTokens (tokens);
366 for (var i in author) {
367 result['author-' + i] = author[i];
368 }
369
370 return result;
371 } // processProgressContent
372
373 function update (form) {
374 var input = form.elements.input.value;
375
376 var result = processProgressContent (input);
377
378 var outputs = form.getElementsByTagName ('output');
379 for (var i = 0; i < outputs.length; i++) {
380 var output = outputs[i];
381 var name = output.getAttribute ('name');
382 var value = result[name];
383 if (value === undefined) {
384 output.textContent = '(undefined)';
385 } else if (value === null) {
386 output.textContent = '(null)';
387 } else if (value === '') {
388 output.textContent = '(empty)';
389 } else {
390 output.textContent = value;
391 }
392 }
393 } // update
394
395 </script>
396
397 <form>
398 <p><input name=input onchange="update (this.form)">
399
400 <fieldset>
401 <legend>From UA parsing rules</legend>
402
403 <p><code>step</code>: <output name=ua-step></output>
404 <p><code>isNothing</code>: <output name=ua-isNothing></output>
405 <p><code>number1</code>: <output name=ua-number1></output>
406 <p><code>number2</code>: <output name=ua-number2></output>
407 <p><code>denominator</code>: <output name=ua-denominator></output>
408 </fieldset>
409
410 <fieldset>
411 <legend>From author requirements</legend>
412
413 <p><code>isNothing</code>: <output name=author-isNothing></output>
414 <p><code>number1</code>: <output name=author-number1></output>
415 <p><code>number2</code>: <output name=author-number2></output>
416 <p><code>denominator</code>: <output name=author-denominator></output>
417 <p>Tokens: <output name=author-tokens></output>
418 </fieldset>
419 </form>
420
421 <script>
422 if (location.href.match (/#/)) {
423 var fragment = decodeURIComponent (location.href.split (/#/, 2)[1]);
424 document.forms[0].elements.input.value = fragment;
425 update (document.forms[0]);
426 }
427 </script>

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24