OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 #import('dart:html'); |
| 6 #import('template.dart'); |
| 7 #import('../lib/file_system_memory.dart'); |
| 8 |
| 9 String currSampleTemplate; |
| 10 |
| 11 void changeTemplate() { |
| 12 final Document doc = window.document; |
| 13 final SelectElement samples = doc.query('#templateSamples'); |
| 14 final TextAreaElement template = doc.query('#template'); |
| 15 template.value = sample(samples.value); |
| 16 } |
| 17 |
| 18 String sample(String sampleName) { |
| 19 final String each = '\${#each'; |
| 20 final String endEach = '\${/each}'; |
| 21 final String with = '\${#with'; |
| 22 final String endWith = '\${/with}'; |
| 23 |
| 24 final String simpleTemplate = ''' |
| 25 template NameEntry(String name, int age) { |
| 26 <div var=topDiv attr="test" attr1=test1 attr2='test2' attr3=test3> |
| 27 <span var=spanElem>\${name}</span> |
| 28 <span>-</span> |
| 29 <span>\${age}</span> |
| 30 </div> |
| 31 } |
| 32 '''; |
| 33 |
| 34 final String simpleTemplate2 = ''' |
| 35 template NameEntry(String name, int age) { |
| 36 <div var=topDiv attr="test" attr1=test1 attr2='test2' attr3=test3> |
| 37 <h1> |
| 38 <h2> |
| 39 <h3> |
| 40 <span var=spanElem>\${name}</span> |
| 41 <span>-</span> |
| 42 <span>\${age}</span> |
| 43 </h3> |
| 44 </h2> |
| 45 </h1> |
| 46 </div> |
| 47 } |
| 48 '''; |
| 49 |
| 50 final String simpleTemplateCSS = ''' |
| 51 template NameEntry(String name, int age) { |
| 52 css { |
| 53 .foo { |
| 54 left: 10px; |
| 55 } |
| 56 } |
| 57 <div var=topDiv attr="test" attr1=test1 attr2='test2' attr3=test3> |
| 58 <span var=spanElem>\${name}</span> |
| 59 <span>-</span> |
| 60 <span>\${age}</span> |
| 61 </div> |
| 62 } |
| 63 '''; |
| 64 |
| 65 |
| 66 final String eachTemplate = ''' |
| 67 template Applications(var products) { |
| 68 <div> |
| 69 ${each} products} |
| 70 <div> |
| 71 <span>\${name}</span> |
| 72 <span>-</span> |
| 73 <span>\${users}</span> |
| 74 </div> |
| 75 ${endEach} |
| 76 </div> |
| 77 } |
| 78 '''; |
| 79 |
| 80 final String withTemplate = ''' |
| 81 template Product(Person person) { |
| 82 <div> |
| 83 ${with} person} |
| 84 <div> |
| 85 <span>\${name}</span> |
| 86 <span>-</span> |
| 87 <span>\${age}</span> |
| 88 </div> |
| 89 ${endWith} |
| 90 </div> |
| 91 } |
| 92 '''; |
| 93 |
| 94 final String withTemplate2 = ''' |
| 95 template Product(Person person) { |
| 96 <div> |
| 97 <span var=a1> |
| 98 <h1> |
| 99 ${with} person} |
| 100 <div> |
| 101 <span>\${name}</span> |
| 102 <span>-</span> |
| 103 <span>\${age}</span> |
| 104 </div> |
| 105 ${endWith} |
| 106 </h1> |
| 107 </span> |
| 108 </div> |
| 109 } |
| 110 '''; |
| 111 |
| 112 final String complexTemplate = ''' |
| 113 template ProductsForPerson(Person person, var products) { |
| 114 <div> |
| 115 ${with} person} |
| 116 <div> |
| 117 <span>\${name}</span> |
| 118 <span>-</span> |
| 119 <span>\${age}</span> |
| 120 </div> |
| 121 ${each} products} |
| 122 <div> |
| 123 <span>product=\${name},users=\${users}</span> |
| 124 </div> |
| 125 ${endEach} |
| 126 ${endWith} |
| 127 </div> |
| 128 } |
| 129 '''; |
| 130 |
| 131 final String complexTemplate2 = ''' |
| 132 template ProductsForPerson(Person person, var products) { |
| 133 <div> |
| 134 ${with} person} |
| 135 <div> |
| 136 <span>\${name}</span> |
| 137 <span>-</span> |
| 138 <span>\${age}</span> |
| 139 </div> |
| 140 <div> |
| 141 ${each} products} |
| 142 <span>product=\${name},users=\${users}</span> |
| 143 ${endEach} |
| 144 </div> |
| 145 ${endWith} |
| 146 </div> |
| 147 } |
| 148 '''; |
| 149 |
| 150 final String complexTemplate3 = ''' |
| 151 template ProductsForPerson(Person person, var products) { |
| 152 css { |
| 153 .sales-item { |
| 154 font-family: arial; |
| 155 background-color: lightgray; |
| 156 margin-left: 10px; |
| 157 border-bottom: 1px solid white; |
| 158 } |
| 159 .ytd-sales { |
| 160 position: absolute; |
| 161 left: 100px; |
| 162 } |
| 163 } |
| 164 <div> |
| 165 ${with} person} |
| 166 <div> |
| 167 <span>\${name}</span> |
| 168 <span>-</span> |
| 169 <span>\${age}</span> |
| 170 </div> |
| 171 <div> |
| 172 ${each} products} |
| 173 <div>product=\${name},users=\${users}</div> |
| 174 ${each} products.sales} |
| 175 <div class="sales-item"> |
| 176 <span>\${country}</span> |
| 177 <span class="ytd-sales">\\\$\${yearly}</span> |
| 178 </div> |
| 179 ${endEach} |
| 180 ${endEach} |
| 181 </div> |
| 182 ${endWith} |
| 183 </div> |
| 184 } |
| 185 |
| 186 |
| 187 template NameEntry(String name, int age) { |
| 188 css { |
| 189 .name-item { |
| 190 font-size: 18pt; |
| 191 font-weight: bold; |
| 192 } |
| 193 } |
| 194 <div var=topDiv class="name-item" attr="test" attr1=test1 attr2='test2' attr3=
test3> |
| 195 <span var=spanElem>\${name}</span> |
| 196 <span> - </span> |
| 197 <span>\${age}</span> |
| 198 </div> |
| 199 } |
| 200 '''; |
| 201 |
| 202 // Test #each in a #each where the nested #each is a top-level child of the |
| 203 // outer #each. |
| 204 final String complexTemplate4 = ''' |
| 205 template DivisionSales(var divisions) { |
| 206 <div> |
| 207 \${#each divisions} |
| 208 <div> |
| 209 <span>\${name}</span> |
| 210 <span>-</span> |
| 211 <span>\${id}</span> |
| 212 </div> |
| 213 <div> |
| 214 \${#each divisions.products} |
| 215 <div> |
| 216 <span var=productItem>▶</span> |
| 217 <span>Product</span> |
| 218 <span>\${name}</span> |
| 219 <span>\${users} users</span> |
| 220 </div> |
| 221 \${#each products.sales} |
| 222 <div> |
| 223 <span>\${country}</span> |
| 224 <span>\\\$\${yearly}</span> |
| 225 </div> |
| 226 \${/each} |
| 227 \${/each} |
| 228 </div> |
| 229 \${/each} |
| 230 </div> |
| 231 } |
| 232 '''; |
| 233 |
| 234 |
| 235 final String realWorldList = ''' |
| 236 template DivisionSales(var divisions) { |
| 237 css { |
| 238 .division-item { |
| 239 background-color: #bbb; |
| 240 border-top: 2px solid white; |
| 241 line-height: 20pt; |
| 242 padding-left: 5px; |
| 243 } |
| 244 .product-item { |
| 245 background-color: lightgray; |
| 246 margin-left: 10px; |
| 247 border-top: 2px solid white; |
| 248 line-height: 20pt; |
| 249 } |
| 250 .product-title { |
| 251 position: absolute; |
| 252 left: 45px; |
| 253 } |
| 254 .product-name { |
| 255 font-weight: bold; |
| 256 position: absolute; |
| 257 left: 100px; |
| 258 } |
| 259 .product-users { |
| 260 position: absolute; |
| 261 left: 150px; |
| 262 font-style: italic; |
| 263 color: gray; |
| 264 width: 110px; |
| 265 } |
| 266 .expand-collapse { |
| 267 margin-left: 5px; |
| 268 margin-right: 5px; |
| 269 vertical-align: top; |
| 270 cursor: pointer; |
| 271 } |
| 272 .expand { |
| 273 font-size: 9pt; |
| 274 } |
| 275 .collapse { |
| 276 font-size: 8pt; |
| 277 } |
| 278 .show-sales { |
| 279 display: inherit; |
| 280 } |
| 281 .hide-sales { |
| 282 display: none; |
| 283 } |
| 284 .sales-item { |
| 285 font-family: arial; |
| 286 background-color: lightgray; |
| 287 margin-left: 10px; |
| 288 border-top: 1px solid white; |
| 289 line-height: 18pt; |
| 290 padding-left: 5px; |
| 291 } |
| 292 .ytd-sales { |
| 293 position: absolute; |
| 294 left: 100px; |
| 295 } |
| 296 } |
| 297 <div> |
| 298 \${#each divisions} |
| 299 <div class="division-item"> |
| 300 <span>\${name}</span> |
| 301 <span>-</span> |
| 302 <span>\${id}</span> |
| 303 </div> |
| 304 <div> |
| 305 \${#each divisions.products} |
| 306 <div class="product-item"> |
| 307 <span var=productZippy class="expand-collapse expand">▼</span> |
| 308 <span class='product-title'>Product</span> |
| 309 <span class="product-name">\${name}</span> |
| 310 <span class="product-users" align=right>\${users} users</span> |
| 311 <div class="show-sales"> |
| 312 \${#each products.sales} |
| 313 <div class="sales-item"> |
| 314 <span>\${country}</span> |
| 315 <span class="ytd-sales">\\\$\${yearly}</span> |
| 316 </div> |
| 317 \${/each} |
| 318 </div> |
| 319 </div> |
| 320 \${/each} |
| 321 </div> |
| 322 \${/each} |
| 323 </div> |
| 324 } |
| 325 |
| 326 template Header(String company, Date date) { |
| 327 css { |
| 328 .header { |
| 329 background-color: slateGray; |
| 330 font-family: arial; |
| 331 color: lightgray; |
| 332 font-weight: bold; |
| 333 padding-top: 20px; |
| 334 } |
| 335 } |
| 336 <div class='header' align=center> |
| 337 <h2>\${company}</h2> |
| 338 <div align=right>\${date}</div> |
| 339 </div> |
| 340 } |
| 341 '''; |
| 342 |
| 343 switch (sampleName) { |
| 344 case "simple": |
| 345 return simpleTemplate; |
| 346 case "simple2": |
| 347 return simpleTemplate2; |
| 348 case "simpleCSS": |
| 349 return simpleTemplateCSS; |
| 350 case "with": |
| 351 return withTemplate; |
| 352 case "with2": |
| 353 return withTemplate2; |
| 354 case "list": |
| 355 return eachTemplate; |
| 356 case "complex": |
| 357 return complexTemplate; |
| 358 case "complex2": |
| 359 return complexTemplate2; |
| 360 case "complex3": |
| 361 return complexTemplate3; |
| 362 case "complex4": |
| 363 return complexTemplate4; |
| 364 case "realWorldList": |
| 365 return realWorldList; |
| 366 default: |
| 367 print("ERROR: Unknown sample template"); |
| 368 } |
| 369 } |
| 370 |
| 371 void runTemplate([bool debug = false, bool parseOnly = false]) { |
| 372 final Document doc = window.document; |
| 373 final TextAreaElement dartClass = doc.query("#dart"); |
| 374 final TextAreaElement template = doc.query('#template'); |
| 375 final TableCellElement validity = doc.query('#validity'); |
| 376 final TableCellElement result = doc.query('#result'); |
| 377 |
| 378 bool templateValid = true; |
| 379 StringBuffer dumpTree = new StringBuffer(); |
| 380 StringBuffer code = new StringBuffer(); |
| 381 String htmlTemplate = template.value; |
| 382 |
| 383 if (debug) { |
| 384 try { |
| 385 List<Template> templates = templateParseAndValidate(htmlTemplate); |
| 386 for (var tmpl in templates) { |
| 387 dumpTree.add(tmpl.toDebugString()); |
| 388 } |
| 389 |
| 390 // Generate the Dart class(es) for all template(s). |
| 391 // Pass in filename of 'foo' for testing in UITest. |
| 392 code.add(Codegen.generate(templates, 'foo')); |
| 393 } catch (final htmlException) { |
| 394 // TODO(terry): TBD |
| 395 print("ERROR unhandled EXCEPTION"); |
| 396 } |
| 397 } |
| 398 |
| 399 /* |
| 400 if (!debug) { |
| 401 try { |
| 402 cssParseAndValidate(cssExpr, cssWorld); |
| 403 } catch (final cssException) { |
| 404 templateValid = false; |
| 405 dumpTree = cssException.toString(); |
| 406 } |
| 407 } else if (parseOnly) { |
| 408 try { |
| 409 Parser parser = new Parser(new lang.SourceFile( |
| 410 lang.SourceFile.IN_MEMORY_FILE, cssExpr)); |
| 411 Stylesheet stylesheet = parser.parse(); |
| 412 StringBuffer stylesheetTree = new StringBuffer(); |
| 413 String prettyStylesheet = stylesheet.toString(); |
| 414 stylesheetTree.add("${prettyStylesheet}\n"); |
| 415 stylesheetTree.add("\n============>Tree Dump<============\n"); |
| 416 stylesheetTree.add(stylesheet.toDebugString()); |
| 417 dumpTree = stylesheetTree.toString(); |
| 418 } catch (final cssParseException) { |
| 419 templateValid = false; |
| 420 dumpTree = cssParseException.toString(); |
| 421 } |
| 422 } else { |
| 423 try { |
| 424 dumpTree = cssParseAndValidateDebug(cssExpr, cssWorld); |
| 425 } catch (final cssException) { |
| 426 templateValid = false; |
| 427 dumpTree = cssException.toString(); |
| 428 } |
| 429 } |
| 430 */ |
| 431 |
| 432 final bgcolor = templateValid ? "white" : "red"; |
| 433 final color = templateValid ? "black" : "white"; |
| 434 final valid = templateValid ? "VALID" : "NOT VALID"; |
| 435 String resultStyle = "resize: none; margin: 0; height: 100%; width: 100%;" |
| 436 "padding: 5px 7px;"; |
| 437 |
| 438 result.innerHTML = ''' |
| 439 <textarea style="${resultStyle}">${dumpTree.toString()}</textarea> |
| 440 '''; |
| 441 |
| 442 dartClass.value = code.toString(); |
| 443 } |
| 444 |
| 445 void main() { |
| 446 final element = new Element.tag('div'); |
| 447 |
| 448 element.innerHTML = ''' |
| 449 <table style="width: 100%; height: 100%;"> |
| 450 <tbody> |
| 451 <tr> |
| 452 <td style="vertical-align: top; width: 50%; padding-right: 7px;"> |
| 453 <table style="height: 100%; width: 100%;" cellspacing=0 cellpadding=
0 border=0> |
| 454 <tbody> |
| 455 <tr style="vertical-align: top; height: 1em;"> |
| 456 <td> |
| 457 <span style="font-weight:bold;">Generated Dart</span> |
| 458 </td> |
| 459 </tr> |
| 460 <tr> |
| 461 <td> |
| 462 <textarea id="dart" style="resize: none; width: 100%; height
: 100%; padding: 5px 7px;"></textarea> |
| 463 </td> |
| 464 </tr> |
| 465 </tbody> |
| 466 </table> |
| 467 </td> |
| 468 <td> |
| 469 <table style="width: 100%; height: 100%;" cellspacing=0 cellpadding=
0 border=0> |
| 470 <tbody> |
| 471 <tr style="vertical-align: top; height: 50%;"> |
| 472 <td> |
| 473 <table style="width: 100%; height: 100%;" cellspacing=0 cell
padding=0 border=0> |
| 474 <tbody> |
| 475 <tr> |
| 476 <td> |
| 477 <span style="font-weight:bold;">HTML Template</span> |
| 478 </td> |
| 479 </tr> |
| 480 <tr style="height: 100%;"> |
| 481 <td> |
| 482 <textarea id="template" style="resize: none; width:
100%; height: 100%; padding: 5px 7px;">${sample("simple")}</textarea> |
| 483 </td> |
| 484 </tr> |
| 485 </tbody> |
| 486 </table> |
| 487 </td> |
| 488 </tr> |
| 489 |
| 490 <tr style="vertical-align: top; height: 50px;"> |
| 491 <td> |
| 492 <table> |
| 493 <tbody> |
| 494 <tr> |
| 495 <td> |
| 496 <button id=generate>Generate</button> |
| 497 </td> |
| 498 <td align="right"> |
| 499 <select id=templateSamples> |
| 500 <option value="simple">Simple Template</option> |
| 501 <option value="simple2">Simple Template #2</option
> |
| 502 <option value="simpleCSS">Simple Template w/ CSS</
option> |
| 503 <option value="with">With Template</option> |
| 504 <option value="with2">With Template #2</option> |
| 505 <option value="list">List Template</option> |
| 506 <option value="complex">Complex Template</option> |
| 507 <option value="complex2">Complex Template #2</opti
on> |
| 508 <option value="complex3">Complex Template #3 w/ CS
S</option> |
| 509 <option value="complex4">Complex Template #4</opti
on> |
| 510 <option value="realWorldList">Real world</option> |
| 511 </select> |
| 512 </td> |
| 513 </tr> |
| 514 </tbody> |
| 515 </table> |
| 516 </td> |
| 517 </tr> |
| 518 |
| 519 <tr style="vertical-align: top;"> |
| 520 <td> |
| 521 <table style="width: 100%; height: 100%;" border="0" cellpad
ding="0" cellspacing="0"> |
| 522 <tbody> |
| 523 <tr style="vertical-align: top; height: 1em;"> |
| 524 <td> |
| 525 <span style="font-weight:bold;">Parse Tree</span> |
| 526 </td> |
| 527 </tr> |
| 528 <tr style="vertical-align: top; height: 1em;"> |
| 529 <td id="validity"> |
| 530 </td> |
| 531 </tr> |
| 532 <tr> |
| 533 <td id="result"> |
| 534 <textarea style="resize: none; width: 100%; height:
100%; border: black solid 1px; padding: 5px 7px;"></textarea> |
| 535 </td> |
| 536 </tr> |
| 537 </tbody> |
| 538 </table> |
| 539 </td> |
| 540 </tr> |
| 541 </tbody> |
| 542 </table> |
| 543 </td> |
| 544 </tr> |
| 545 </tbody> |
| 546 </table> |
| 547 '''; |
| 548 |
| 549 document.body.style.setProperty("background-color", "lightgray"); |
| 550 document.body.elements.add(element); |
| 551 |
| 552 ButtonElement genElem = window.document.query('#generate'); |
| 553 genElem.on.click.add((MouseEvent e) { |
| 554 runTemplate(true, true); |
| 555 }); |
| 556 |
| 557 SelectElement cannedTemplates = window.document.query('#templateSamples'); |
| 558 cannedTemplates.on.change.add((e) { |
| 559 changeTemplate(); |
| 560 }); |
| 561 |
| 562 parseOptions([], null); |
| 563 initHtmlWorld(false); |
| 564 |
| 565 // Don't display any colors in the UI. |
| 566 options.useColors = false; |
| 567 |
| 568 // Replace error handler bring up alert for any problems. |
| 569 world.printHandler = (String msg) { |
| 570 window.alert(msg); |
| 571 }; |
| 572 } |
OLD | NEW |