Modern
Workflow
& Tooling
🔥 Tasty Tooling Tips
wesbos.com@wesbos
├── .gitignore ├── _deps.styl ├── gulpfile.js ├── images ├── 1.jpg ├── 10.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg ├── 6.jpg ├── 7.jpg ├── 8.jpg ├── 9.jpg ├── BrowserSync.mp4 ├── Twitter_logo_white.png ├── arrows.png ├── babel.svg ├── babeled.png ├── brain.svg ├── canada-flag.png ├── canadian-stylesheets.png ├── commandline.png ├── cover.png ├── critical.png ├── css-next-logo.svg ├── css-sourcemaps.png ├── cssnext-gulp.png ├── es6.png ├── fetch.png ├── flexbox.png ├── german-stylesheets.png ├── grunt-logo.png ├── gulp-logo.png ├── hackerYou-logomark.png ├── image-compress.png ├── images-gulp.png ├── jslogo.jpg ├── lodash.png ├── modules.png ├── npm-mess.png ├── postcss-logo.png ├── purify.png ├── scoped-variables.png ├── sharkbite-depth.jpg ├── soldering.jpg ├── sourcemaps-in-devtools.png ├── sourcemaps.png ├── ugggggggly.png ├── uglify.png ├── webpack.png └── wow-scripts.png ├── index.html ├── index.jade ├── package.json ├── prettify.js ├── readme.md ├── slides.js ├── styles.css └── styles.styl /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | updates.md 4 | -------------------------------------------------------------------------------- /_deps.styl: -------------------------------------------------------------------------------- 1 | /* 2 | Google HTML5 slides template 3 | 4 | Authors: Luke Mahé (code) 5 | Marcin Wichary (code and design) 6 | 7 | Dominic Mazzoni (browser compatibility) 8 | Charles Chen (ChromeVox support) 9 | 10 | URL: http://code.google.com/p/html5slides/ 11 | */ 12 | 13 | /* Framework */ 14 | 15 | 16 | .wrapper { 17 | background: #BADA55; 18 | color:#D12028; 19 | border:1px solid #fff; 20 | } 21 | 22 | html { 23 | height: 100%; 24 | } 25 | 26 | body { 27 | margin: 0; 28 | padding: 0; 29 | display: block !important; 30 | height: 100%; 31 | min-height: 740px; 32 | overflow-x: hidden; 33 | overflow-y: auto; 34 | } 35 | 36 | .slides { 37 | width: 100%; 38 | height: 100%; 39 | left: 0; 40 | top: 0; 41 | color:#f21818; 42 | background:#193549; 43 | position: absolute; 44 | -webkit-transform: translate3d(0, 0, 0); 45 | } 46 | 47 | 48 | /* 49 | Slide Widths 50 | */ 51 | 52 | w = 1920px 53 | h = 1080px 54 | 55 | .slides > article { 56 | display: block; 57 | position: absolute; 58 | overflow: hidden; 59 | width w 60 | height h 61 | margin-left: -(w / 2); 62 | margin-top: -(h / 2); 63 | 64 | left: 50%; 65 | top: 50%; 66 | border-radius 5px; 67 | padding: 0; 68 | background-color: none; 69 | transition: all 0.3s ease-out; 70 | justify-content center 71 | flex-direction column 72 | & > * { 73 | display block 74 | clear both 75 | min-width 100% 76 | flex-wrap wrap 77 | } 78 | & > img { 79 | min-width: 0; 80 | display: block; 81 | margin: 0 auto 82 | } 83 | 84 | } 85 | 86 | .slide-area { 87 | z-index: 1000; 88 | 89 | position: absolute; 90 | left: 0; 91 | top: 0; 92 | width: 150px; 93 | height: 100%; 94 | left: 0; 95 | top: 0; 96 | cursor: pointer; 97 | tap-highlight-color: transparent; 98 | 99 | } 100 | #prev-slide-area { 101 | 102 | } 103 | #next-slide-area { 104 | right 0 105 | left auto 106 | } 107 | .slides.layout-widescreen #prev-slide-area, 108 | .slides.layout-faux-widescreen #prev-slide-area { 109 | margin-left: -650px; 110 | } 111 | .slides.layout-widescreen #next-slide-area, 112 | .slides.layout-faux-widescreen #next-slide-area { 113 | margin-left: 500px; 114 | } 115 | 116 | /* Slides */ 117 | 118 | .slides > article { 119 | display: none; 120 | text-align: center; 121 | } 122 | .slides > article.far-past { 123 | display: block; 124 | transform: translate(-4000px); 125 | display none; 126 | } 127 | .slides > article.past { 128 | display: flex; 129 | transform: scale(0.5) translate(-(w + (0))px); 130 | opacity: 0.3; 131 | 132 | } 133 | .slides > article.current { 134 | display: flex; 135 | transform: translate(0); 136 | z-index 10 137 | } 138 | .slides > article.next { 139 | display: flex; 140 | transform: scale(0.5) translate((w + (0))px); 141 | opacity: 0.3; 142 | } 143 | .slides > article.far-next { 144 | display: flex; 145 | transform: translate(4000px); 146 | display none; 147 | } 148 | 149 | 150 | /* Styles for slides */ 151 | 152 | .slides > article { 153 | color: #6C818F; 154 | font-size: 30px; 155 | letter-spacing: -1px; 156 | } 157 | 158 | b { 159 | font-weight: 600; 160 | } 161 | 162 | .blue { 163 | color: rgb(0, 102, 204); 164 | } 165 | .yellow { 166 | color: rgb(255, 211, 25); 167 | } 168 | .green { 169 | color: #29E254; 170 | } 171 | .red { 172 | color: rgb(255, 0, 0); 173 | } 174 | .black { 175 | color: black; 176 | } 177 | .white { 178 | color: white; 179 | } 180 | 181 | a { 182 | color: #FFDD00; 183 | } 184 | 185 | ::-moz-selection { background: #FFDD00; } 186 | ::selection { background: #FFDD00; } 187 | 188 | 189 | p { 190 | margin: 0; 191 | padding: 0; 192 | } 193 | p:first-child { 194 | margin-top: 0; 195 | } 196 | 197 | body { 198 | // font-family: inconsolata, courier; 199 | font-family: 'Open Sans', sans-serif; 200 | } 201 | h1 { 202 | font-size: 60px; 203 | line-height: 60px; 204 | padding: 0; 205 | margin: 0; 206 | color: white; 207 | } 208 | 209 | h2 { 210 | font-size: 45px; 211 | line-height: 45px; 212 | 213 | bottom: 150px; 214 | 215 | padding: 0; 216 | margin: 0; 217 | font-weight: 600; 218 | color:white; 219 | letter-spacing: -2px; 220 | } 221 | 222 | h2 a { 223 | text-decoration: none; 224 | } 225 | 226 | h3 { 227 | font-size: 20px; 228 | line-height: 36px; 229 | padding: 0 0 10px 0; 230 | margin: 0; 231 | padding-right: 40px; 232 | font-weight: 600; 233 | letter-spacing: -1px; 234 | color:#EAEAEA; 235 | } 236 | 237 | .half { 238 | width:350px; 239 | float:left; 240 | } 241 | 242 | .button:hover { 243 | color:#fff; 244 | background:#392C44; 245 | } 246 | 247 | pre.half { 248 | width: 400px; 249 | font-size:17px; 250 | } 251 | 252 | p.small { 253 | color:#000; 254 | font-size:18px; 255 | } 256 | article.fill h3 { 257 | background: rgba(255, 255, 255, .75); 258 | padding-top: .2em; 259 | padding-bottom: .3em; 260 | margin-top: -.2em; 261 | margin-left: -60px; 262 | padding-left: 60px; 263 | margin-right: -60px; 264 | padding-right: 60px; 265 | } 266 | 267 | h4 { 268 | margin:0; 269 | } 270 | 271 | 272 | .center { 273 | text-align:center; 274 | } 275 | 276 | .center h3 { 277 | font-size:100px; 278 | margin-top:220px; 279 | } 280 | ul { 281 | list-style: none; 282 | margin: 0; 283 | padding: 0; 284 | 285 | margin-top: 40px; 286 | 287 | margin-left: .75em; 288 | } 289 | ul:first-child { 290 | margin-top: 0; 291 | } 292 | ul ul { 293 | margin-top: .5em; 294 | } 295 | li { 296 | padding: 0; 297 | margin: 0; 298 | 299 | margin-bottom: .5em; 300 | } 301 | li::before { 302 | content: '·'; 303 | 304 | width: .75em; 305 | margin-left: -.75em; 306 | 307 | position: absolute; 308 | } 309 | 310 | pre { 311 | 312 | font-size: 20px; 313 | line-height: 28px; 314 | padding: 5px 10px; 315 | 316 | letter-spacing: -1px; 317 | 318 | margin-top: 20px; 319 | margin-bottom: 20px; 320 | 321 | color: black; 322 | background: rgb(240, 240, 240); 323 | border: 1px solid rgb(224, 224, 224); 324 | box-shadow: inset 0 2px 6px rgba(0, 0, 0, .1); 325 | 326 | overflow: hidden; 327 | } 328 | 329 | code { 330 | font-size: 95%; 331 | font-family: 'Droid Sans Mono', 'Courier New', monospace; 332 | display: inline-block; 333 | background rgba(255,255,255,0.2); 334 | padding 10px 335 | border-radius 4px; 336 | font-weight 600 337 | } 338 | 339 | iframe { 340 | width: 100%; 341 | height: 620px; 342 | background: white; 343 | border: 1px solid rgb(192, 192, 192); 344 | margin: -1px; 345 | /*box-shadow: inset 0 2px 6px rgba(0, 0, 0, .1);*/ 346 | } 347 | 348 | img { 349 | max-width: 100%; 350 | max-height:570px; 351 | } 352 | 353 | h3 + iframe { 354 | margin-top: 40px; 355 | height: 540px; 356 | } 357 | 358 | article.fill iframe { 359 | position: absolute; 360 | left: 0; 361 | top: 0; 362 | width: 100%; 363 | height: 100%; 364 | 365 | border: 0; 366 | margin: 0; 367 | 368 | border-radius: 10px; 369 | -o-border-radius: 10px; 370 | -moz-border-radius: 10px; 371 | -webkit-border-radius: 10px; 372 | 373 | z-index: -1; 374 | } 375 | 376 | article.fill img { 377 | position: absolute; 378 | left: 0; 379 | top: 0; 380 | min-width: 100%; 381 | min-height: 100%; 382 | 383 | border-radius: 10px; 384 | -o-border-radius: 10px; 385 | -moz-border-radius: 10px; 386 | -webkit-border-radius: 10px; 387 | 388 | z-index: -1; 389 | } 390 | img.centered { 391 | margin: 0 auto; 392 | display: block; 393 | } 394 | 395 | table { 396 | width: 100%; 397 | border-collapse: collapse; 398 | margin-top: 40px; 399 | } 400 | th { 401 | font-weight: 600; 402 | text-align: left; 403 | } 404 | td, 405 | th { 406 | border: 1px solid rgb(224, 224, 224); 407 | padding: 5px 10px; 408 | vertical-align: top; 409 | } 410 | 411 | .source { 412 | position: absolute; 413 | left: 60px; 414 | top: 644px; 415 | padding-right: 175px; 416 | 417 | font-size: 15px; 418 | letter-spacing: 0; 419 | line-height: 18px; 420 | } 421 | 422 | q { 423 | display: block; 424 | font-size: 60px; 425 | line-height: 72px; 426 | 427 | margin-left: 20px; 428 | 429 | margin-top: 100px; 430 | margin-right: 150px; 431 | } 432 | q::before { 433 | content: '“'; 434 | 435 | position: absolute; 436 | display: inline-block; 437 | margin-left: -2.1em; 438 | width: 2em; 439 | text-align: right; 440 | 441 | font-size: 90px; 442 | color: rgb(192, 192, 192); 443 | } 444 | q::after { 445 | content: '”'; 446 | 447 | position: absolute; 448 | margin-left: .1em; 449 | 450 | font-size: 90px; 451 | color: rgb(192, 192, 192); 452 | } 453 | div.author { 454 | text-align: right; 455 | font-size: 40px; 456 | 457 | margin-top: 20px; 458 | margin-right: 150px; 459 | } 460 | div.author::before { 461 | content: '—'; 462 | } 463 | 464 | /* Size variants */ 465 | 466 | article.smaller p, 467 | article.smaller ul { 468 | font-size: 20px; 469 | line-height: 24px; 470 | letter-spacing: 0; 471 | } 472 | article.smaller table { 473 | font-size: 20px; 474 | line-height: 24px; 475 | letter-spacing: 0; 476 | } 477 | article.smaller pre { 478 | font-size: 15px; 479 | line-height: 20px; 480 | letter-spacing: 0; 481 | } 482 | article.smaller q { 483 | font-size: 40px; 484 | line-height: 48px; 485 | } 486 | article.smaller q::before, 487 | article.smaller q::after { 488 | font-size: 60px; 489 | } 490 | 491 | /* Builds */ 492 | 493 | .build > * { 494 | transition: opacity 0.2s ease-in-out 0.2s; 495 | } 496 | 497 | .to-build { 498 | opacity: 0; 499 | } 500 | 501 | /* Pretty print */ 502 | 503 | .prettyprint .str, /* string content */ 504 | .prettyprint .atv { /* a markup attribute value */ 505 | color: rgb(0, 138, 53); 506 | } 507 | .prettyprint .kwd, /* a keyword */ 508 | .prettyprint .tag { /* a markup tag name */ 509 | color: rgb(0, 102, 204); 510 | } 511 | .prettyprint .com { /* a comment */ 512 | color: rgb(127, 127, 127); 513 | font-style: italic; 514 | } 515 | .prettyprint .lit { /* a literal value */ 516 | color: rgb(127, 0, 0); 517 | } 518 | .prettyprint .pun, /* punctuation, lisp open bracket, lisp close bracket */ 519 | .prettyprint .opn, 520 | .prettyprint .clo { 521 | color: rgb(127, 127, 127); 522 | } 523 | .prettyprint .typ, /* a type name */ 524 | .prettyprint .atn, /* a markup attribute name */ 525 | .prettyprint .dec, 526 | .prettyprint .var { /* a declaration; a variable name */ 527 | color: rgb(127, 0, 127); 528 | } 529 | 530 | 531 | 532 | 533 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var p = require('gulp-load-plugins')(); 3 | 4 | var browserSync = require('browser-sync'); 5 | var reload = browserSync.reload; 6 | 7 | // Start the server 8 | gulp.task('browser-sync', function() { 9 | browserSync({ 10 | open : true, 11 | server: { 12 | baseDir: "./" 13 | } 14 | }); 15 | }); 16 | 17 | gulp.task('slides',function () { 18 | gulp.src('index.jade') 19 | .pipe(p.jade()) 20 | .pipe(gulp.dest('./')) 21 | .pipe(reload({stream:true})) 22 | }); 23 | 24 | 25 | gulp.task('styles',function() { 26 | gulp.src('./styles.styl') 27 | .pipe(p.stylus()) 28 | .pipe(p.autoprefixer()) 29 | .pipe(gulp.dest('./')) 30 | .pipe(reload({stream:true})) 31 | }); 32 | 33 | 34 | gulp.task('default', ['slides','styles','browser-sync'] ,function() { 35 | gulp.watch('./**/*.jade',['slides']); 36 | gulp.watch('./**/*.styl',['styles']); 37 | }); 38 | -------------------------------------------------------------------------------- /images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/1.jpg -------------------------------------------------------------------------------- /images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/10.jpg -------------------------------------------------------------------------------- /images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/2.jpg -------------------------------------------------------------------------------- /images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/3.jpg -------------------------------------------------------------------------------- /images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/4.jpg -------------------------------------------------------------------------------- /images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/5.jpg -------------------------------------------------------------------------------- /images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/6.jpg -------------------------------------------------------------------------------- /images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/7.jpg -------------------------------------------------------------------------------- /images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/8.jpg -------------------------------------------------------------------------------- /images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/9.jpg -------------------------------------------------------------------------------- /images/BrowserSync.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/BrowserSync.mp4 -------------------------------------------------------------------------------- /images/Twitter_logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/Twitter_logo_white.png -------------------------------------------------------------------------------- /images/arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/arrows.png -------------------------------------------------------------------------------- /images/babel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 171 | -------------------------------------------------------------------------------- /images/babeled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/babeled.png -------------------------------------------------------------------------------- /images/brain.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/canada-flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/canada-flag.png -------------------------------------------------------------------------------- /images/canadian-stylesheets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/canadian-stylesheets.png -------------------------------------------------------------------------------- /images/commandline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/commandline.png -------------------------------------------------------------------------------- /images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/cover.png -------------------------------------------------------------------------------- /images/critical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/critical.png -------------------------------------------------------------------------------- /images/css-next-logo.svg: -------------------------------------------------------------------------------- 1 | 160 | -------------------------------------------------------------------------------- /images/css-sourcemaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/css-sourcemaps.png -------------------------------------------------------------------------------- /images/cssnext-gulp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/cssnext-gulp.png -------------------------------------------------------------------------------- /images/es6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/es6.png -------------------------------------------------------------------------------- /images/fetch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/fetch.png -------------------------------------------------------------------------------- /images/flexbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/flexbox.png -------------------------------------------------------------------------------- /images/german-stylesheets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/german-stylesheets.png -------------------------------------------------------------------------------- /images/grunt-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/grunt-logo.png -------------------------------------------------------------------------------- /images/gulp-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/gulp-logo.png -------------------------------------------------------------------------------- /images/hackerYou-logomark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/hackerYou-logomark.png -------------------------------------------------------------------------------- /images/image-compress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/image-compress.png -------------------------------------------------------------------------------- /images/images-gulp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/images-gulp.png -------------------------------------------------------------------------------- /images/jslogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/jslogo.jpg -------------------------------------------------------------------------------- /images/lodash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/lodash.png -------------------------------------------------------------------------------- /images/modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/modules.png -------------------------------------------------------------------------------- /images/npm-mess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/npm-mess.png -------------------------------------------------------------------------------- /images/postcss-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/postcss-logo.png -------------------------------------------------------------------------------- /images/purify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/purify.png -------------------------------------------------------------------------------- /images/scoped-variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/scoped-variables.png -------------------------------------------------------------------------------- /images/sharkbite-depth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/sharkbite-depth.jpg -------------------------------------------------------------------------------- /images/soldering.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/soldering.jpg -------------------------------------------------------------------------------- /images/sourcemaps-in-devtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/sourcemaps-in-devtools.png -------------------------------------------------------------------------------- /images/sourcemaps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/sourcemaps.png -------------------------------------------------------------------------------- /images/ugggggggly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/ugggggggly.png -------------------------------------------------------------------------------- /images/uglify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/uglify.png -------------------------------------------------------------------------------- /images/webpack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/webpack.png -------------------------------------------------------------------------------- /images/wow-scripts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wesbos/Modern-Workflow-and-Tooling-Talk/96316bdfb6f7ae6b10438685db5edda6b690c489/images/wow-scripts.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 |
gulp-babel
417 | h4 Grunt → grunt-babel
418 | h4 Browserify → babelify transformer
419 | h4 WebPack → babel-loader
420 | h4 CLI → babel script.js --out-file script-compiled.js
421 |
422 | //- article
423 | //- h2 What about new Language Features?
424 | //- p Not everything new is just Syntax require('babel/polyfill');
426 |
427 | //- Future CSS
428 | article
429 | h1(style="font-size:500px") CSS4
430 |
431 | article
432 | h1 Everyone is Stylus
→ AutoPrefixer
→ CSS
484 | p ES6
→ Babel
→ Browserify
→ UglifyJS
→ JavaScript
485 |
486 | article
487 | h2 What happens when there is an error?
488 | p How do we trace it back to the original file?
489 |
490 | article
491 | p CSS bug in _typography.scss:10
but browser shows error in compiled and minified app.css
492 | p JavaScript error in your React JSX component Store.js:25
, but is untraceable after running through Babel and Browserify!
493 |
494 | article
495 | h1(style="font-size:160px;") Sourcemaps are21 | * For a fairly comprehensive set of languages see the 22 | * README 23 | * file that came with this source. At a minimum, the lexer should work on a 24 | * number of languages including C and friends, Java, Python, Bash, SQL, HTML, 25 | * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk 26 | * and a subset of Perl, but, because of commenting conventions, doesn't work on 27 | * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. 28 | *
29 | * Usage:
} and {@code } tags in your source with
34 | * {@code class=prettyprint.}
35 | * You can also use the (html deprecated) {@code } tag, but the pretty
36 | * printer needs to do more substantial DOM manipulations to support that, so
37 | * some css styles may not be preserved.
38 | *
} or {@code } element to specify the
42 | * language, as in {@code }. Any class that
43 | * starts with "lang-" followed by a file extension, specifies the file type.
44 | * See the "lang-*.js" files in this directory for code that implements
45 | * per-language file handlers.
46 | *
47 | * Change log:
48 | * cbeust, 2006/08/22
49 | *
50 | * Java annotations (start with "@") are now captured as literals ("lit")
51 | *
52 | * @requires console
53 | */
54 |
55 | // JSLint declarations
56 | /*global console, document, navigator, setTimeout, window */
57 |
58 | /**
59 | * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
60 | * UI events.
61 | * If set to {@code false}, {@code prettyPrint()} is synchronous.
62 | */
63 | window['PR_SHOULD_USE_CONTINUATION'] = true;
64 |
65 | /** the number of characters between tab columns */
66 | window['PR_TAB_WIDTH'] = 8;
67 |
68 | /** Contains functions for creating and registering new language handlers.
69 | * @type {Object}
70 | */
71 | window['PR']
72 |
73 | /** Pretty print a chunk of code.
74 | *
75 | * @param {string} sourceCodeHtml code as html
76 | * @return {string} code as html, but prettier
77 | */
78 | = window['prettyPrintOne']
79 | /** Find all the {@code } and {@code } tags in the DOM with
80 | * {@code class=prettyprint} and prettify them.
81 | * @param {Function?} opt_whenDone if specified, called when the last entry
82 | * has been finished.
83 | */
84 | = window['prettyPrint'] = void 0;
85 |
86 |
87 | (function () {
88 | // Keyword lists for various languages.
89 | var FLOW_CONTROL_KEYWORDS =
90 | "break continue do else for if return while ";
91 | var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " +
92 | "double enum extern float goto int long register short signed sizeof " +
93 | "static struct switch typedef union unsigned void volatile ";
94 | var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " +
95 | "new operator private protected public this throw true try typeof ";
96 | var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " +
97 | "concept concept_map const_cast constexpr decltype " +
98 | "dynamic_cast explicit export friend inline late_check " +
99 | "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
100 | "template typeid typename using virtual wchar_t where ";
101 | var JAVA_KEYWORDS = COMMON_KEYWORDS +
102 | "abstract boolean byte extends final finally implements import " +
103 | "instanceof null native package strictfp super synchronized throws " +
104 | "transient ";
105 | var CSHARP_KEYWORDS = JAVA_KEYWORDS +
106 | "as base by checked decimal delegate descending dynamic event " +
107 | "fixed foreach from group implicit in interface internal into is lock " +
108 | "object out override orderby params partial readonly ref sbyte sealed " +
109 | "stackalloc string select uint ulong unchecked unsafe ushort var ";
110 | var COFFEE_KEYWORDS = "all and by catch class else extends false finally " +
111 | "for if in is isnt loop new no not null of off on or return super then " +
112 | "true try unless until when while yes ";
113 | var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
114 | "debugger eval export function get null set undefined var with " +
115 | "Infinity NaN ";
116 | var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " +
117 | "goto if import last local my next no our print package redo require " +
118 | "sub undef unless until use wantarray while BEGIN END ";
119 | var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
120 | "elif except exec finally from global import in is lambda " +
121 | "nonlocal not or pass print raise try with yield " +
122 | "False True None ";
123 | var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
124 | " defined elsif end ensure false in module next nil not or redo rescue " +
125 | "retry self super then true undef unless until when yield BEGIN END ";
126 | var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " +
127 | "function in local set then until ";
128 | var ALL_KEYWORDS = (
129 | CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +
130 | PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);
131 |
132 | // token style names. correspond to css classes
133 | /** token style for a string literal */
134 | var PR_STRING = 'str';
135 | /** token style for a keyword */
136 | var PR_KEYWORD = 'kwd';
137 | /** token style for a comment */
138 | var PR_COMMENT = 'com';
139 | /** token style for a type */
140 | var PR_TYPE = 'typ';
141 | /** token style for a literal value. e.g. 1, null, true. */
142 | var PR_LITERAL = 'lit';
143 | /** token style for a punctuation string. */
144 | var PR_PUNCTUATION = 'pun';
145 | /** token style for a punctuation string. */
146 | var PR_PLAIN = 'pln';
147 |
148 | /** token style for an sgml tag. */
149 | var PR_TAG = 'tag';
150 | /** token style for a markup declaration such as a DOCTYPE. */
151 | var PR_DECLARATION = 'dec';
152 | /** token style for embedded source. */
153 | var PR_SOURCE = 'src';
154 | /** token style for an sgml attribute name. */
155 | var PR_ATTRIB_NAME = 'atn';
156 | /** token style for an sgml attribute value. */
157 | var PR_ATTRIB_VALUE = 'atv';
158 |
159 | /**
160 | * A class that indicates a section of markup that is not code, e.g. to allow
161 | * embedding of line numbers within code listings.
162 | */
163 | var PR_NOCODE = 'nocode';
164 |
165 | /** A set of tokens that can precede a regular expression literal in
166 | * javascript.
167 | * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full
168 | * list, but I've removed ones that might be problematic when seen in
169 | * languages that don't support regular expression literals.
170 | *
171 | * Specifically, I've removed any keywords that can't precede a regexp
172 | * literal in a syntactically legal javascript program, and I've removed the
173 | * "in" keyword since it's not a keyword in many languages, and might be used
174 | * as a count of inches.
175 | *
176 | *
The link a above does not accurately describe EcmaScript rules since
177 | * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
178 | * very well in practice.
179 | *
180 | * @private
181 | */
182 | var REGEXP_PRECEDER_PATTERN = function () {
183 | var preceders = [
184 | "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=",
185 | "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=",
186 | "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";",
187 | "<", "<<", "<<=", "<=", "=", "==", "===", ">",
188 | ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
189 | "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
190 | "||=", "~" /* handles =~ and !~ */,
191 | "break", "case", "continue", "delete",
192 | "do", "else", "finally", "instanceof",
193 | "return", "throw", "try", "typeof"
194 | ];
195 | var pattern = '(?:^^|[+-]';
196 | for (var i = 0; i < preceders.length; ++i) {
197 | pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1');
198 | }
199 | pattern += ')\\s*'; // matches at end, and matches empty string
200 | return pattern;
201 | // CAVEAT: this does not properly handle the case where a regular
202 | // expression immediately follows another since a regular expression may
203 | // have flags for case-sensitivity and the like. Having regexp tokens
204 | // adjacent is not valid in any language I'm aware of, so I'm punting.
205 | // TODO: maybe style special characters inside a regexp as punctuation.
206 | }();
207 |
208 |
209 | /**
210 | * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
211 | * matches the union of the sets of strings matched by the input RegExp.
212 | * Since it matches globally, if the input strings have a start-of-input
213 | * anchor (/^.../), it is ignored for the purposes of unioning.
214 | * @param {Array.} regexs non multiline, non-global regexs.
215 | * @return {RegExp} a global regex.
216 | */
217 | function combinePrefixPatterns(regexs) {
218 | var capturedGroupIndex = 0;
219 |
220 | var needToFoldCase = false;
221 | var ignoreCase = false;
222 | for (var i = 0, n = regexs.length; i < n; ++i) {
223 | var regex = regexs[i];
224 | if (regex.ignoreCase) {
225 | ignoreCase = true;
226 | } else if (/[a-z]/i.test(regex.source.replace(
227 | /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
228 | needToFoldCase = true;
229 | ignoreCase = false;
230 | break;
231 | }
232 | }
233 |
234 | function decodeEscape(charsetPart) {
235 | if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); }
236 | switch (charsetPart.charAt(1)) {
237 | case 'b': return 8;
238 | case 't': return 9;
239 | case 'n': return 0xa;
240 | case 'v': return 0xb;
241 | case 'f': return 0xc;
242 | case 'r': return 0xd;
243 | case 'u': case 'x':
244 | return parseInt(charsetPart.substring(2), 16)
245 | || charsetPart.charCodeAt(1);
246 | case '0': case '1': case '2': case '3': case '4':
247 | case '5': case '6': case '7':
248 | return parseInt(charsetPart.substring(1), 8);
249 | default: return charsetPart.charCodeAt(1);
250 | }
251 | }
252 |
253 | function encodeEscape(charCode) {
254 | if (charCode < 0x20) {
255 | return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
256 | }
257 | var ch = String.fromCharCode(charCode);
258 | if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
259 | ch = '\\' + ch;
260 | }
261 | return ch;
262 | }
263 |
264 | function caseFoldCharset(charSet) {
265 | var charsetParts = charSet.substring(1, charSet.length - 1).match(
266 | new RegExp(
267 | '\\\\u[0-9A-Fa-f]{4}'
268 | + '|\\\\x[0-9A-Fa-f]{2}'
269 | + '|\\\\[0-3][0-7]{0,2}'
270 | + '|\\\\[0-7]{1,2}'
271 | + '|\\\\[\\s\\S]'
272 | + '|-'
273 | + '|[^-\\\\]',
274 | 'g'));
275 | var groups = [];
276 | var ranges = [];
277 | var inverse = charsetParts[0] === '^';
278 | for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
279 | var p = charsetParts[i];
280 | switch (p) {
281 | case '\\B': case '\\b':
282 | case '\\D': case '\\d':
283 | case '\\S': case '\\s':
284 | case '\\W': case '\\w':
285 | groups.push(p);
286 | continue;
287 | }
288 | var start = decodeEscape(p);
289 | var end;
290 | if (i + 2 < n && '-' === charsetParts[i + 1]) {
291 | end = decodeEscape(charsetParts[i + 2]);
292 | i += 2;
293 | } else {
294 | end = start;
295 | }
296 | ranges.push([start, end]);
297 | // If the range might intersect letters, then expand it.
298 | if (!(end < 65 || start > 122)) {
299 | if (!(end < 65 || start > 90)) {
300 | ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
301 | }
302 | if (!(end < 97 || start > 122)) {
303 | ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
304 | }
305 | }
306 | }
307 |
308 | // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
309 | // -> [[1, 12], [14, 14], [16, 17]]
310 | ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1] - a[1]); });
311 | var consolidatedRanges = [];
312 | var lastRange = [NaN, NaN];
313 | for (var i = 0; i < ranges.length; ++i) {
314 | var range = ranges[i];
315 | if (range[0] <= lastRange[1] + 1) {
316 | lastRange[1] = Math.max(lastRange[1], range[1]);
317 | } else {
318 | consolidatedRanges.push(lastRange = range);
319 | }
320 | }
321 |
322 | var out = ['['];
323 | if (inverse) { out.push('^'); }
324 | out.push.apply(out, groups);
325 | for (var i = 0; i < consolidatedRanges.length; ++i) {
326 | var range = consolidatedRanges[i];
327 | out.push(encodeEscape(range[0]));
328 | if (range[1] > range[0]) {
329 | if (range[1] + 1 > range[0]) { out.push('-'); }
330 | out.push(encodeEscape(range[1]));
331 | }
332 | }
333 | out.push(']');
334 | return out.join('');
335 | }
336 |
337 | function allowAnywhereFoldCaseAndRenumberGroups(regex) {
338 | // Split into character sets, escape sequences, punctuation strings
339 | // like ('(', '(?:', ')', '^'), and runs of characters that do not
340 | // include any of the above.
341 | var parts = regex.source.match(
342 | new RegExp(
343 | '(?:'
344 | + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]' // a character set
345 | + '|\\\\u[A-Fa-f0-9]{4}' // a unicode escape
346 | + '|\\\\x[A-Fa-f0-9]{2}' // a hex escape
347 | + '|\\\\[0-9]+' // a back-reference or octal escape
348 | + '|\\\\[^ux0-9]' // other escape sequence
349 | + '|\\(\\?[:!=]' // start of a non-capturing group
350 | + '|[\\(\\)\\^]' // start/emd of a group, or line start
351 | + '|[^\\x5B\\x5C\\(\\)\\^]+' // run of other characters
352 | + ')',
353 | 'g'));
354 | var n = parts.length;
355 |
356 | // Maps captured group numbers to the number they will occupy in
357 | // the output or to -1 if that has not been determined, or to
358 | // undefined if they need not be capturing in the output.
359 | var capturedGroups = [];
360 |
361 | // Walk over and identify back references to build the capturedGroups
362 | // mapping.
363 | for (var i = 0, groupIndex = 0; i < n; ++i) {
364 | var p = parts[i];
365 | if (p === '(') {
366 | // groups are 1-indexed, so max group index is count of '('
367 | ++groupIndex;
368 | } else if ('\\' === p.charAt(0)) {
369 | var decimalValue = +p.substring(1);
370 | if (decimalValue && decimalValue <= groupIndex) {
371 | capturedGroups[decimalValue] = -1;
372 | }
373 | }
374 | }
375 |
376 | // Renumber groups and reduce capturing groups to non-capturing groups
377 | // where possible.
378 | for (var i = 1; i < capturedGroups.length; ++i) {
379 | if (-1 === capturedGroups[i]) {
380 | capturedGroups[i] = ++capturedGroupIndex;
381 | }
382 | }
383 | for (var i = 0, groupIndex = 0; i < n; ++i) {
384 | var p = parts[i];
385 | if (p === '(') {
386 | ++groupIndex;
387 | if (capturedGroups[groupIndex] === undefined) {
388 | parts[i] = '(?:';
389 | }
390 | } else if ('\\' === p.charAt(0)) {
391 | var decimalValue = +p.substring(1);
392 | if (decimalValue && decimalValue <= groupIndex) {
393 | parts[i] = '\\' + capturedGroups[groupIndex];
394 | }
395 | }
396 | }
397 |
398 | // Remove any prefix anchors so that the output will match anywhere.
399 | // ^^ really does mean an anchored match though.
400 | for (var i = 0, groupIndex = 0; i < n; ++i) {
401 | if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
402 | }
403 |
404 | // Expand letters to groups to handle mixing of case-sensitive and
405 | // case-insensitive patterns if necessary.
406 | if (regex.ignoreCase && needToFoldCase) {
407 | for (var i = 0; i < n; ++i) {
408 | var p = parts[i];
409 | var ch0 = p.charAt(0);
410 | if (p.length >= 2 && ch0 === '[') {
411 | parts[i] = caseFoldCharset(p);
412 | } else if (ch0 !== '\\') {
413 | // TODO: handle letters in numeric escapes.
414 | parts[i] = p.replace(
415 | /[a-zA-Z]/g,
416 | function (ch) {
417 | var cc = ch.charCodeAt(0);
418 | return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
419 | });
420 | }
421 | }
422 | }
423 |
424 | return parts.join('');
425 | }
426 |
427 | var rewritten = [];
428 | for (var i = 0, n = regexs.length; i < n; ++i) {
429 | var regex = regexs[i];
430 | if (regex.global || regex.multiline) { throw new Error('' + regex); }
431 | rewritten.push(
432 | '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
433 | }
434 |
435 | return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
436 | }
437 |
438 |
439 | /**
440 | * Split markup into a string of source code and an array mapping ranges in
441 | * that string to the text nodes in which they appear.
442 | *
443 | *
444 | * The HTML DOM structure:
445 | *
446 | * (Element "p"
447 | * (Element "b"
448 | * (Text "print ")) ; #1
449 | * (Text "'Hello '") ; #2
450 | * (Element "br") ; #3
451 | * (Text " + 'World';")) ; #4
452 | *
453 | *
454 | * corresponds to the HTML
455 | * {@code
print 'Hello '
+ 'World';
}.
456 | *
457 | *
458 | * It will produce the output:
459 | *
460 | * {
461 | * source: "print 'Hello '\n + 'World';",
462 | * // 1 2
463 | * // 012345678901234 5678901234567
464 | * spans: [0, #1, 6, #2, 14, #3, 15, #4]
465 | * }
466 | *
467 | *
468 | * where #1 is a reference to the {@code "print "} text node above, and so
469 | * on for the other text nodes.
470 | *
471 | *
472 | *
473 | * The {@code} spans array is an array of pairs. Even elements are the start
474 | * indices of substrings, and odd elements are the text nodes (or BR elements)
475 | * that contain the text for those substrings.
476 | * Substrings continue until the next index or the end of the source.
477 | *
478 | *
479 | * @param {Node} node an HTML DOM subtree containing source-code.
480 | * @return {Object} source code and the text nodes in which they occur.
481 | */
482 | function extractSourceSpans(node) {
483 | var nocode = /(?:^|\s)nocode(?:\s|$)/;
484 |
485 | var chunks = [];
486 | var length = 0;
487 | var spans = [];
488 | var k = 0;
489 |
490 | var whitespace;
491 | if (node.currentStyle) {
492 | whitespace = node.currentStyle.whiteSpace;
493 | } else if (window.getComputedStyle) {
494 | whitespace = document.defaultView.getComputedStyle(node, null)
495 | .getPropertyValue('white-space');
496 | }
497 | var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);
498 |
499 | function walk(node) {
500 | switch (node.nodeType) {
501 | case 1: // Element
502 | if (nocode.test(node.className)) { return; }
503 | for (var child = node.firstChild; child; child = child.nextSibling) {
504 | walk(child);
505 | }
506 | var nodeName = node.nodeName;
507 | if ('BR' === nodeName || 'LI' === nodeName) {
508 | chunks[k] = '\n';
509 | spans[k << 1] = length++;
510 | spans[(k++ << 1) | 1] = node;
511 | }
512 | break;
513 | case 3: case 4: // Text
514 | var text = node.nodeValue;
515 | if (text.length) {
516 | if (!isPreformatted) {
517 | text = text.replace(/[ \t\r\n]+/g, ' ');
518 | } else {
519 | text = text.replace(/\r\n?/g, '\n'); // Normalize newlines.
520 | }
521 | // TODO: handle tabs here?
522 | chunks[k] = text;
523 | spans[k << 1] = length;
524 | length += text.length;
525 | spans[(k++ << 1) | 1] = node;
526 | }
527 | break;
528 | }
529 | }
530 |
531 | walk(node);
532 |
533 | return {
534 | source: chunks.join('').replace(/\n$/, ''),
535 | spans: spans
536 | };
537 | }
538 |
539 |
540 | /**
541 | * Apply the given language handler to sourceCode and add the resulting
542 | * decorations to out.
543 | * @param {number} basePos the index of sourceCode within the chunk of source
544 | * whose decorations are already present on out.
545 | */
546 | function appendDecorations(basePos, sourceCode, langHandler, out) {
547 | if (!sourceCode) { return; }
548 | var job = {
549 | source: sourceCode,
550 | basePos: basePos
551 | };
552 | langHandler(job);
553 | out.push.apply(out, job.decorations);
554 | }
555 |
556 | /** Given triples of [style, pattern, context] returns a lexing function,
557 | * The lexing function interprets the patterns to find token boundaries and
558 | * returns a decoration list of the form
559 | * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
560 | * where index_n is an index into the sourceCode, and style_n is a style
561 | * constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to
562 | * all characters in sourceCode[index_n-1:index_n].
563 | *
564 | * The stylePatterns is a list whose elements have the form
565 | * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
566 | *
567 | * Style is a style constant like PR_PLAIN, or can be a string of the
568 | * form 'lang-FOO', where FOO is a language extension describing the
569 | * language of the portion of the token in $1 after pattern executes.
570 | * E.g., if style is 'lang-lisp', and group 1 contains the text
571 | * '(hello (world))', then that portion of the token will be passed to the
572 | * registered lisp handler for formatting.
573 | * The text before and after group 1 will be restyled using this decorator
574 | * so decorators should take care that this doesn't result in infinite
575 | * recursion. For example, the HTML lexer rule for SCRIPT elements looks
576 | * something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match
577 | * '