| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, 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 = r''' | |
| 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 = r''' | |
| 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 = r''' | |
| 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 = r''' | |
| 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 = r''' | |
| 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 = r''' | |
| 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 = r''' | |
| 113 template ProductsForPerson(Person person, var products) { | |
| 114 <div> | |
| 115 ${with} person person | |
| 116 <div> | |
| 117 <span>${person.name}</span> | |
| 118 <span>-</span> | |
| 119 <span>${person.age}</span> | |
| 120 </div> | |
| 121 ${each} products product | |
| 122 <div> | |
| 123 <span>product=${product.name},users=${product.users}</span> | |
| 124 </div> | |
| 125 ${endEach} | |
| 126 ${endWith} | |
| 127 </div> | |
| 128 } | |
| 129 '''; | |
| 130 | |
| 131 final String complexTemplate2 = r''' | |
| 132 template ProductsForPerson(Person person, var products) { | |
| 133 <div> | |
| 134 ${with} person person | |
| 135 <div> | |
| 136 <span>${person.name}</span> | |
| 137 <span>-</span> | |
| 138 <span>${person.age}</span> | |
| 139 </div> | |
| 140 <div> | |
| 141 ${each} products product | |
| 142 <span>product=${product.name},users=${product.users}</span> | |
| 143 ${endEach} | |
| 144 </div> | |
| 145 ${endWith} | |
| 146 </div> | |
| 147 } | |
| 148 '''; | |
| 149 | |
| 150 final String complexTemplate3 = r''' | |
| 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 person | |
| 166 <div> | |
| 167 <span>${person.name}</span> | |
| 168 <span>-</span> | |
| 169 <span>${person.age}</span> | |
| 170 </div> | |
| 171 <div> | |
| 172 ${each} products product | |
| 173 <div>product=${product.name},users=${product.users}</div> | |
| 174 ${each} products.sales sale | |
| 175 <div class="sales-item"> | |
| 176 <span>${sale.country}</span> | |
| 177 <span class="ytd-sales">\$${sale.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 = r''' | |
| 205 template DivisionSales(var divisions) { | |
| 206 <div> | |
| 207 ${each} divisions division | |
| 208 <div> | |
| 209 <span>${division.name}</span> | |
| 210 <span>-</span> | |
| 211 <span>${division.id}</span> | |
| 212 </div> | |
| 213 <div> | |
| 214 ${each} divisions.products divProduct | |
| 215 <div> | |
| 216 <span var=productItem>▶</span> | |
| 217 <span>Product</span> | |
| 218 <span>${divProduct.name}</span> | |
| 219 <span>${divProduct.users} users</span> | |
| 220 </div> | |
| 221 ${each} products.sales sale | |
| 222 <div> | |
| 223 <span>${sale.country}</span> | |
| 224 <span>\$${sale.yearly}</span> | |
| 225 </div> | |
| 226 ${endEach} | |
| 227 ${endEach} | |
| 228 </div> | |
| 229 ${endEach} | |
| 230 </div> | |
| 231 } | |
| 232 '''; | |
| 233 | |
| 234 | |
| 235 final String realWorldList = r''' | |
| 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 division | |
| 299 <div class="division-item"> | |
| 300 <span>${division.name}</span> | |
| 301 <span>-</span> | |
| 302 <span>${division.id}</span> | |
| 303 </div> | |
| 304 <div> | |
| 305 ${each} divisions.products divProduct | |
| 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">${divProduct.name}</span> | |
| 310 <span class="product-users" align=right>${divProduct.users | |
| 311 } users</span> | |
| 312 <div class="show-sales"> | |
| 313 ${each} products.sales sale | |
| 314 <div class="sales-item"> | |
| 315 <span>${sale.country}</span> | |
| 316 <span class="ytd-sales">\$${sale.yearly}</span> | |
| 317 </div> | |
| 318 ${endEach} | |
| 319 </div> | |
| 320 </div> | |
| 321 ${endEach} | |
| 322 </div> | |
| 323 ${endEach} | |
| 324 </div> | |
| 325 } | |
| 326 | |
| 327 template Header(String company, DateTime date) { | |
| 328 css { | |
| 329 .header { | |
| 330 background-color: slateGray; | |
| 331 font-family: arial; | |
| 332 color: lightgray; | |
| 333 font-weight: bold; | |
| 334 padding-top: 20px; | |
| 335 } | |
| 336 } | |
| 337 <div class='header' align=center> | |
| 338 <h2>${company}</h2> | |
| 339 <div align=right>${date}</div> | |
| 340 </div> | |
| 341 } | |
| 342 '''; | |
| 343 | |
| 344 switch (sampleName) { | |
| 345 case "simple": | |
| 346 return simpleTemplate; | |
| 347 case "simple2": | |
| 348 return simpleTemplate2; | |
| 349 case "simpleCSS": | |
| 350 return simpleTemplateCSS; | |
| 351 case "with": | |
| 352 return withTemplate; | |
| 353 case "with2": | |
| 354 return withTemplate2; | |
| 355 case "list": | |
| 356 return eachTemplate; | |
| 357 case "complex": | |
| 358 return complexTemplate; | |
| 359 case "complex2": | |
| 360 return complexTemplate2; | |
| 361 case "complex3": | |
| 362 return complexTemplate3; | |
| 363 case "complex4": | |
| 364 return complexTemplate4; | |
| 365 case "realWorldList": | |
| 366 return realWorldList; | |
| 367 default: | |
| 368 print("ERROR: Unknown sample template"); | |
| 369 } | |
| 370 } | |
| 371 | |
| 372 void runTemplate([bool debug = false, bool parseOnly = false]) { | |
| 373 final Document doc = window.document; | |
| 374 final TextAreaElement dartClass = doc.query("#dart"); | |
| 375 final TextAreaElement template = doc.query('#template'); | |
| 376 final TableCellElement validity = doc.query('#validity'); | |
| 377 final TableCellElement result = doc.query('#result'); | |
| 378 | |
| 379 bool templateValid = true; | |
| 380 StringBuffer dumpTree = new StringBuffer(); | |
| 381 StringBuffer code = new StringBuffer(); | |
| 382 String htmlTemplate = template.value; | |
| 383 | |
| 384 if (debug) { | |
| 385 try { | |
| 386 List<Template> templates = templateParseAndValidate(htmlTemplate); | |
| 387 for (var tmpl in templates) { | |
| 388 dumpTree.write(tmpl.toDebugString()); | |
| 389 } | |
| 390 | |
| 391 // Generate the Dart class(es) for all template(s). | |
| 392 // Pass in filename of 'foo' for testing in UITest. | |
| 393 code.write(Codegen.generate(templates, 'foo')); | |
| 394 } catch (htmlException) { | |
| 395 // TODO(terry): TBD | |
| 396 print("ERROR unhandled EXCEPTION"); | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 /* | |
| 401 if (!debug) { | |
| 402 try { | |
| 403 cssParseAndValidate(cssExpr, cssWorld); | |
| 404 } catch (cssException) { | |
| 405 templateValid = false; | |
| 406 dumpTree = cssException.toString(); | |
| 407 } | |
| 408 } else if (parseOnly) { | |
| 409 try { | |
| 410 Parser parser = new Parser(new lang.SourceFile( | |
| 411 lang.SourceFile.IN_MEMORY_FILE, cssExpr)); | |
| 412 Stylesheet stylesheet = parser.parse(); | |
| 413 StringBuffer stylesheetTree = new StringBuffer(); | |
| 414 String prettyStylesheet = stylesheet.toString(); | |
| 415 stylesheetTree.add("${prettyStylesheet}\n"); | |
| 416 stylesheetTree.add("\n============>Tree Dump<============\n"); | |
| 417 stylesheetTree.add(stylesheet.toDebugString()); | |
| 418 dumpTree = stylesheetTree.toString(); | |
| 419 } catch (cssParseException) { | |
| 420 templateValid = false; | |
| 421 dumpTree = cssParseException.toString(); | |
| 422 } | |
| 423 } else { | |
| 424 try { | |
| 425 dumpTree = cssParseAndValidateDebug(cssExpr, cssWorld); | |
| 426 } catch (cssException) { | |
| 427 templateValid = false; | |
| 428 dumpTree = cssException.toString(); | |
| 429 } | |
| 430 } | |
| 431 */ | |
| 432 | |
| 433 final bgcolor = templateValid ? "white" : "red"; | |
| 434 final color = templateValid ? "black" : "white"; | |
| 435 final valid = templateValid ? "VALID" : "NOT VALID"; | |
| 436 String resultStyle = "resize: none; margin: 0; height: 100%; width: 100%;" | |
| 437 "padding: 5px 7px;"; | |
| 438 | |
| 439 result.innerHTML = ''' | |
| 440 <textarea style="${resultStyle}">${dumpTree.toString()}</textarea> | |
| 441 '''; | |
| 442 | |
| 443 dartClass.value = code.toString(); | |
| 444 } | |
| 445 | |
| 446 void main() { | |
| 447 final element = new Element.tag('div'); | |
| 448 | |
| 449 element.innerHTML = ''' | |
| 450 <table style="width: 100%; height: 100%;"> | |
| 451 <tbody> | |
| 452 <tr> | |
| 453 <td style="vertical-align: top; width: 50%; padding-right: 7px;"> | |
| 454 <table style="height: 100%; width: 100%;" cellspacing=0 cellpadding=
0 border=0> | |
| 455 <tbody> | |
| 456 <tr style="vertical-align: top; height: 1em;"> | |
| 457 <td> | |
| 458 <span style="font-weight:bold;">Generated Dart</span> | |
| 459 </td> | |
| 460 </tr> | |
| 461 <tr> | |
| 462 <td> | |
| 463 <textarea id="dart" style="resize: none; width: 100%; height
: 100%; padding: 5px 7px;"></textarea> | |
| 464 </td> | |
| 465 </tr> | |
| 466 </tbody> | |
| 467 </table> | |
| 468 </td> | |
| 469 <td> | |
| 470 <table style="width: 100%; height: 100%;" cellspacing=0 cellpadding=
0 border=0> | |
| 471 <tbody> | |
| 472 <tr style="vertical-align: top; height: 50%;"> | |
| 473 <td> | |
| 474 <table style="width: 100%; height: 100%;" cellspacing=0 cell
padding=0 border=0> | |
| 475 <tbody> | |
| 476 <tr> | |
| 477 <td> | |
| 478 <span style="font-weight:bold;">HTML Template</span> | |
| 479 </td> | |
| 480 </tr> | |
| 481 <tr style="height: 100%;"> | |
| 482 <td> | |
| 483 <textarea id="template" style="resize: none; width:
100%; height: 100%; padding: 5px 7px;">${sample("simple")}</textarea> | |
| 484 </td> | |
| 485 </tr> | |
| 486 </tbody> | |
| 487 </table> | |
| 488 </td> | |
| 489 </tr> | |
| 490 | |
| 491 <tr style="vertical-align: top; height: 50px;"> | |
| 492 <td> | |
| 493 <table> | |
| 494 <tbody> | |
| 495 <tr> | |
| 496 <td> | |
| 497 <button id=generate>Generate</button> | |
| 498 </td> | |
| 499 <td align="right"> | |
| 500 <select id=templateSamples> | |
| 501 <option value="simple">Simple Template</option> | |
| 502 <option value="simple2">Simple Template #2</option
> | |
| 503 <option value="simpleCSS">Simple Template w/ CSS</
option> | |
| 504 <option value="with">With Template</option> | |
| 505 <option value="with2">With Template #2</option> | |
| 506 <option value="list">List Template</option> | |
| 507 <option value="complex">Complex Template</option> | |
| 508 <option value="complex2">Complex Template #2</opti
on> | |
| 509 <option value="complex3">Complex Template #3 w/ CS
S</option> | |
| 510 <option value="complex4">Complex Template #4</opti
on> | |
| 511 <option value="realWorldList">Real world</option> | |
| 512 </select> | |
| 513 </td> | |
| 514 </tr> | |
| 515 </tbody> | |
| 516 </table> | |
| 517 </td> | |
| 518 </tr> | |
| 519 | |
| 520 <tr style="vertical-align: top;"> | |
| 521 <td> | |
| 522 <table style="width: 100%; height: 100%;" border="0" cellpad
ding="0" cellspacing="0"> | |
| 523 <tbody> | |
| 524 <tr style="vertical-align: top; height: 1em;"> | |
| 525 <td> | |
| 526 <span style="font-weight:bold;">Parse Tree</span> | |
| 527 </td> | |
| 528 </tr> | |
| 529 <tr style="vertical-align: top; height: 1em;"> | |
| 530 <td id="validity"> | |
| 531 </td> | |
| 532 </tr> | |
| 533 <tr> | |
| 534 <td id="result"> | |
| 535 <textarea style="resize: none; width: 100%; height:
100%; border: black solid 1px; padding: 5px 7px;"></textarea> | |
| 536 </td> | |
| 537 </tr> | |
| 538 </tbody> | |
| 539 </table> | |
| 540 </td> | |
| 541 </tr> | |
| 542 </tbody> | |
| 543 </table> | |
| 544 </td> | |
| 545 </tr> | |
| 546 </tbody> | |
| 547 </table> | |
| 548 '''; | |
| 549 | |
| 550 document.body.style.setProperty("background-color", "lightgray"); | |
| 551 document.body.elements.add(element); | |
| 552 | |
| 553 ButtonElement genElem = window.document.query('#generate'); | |
| 554 genElem.on.click.add((MouseEvent e) { | |
| 555 runTemplate(true, true); | |
| 556 }); | |
| 557 | |
| 558 SelectElement cannedTemplates = window.document.query('#templateSamples'); | |
| 559 cannedTemplates.on.change.add((e) { | |
| 560 changeTemplate(); | |
| 561 }); | |
| 562 | |
| 563 parseOptions([], null); | |
| 564 initHtmlWorld(false); | |
| 565 | |
| 566 // Don't display any colors in the UI. | |
| 567 options.useColors = false; | |
| 568 | |
| 569 // Replace error handler bring up alert for any problems. | |
| 570 world.printHandler = (String msg) { | |
| 571 window.alert(msg); | |
| 572 }; | |
| 573 } | |
| OLD | NEW |