SiteOrigin CSS - Version 1.2.0

Version Description

  • 6 June 2018 =
  • Updated CSS library.
  • UI changes to make it more obvious when viewing revision.
  • Ensure revisions are sorted in descending time order.
  • Don't link to revision currently being displayed.
  • Add search functionality to editor.
  • Enable persistent search and JumpToLine.
Download this release

Release Info

Developer gpriday
Plugin Icon 128x128 SiteOrigin CSS
Version 1.2.0
Comparing to
See all releases

Code changes from version 1.1.5 to 1.2.0

css/admin.css CHANGED
@@ -1,645 +1,645 @@
1
- #siteorigin-custom-css {
2
- color: #333;
3
- margin: 0 0 0 -20px;
4
- }
5
- #siteorigin-custom-css h2 {
6
- background: #f8f8f8;
7
- padding: 20px;
8
- border-bottom: 1px solid #d0d0d0;
9
- margin-bottom: 20px;
10
- box-shadow: 0 1px 1px rgba(0, 0, 0, 0.035);
11
- }
12
- #siteorigin-custom-css h2 .icon {
13
- width: 40px;
14
- height: auto;
15
- margin: -8px 10px -8px 0;
16
- }
17
- #siteorigin-custom-css .updated {
18
- margin: 0 20px 20px 20px ;
19
- }
20
- #siteorigin-custom-css #poststuff {
21
- padding: 0 20px;
22
- }
23
- #siteorigin-custom-css #poststuff .postbox {
24
- border: 1px solid #D0D0D0;
25
- }
26
- #siteorigin-custom-css #poststuff .postbox h3.hndle {
27
- cursor: default;
28
- border-bottom: 1px solid #D0D0D0;
29
- background: #efefef;
30
- position: relative;
31
- }
32
- #siteorigin-custom-css #poststuff .postbox h3.hndle .hide {
33
- position: absolute;
34
- top: 50%;
35
- line-height: 1em;
36
- margin-top: -0.5em;
37
- right: 12px;
38
- }
39
- #siteorigin-custom-css #poststuff #so-custom-css-getting-started .inside {
40
- padding: 0 6px 6px 6px;
41
- }
42
- #siteorigin-custom-css #poststuff #so-custom-css-getting-started .inside img {
43
- display: block;
44
- width: 100%;
45
- height: auto;
46
- }
47
- #so-custom-css-form {
48
- margin-right: 340px;
49
- }
50
- #so-custom-css-info {
51
- width: 315px;
52
- float: right;
53
- }
54
- #so-custom-css-info *:first-child {
55
- margin-top: 0;
56
- }
57
- #so-custom-css-info *:last-child {
58
- margin-bottom: 0;
59
- }
60
- #so-custom-css-revisions ol {
61
- list-style: none;
62
- margin: 0;
63
- }
64
- #so-custom-css-revisions ol li {
65
- margin: 0;
66
- line-height: 2.2em;
67
- }
68
- #so-custom-css-form .custom-css-preview iframe,
69
- #so-custom-css-form .custom-css-preview #preview-navigator {
70
- display: none;
71
- }
72
- #so-custom-css-form .custom-css-toolbar {
73
- border: 1px solid #D0D0D0;
74
- border-bottom: none;
75
- background: #efefef;
76
- padding: 8px 10px;
77
- overflow: auto;
78
- }
79
- #so-custom-css-form .custom-css-toolbar .toolbar-function-buttons {
80
- float: left;
81
- }
82
- #so-custom-css-form .custom-css-toolbar .toolbar-function-buttons .toolbar-functions-dropdown {
83
- display: none;
84
- }
85
- #so-custom-css-form .custom-css-toolbar .toolbar-function-buttons ul.toolbar-buttons {
86
- margin: 0;
87
- }
88
- #so-custom-css-form .custom-css-toolbar .toolbar-function-buttons ul.toolbar-buttons li {
89
- display: inline-block;
90
- margin: 0;
91
- padding: 0;
92
- }
93
- #so-custom-css-form .custom-css-toolbar .toolbar-action-buttons {
94
- float: right;
95
- }
96
- #so-custom-css-form .custom-css-toolbar .toolbar-action-buttons a.active {
97
- border-color: #b4c4cf;
98
- background-color: #e9f9ff;
99
- color: #596872;
100
- }
101
- #so-custom-css-form .custom-css-toolbar .toolbar-action-buttons .editor-expand {
102
- float: right;
103
- text-decoration: none;
104
- color: #666;
105
- }
106
- #so-custom-css-form .custom-css-toolbar .toolbar-action-buttons .editor-expand .fa-compress {
107
- display: none;
108
- }
109
- #so-custom-css-form .custom-css-toolbar .fa {
110
- font-size: 14px;
111
- }
112
- #so-custom-css-form .custom-css-container {
113
- border: 1px solid #D0D0D0;
114
- background: #f7f7f7;
115
- cursor: text;
116
- overflow: hidden;
117
- }
118
- #so-custom-css-form .custom-css-container .CodeMirror {
119
- height: auto;
120
- }
121
- #so-custom-css-form .custom-css-container .CodeMirror-scroll {
122
- min-height: 300px;
123
- }
124
- #so-custom-css-form .custom-css-container .CodeMirror-lines {
125
- padding: 8px 0 8px 0;
126
- }
127
- #so-custom-css-form .custom-css-container textarea {
128
- border: 0;
129
- padding: 8px 0 8px 4px;
130
- width: 100%;
131
- min-height: 300px;
132
- display: block;
133
- font-family: monospace;
134
- font-size: 13px;
135
- line-height: 1.4em;
136
- border-left: 1px solid #ddd;
137
- margin-left: 16px;
138
- }
139
- #so-custom-css-form .decoration {
140
- display: none;
141
- }
142
- #so-custom-css-form.expanded {
143
- z-index: 100000;
144
- position: fixed;
145
- top: 0;
146
- left: 0;
147
- bottom: 0;
148
- width: 340px;
149
- }
150
- #so-custom-css-form.expanded .custom-css-toolbar .editor-expand .fa-expand {
151
- display: none;
152
- }
153
- #so-custom-css-form.expanded .custom-css-toolbar .editor-expand .fa-compress {
154
- display: inline-block;
155
- }
156
- #so-custom-css-form.expanded .decoration {
157
- display: block;
158
- position: absolute;
159
- top: 0;
160
- bottom: 0;
161
- left: 339px;
162
- width: 2px;
163
- background: rgba(0, 0, 0, 0.1);
164
- }
165
- #so-custom-css-form.expanded .description {
166
- display: none;
167
- }
168
- #so-custom-css-form.expanded .submit {
169
- display: none;
170
- }
171
- #so-custom-css-form.expanded .custom-css-preview {
172
- position: fixed;
173
- display: block;
174
- top: 40px;
175
- right: 0;
176
- bottom: 0;
177
- left: 340px;
178
- background: #ffffff;
179
- }
180
- #so-custom-css-form.expanded .custom-css-preview #preview-navigator {
181
- display: block;
182
- -ms-box-sizing: border-box;
183
- -moz-box-sizing: border-box;
184
- -webkit-box-sizing: border-box;
185
- box-sizing: border-box;
186
- padding: 6px 10px;
187
- position: absolute;
188
- width: 100%;
189
- height: 40px;
190
- top: -40px;
191
- background: #bbb;
192
- background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #bbb), color-stop(1, #eee));
193
- background: -ms-linear-gradient(bottom, #bbb, #eee);
194
- background: -moz-linear-gradient(center bottom, #bbb 0%, #eee 100%);
195
- background: -o-linear-gradient(#eee, #bbb);
196
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eee', endColorstr='#bbb', GradientType=0);
197
- border-bottom: 1px solid #888;
198
- }
199
- #so-custom-css-form.expanded .custom-css-preview #preview-navigator input {
200
- width: 100%;
201
- border: 1px solid #888;
202
- border-radius: 2px;
203
- color: #444;
204
- -webkit-box-shadow: inset 2px 2px 2px rgba( 0,0,0,0.1 );
205
- -moz-box-shadow: inset 2px 2px 2px rgba( 0,0,0,0.1 );
206
- box-shadow: inset 2px 2px 2px rgba( 0,0,0,0.1 );
207
- }
208
- #so-custom-css-form.expanded .custom-css-preview #preview-iframe {
209
- display: block;
210
- width: 100%;
211
- height: 100%;
212
- overflow-x: hidden;
213
- }
214
- #so-custom-css-properties {
215
- display: none;
216
- position: fixed;
217
- top: 0;
218
- left: -338px;
219
- bottom: 0;
220
- width: 338px;
221
- background: #ffffff;
222
- border: 1px solid #D0D0D0;
223
- overflow-y: auto;
224
- z-index: 100000;
225
- }
226
- #so-custom-css-properties .toolbar {
227
- display: block;
228
- padding: 7px 10px;
229
- border-bottom: 1px solid #aaa;
230
- background: #F6F6F6;
231
- text-align: left;
232
- }
233
- #so-custom-css-properties .toolbar select {
234
- line-height: 1;
235
- font-size: 13px;
236
- max-width: 265px;
237
- -webkit-transition: all 0.5s ease;
238
- -moz-transition: all 0.5s ease;
239
- -o-transition: all 0.5s ease;
240
- transition: all 0.5s ease;
241
- }
242
- #so-custom-css-properties .toolbar select.highlighted {
243
- background: #daeaf7;
244
- }
245
- #so-custom-css-properties .toolbar .close {
246
- float: right;
247
- margin: 2px 4px 0 0;
248
- }
249
- #so-custom-css-properties .section-tabs {
250
- list-style: none;
251
- height: auto;
252
- margin: 0;
253
- box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
254
- }
255
- #so-custom-css-properties .section-tabs li {
256
- box-sizing: border-box;
257
- float: left;
258
- width: 33.333%;
259
- padding: 10px 7px;
260
- border: 1px solid #aaa;
261
- background: #F6F6F6;
262
- font-weight: bold;
263
- border-top: 0;
264
- border-left: 0;
265
- font-size: 13px;
266
- line-height: 1em;
267
- cursor: pointer;
268
- white-space: nowrap;
269
- overflow: hidden;
270
- color: #666;
271
- }
272
- #so-custom-css-properties .section-tabs li:hover {
273
- background: #fff;
274
- }
275
- #so-custom-css-properties .section-tabs li .fa {
276
- float: left;
277
- display: block;
278
- margin: -1px 6px -1px 0;
279
- font-size: 15px;
280
- color: #666;
281
- }
282
- #so-custom-css-properties .section-tabs li:last-child {
283
- border-right: 0;
284
- }
285
- #so-custom-css-properties .section-tabs li.active {
286
- color: #444;
287
- background: #e8e8e8;
288
- }
289
- #so-custom-css-properties .section-tabs li.active .fa {
290
- color: #333;
291
- }
292
- #so-custom-css-properties .sections .section {
293
- display: none;
294
- padding: 10px;
295
- }
296
- #so-custom-css-properties .sections .fields-table {
297
- width: 100%;
298
- padding-top: 5px;
299
- }
300
- #so-custom-css-properties .sections .fields-table th,
301
- #so-custom-css-properties .sections .fields-table td {
302
- position: relative;
303
- zoom: 1;
304
- }
305
- #so-custom-css-properties .sections .fields-table th:before,
306
- #so-custom-css-properties .sections .fields-table td:before {
307
- content: '';
308
- display: block;
309
- }
310
- #so-custom-css-properties .sections .fields-table th:after,
311
- #so-custom-css-properties .sections .fields-table td:after {
312
- content: '';
313
- display: table;
314
- clear: both;
315
- }
316
- #so-custom-css-properties .sections .fields-table th[scope="row"] {
317
- font-weight: bold;
318
- font-size: 12px;
319
- padding-right: 10px;
320
- text-align: left;
321
- width: 36%;
322
- vertical-align: top;
323
- }
324
- #so-custom-css-properties .sections .fields-table td {
325
- padding: 0 0 12px 0 ;
326
- }
327
- #so-custom-css-properties .sections .fields-table input,
328
- #so-custom-css-properties .sections .fields-table select {
329
- display: block;
330
- margin: 0 25px 0 0;
331
- border: 1px solid #c0c0c0;
332
- width: 175px;
333
- box-sizing: border-box;
334
- border-radius: 0;
335
- font-size: 12px;
336
- padding: 5px 8px;
337
- }
338
- #so-custom-css-properties .sections .fields-table .minicolors input {
339
- box-sizing: border-box;
340
- height: 30px;
341
- padding: 5px 0 5px 30px;
342
- }
343
- #so-custom-css-properties .sections .fields-table .select {
344
- display: block;
345
- position: absolute;
346
- top: 0px;
347
- right: 1px;
348
- padding: 5px;
349
- cursor: pointer;
350
- font-size: 15px;
351
- }
352
- #so-custom-css-properties .sections .fields-table .select-tabs {
353
- margin: 0;
354
- height: 40px;
355
- }
356
- #so-custom-css-properties .sections .fields-table .select-tabs .select-tab {
357
- cursor: pointer;
358
- float: left;
359
- -webkit-box-sizing: border-box;
360
- -moz-box-sizing: border-box;
361
- box-sizing: border-box;
362
- text-align: center;
363
- border: 1px solid #c0c0c0;
364
- padding: 4px 2px;
365
- border-right-width: 0;
366
- background: #f7f7f7;
367
- }
368
- #so-custom-css-properties .sections .fields-table .select-tabs .select-tab .fa {
369
- line-height: 14px;
370
- font-size: 14px;
371
- color: #777;
372
- }
373
- #so-custom-css-properties .sections .fields-table .select-tabs .select-tab:last-child {
374
- border-right-width: 1px;
375
- }
376
- #so-custom-css-properties .sections .fields-table .select-tabs .select-tab:hover,
377
- #so-custom-css-properties .sections .fields-table .select-tabs .select-tab.active {
378
- background: #e9e9e9;
379
- }
380
- #so-custom-css-properties .sections .fields-table .select-tabs .select-tab:hover .fa,
381
- #so-custom-css-properties .sections .fields-table .select-tabs .select-tab.active .fa {
382
- color: #333;
383
- }
384
- #so-custom-css-properties .sections .fields-table .side-tabs {
385
- height: 26px;
386
- }
387
- #so-custom-css-properties .sections .fields-table .side-tabs .side-tab {
388
- width: 20%;
389
- text-align: center;
390
- padding: 5px;
391
- line-height: 0;
392
- }
393
- #so-custom-css-properties .sections .fields-table .side-tabs .side-tab div {
394
- display: inline-block;
395
- width: 10px;
396
- height: 10px;
397
- border: 2px solid #aaa;
398
- }
399
- #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-all {
400
- border-color: #12609b;
401
- }
402
- #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-top {
403
- border-top-color: #12609b;
404
- }
405
- #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-left {
406
- border-left-color: #12609b;
407
- }
408
- #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-bottom {
409
- border-bottom-color: #12609b;
410
- }
411
- #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-right {
412
- border-right-color: #12609b;
413
- }
414
- #so-custom-css-properties .sections .fields-table .sides .side > div {
415
- margin-bottom: 5px;
416
- }
417
- #so-custom-css-properties .sections .fields-table .sides .side > div:last-child {
418
- margin-bottom: 0;
419
- }
420
- .css-editor-snippet-browser {
421
- display: none;
422
- }
423
- .css-editor-snippet-browser .snippet-browser-overlay {
424
- position: fixed;
425
- z-index: 100000;
426
- top: 0;
427
- left: 0;
428
- right: 0;
429
- bottom: 0;
430
- background: rgba(0, 0, 0, 0.8);
431
- }
432
- .css-editor-snippet-browser .snippet-browser-dialog > div {
433
- position: fixed;
434
- z-index: 100001;
435
- background: #fff;
436
- box-sizing: border-box;
437
- }
438
- .css-editor-snippet-browser .snippet-browser-dialog .toolbar {
439
- top: 40px;
440
- left: 40px;
441
- right: 40px;
442
- height: 50px;
443
- background: #FCFCFC;
444
- border-bottom: 1px solid #dddddd;
445
- overflow: hidden;
446
- }
447
- .css-editor-snippet-browser .snippet-browser-dialog .toolbar h1 {
448
- padding: 0 16px;
449
- font-size: 22px;
450
- line-height: 50px;
451
- margin: 0;
452
- color: #444;
453
- }
454
- .css-editor-snippet-browser .snippet-browser-dialog .toolbar .close {
455
- cursor: pointer;
456
- color: #777;
457
- background-color: transparent;
458
- height: 50px;
459
- width: 50px;
460
- padding: 15px 0 0 0;
461
- position: absolute;
462
- text-align: center;
463
- border: 0;
464
- border-left: 1px solid #ddd;
465
- top: 0;
466
- right: 0;
467
- text-decoration: none;
468
- box-sizing: border-box;
469
- }
470
- .css-editor-snippet-browser .snippet-browser-dialog .toolbar .close:hover {
471
- background: #dddddd;
472
- }
473
- .css-editor-snippet-browser .snippet-browser-dialog .toolbar .close .icon:before {
474
- content: '\f158';
475
- font: normal 20px/1 'dashicons';
476
- vertical-align: middle;
477
- -webkit-font-smoothing: antialiased;
478
- -moz-osx-font-smoothing: grayscale;
479
- color: #666;
480
- }
481
- .css-editor-snippet-browser .snippet-browser-dialog .sidebar {
482
- top: 90px;
483
- left: 40px;
484
- bottom: 90px;
485
- width: 300px;
486
- background: #f3f3f3;
487
- border-right: 1px solid #dddddd;
488
- padding: 16px;
489
- overflow: auto;
490
- }
491
- .css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippet-search {
492
- width: 100%;
493
- margin-bottom: 20px;
494
- padding: 8px;
495
- }
496
- .css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippets {
497
- margin: 0;
498
- }
499
- .css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippets .snippet {
500
- cursor: pointer;
501
- font-size: 1.1em;
502
- line-height: 1.35em;
503
- margin-bottom: 20px;
504
- }
505
- .css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippets .snippet.active {
506
- font-weight: bold;
507
- }
508
- .css-editor-snippet-browser .snippet-browser-dialog .main {
509
- top: 90px;
510
- left: 340px;
511
- right: 40px;
512
- bottom: 90px;
513
- background: #fff;
514
- overflow: auto;
515
- }
516
- .css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view {
517
- padding: 20px;
518
- }
519
- .css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view .snippet-title {
520
- margin: 0 0 0.75em 0;
521
- padding: 0;
522
- }
523
- .css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view .snippet-description {
524
- font-size: 1.1em;
525
- color: #666;
526
- margin-bottom: 2em;
527
- }
528
- .css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view .snippet-code {
529
- padding: 20px;
530
- border: 1px solid #d0d0d0;
531
- background: #f8f8f8;
532
- }
533
- .css-editor-snippet-browser .snippet-browser-dialog .buttons {
534
- bottom: 40px;
535
- left: 40px;
536
- right: 40px;
537
- height: 50px;
538
- background: #FCFCFC;
539
- border-top: 1px solid #dddddd;
540
- text-align: right;
541
- padding: 10px 20px;
542
- overflow: hidden;
543
- }
544
- .socss-field-measurement {
545
- position: relative;
546
- }
547
- .socss-field-measurement input.socss-field-input {
548
- min-height: 1.5em;
549
- padding-right: 50px;
550
- width: 120px !important;
551
- box-sizing: border-box;
552
- }
553
- .socss-field-measurement .dashicons-arrow-down {
554
- position: absolute;
555
- top: 4px;
556
- left: 97px;
557
- cursor: pointer;
558
- }
559
- .socss-field-measurement .dropdown {
560
- display: none;
561
- background: #F5F5F5;
562
- border: 1px solid #c0c0c0;
563
- position: absolute;
564
- top: 27px;
565
- left: 71px;
566
- width: 50px;
567
- z-index: 2;
568
- margin: 0;
569
- box-sizing: border-box;
570
- box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
571
- }
572
- .socss-field-measurement .dropdown li {
573
- padding: 5px 0;
574
- text-align: center;
575
- line-height: 1.1em;
576
- font-size: 11px;
577
- margin: 0;
578
- }
579
- .socss-field-measurement .dropdown li:hover,
580
- .socss-field-measurement .dropdown li.active {
581
- background: #e8e8e8;
582
- cursor: pointer;
583
- }
584
- .socss-field-measurement .units {
585
- position: absolute;
586
- top: 5px;
587
- left: 12px;
588
- color: #bbb;
589
- pointer-events: none;
590
- }
591
- .socss-diw {
592
- position: absolute;
593
- top: 0px;
594
- left: 124px;
595
- }
596
- .socss-diw .inc-button,
597
- .socss-diw .dec-button {
598
- cursor: pointer;
599
- box-sizing: border-box;
600
- float: left;
601
- padding: 8px;
602
- user-select: none;
603
- text-align: center;
604
- margin: 0;
605
- width: 27px;
606
- height: 27px;
607
- font-size: 10px;
608
- }
609
- .socss-diw .inc-button {
610
- border-left: 0;
611
- }
612
- .socss-button {
613
- cursor: pointer;
614
- line-height: 1em;
615
- display: inline-block;
616
- border: 1px solid #c0c0c0;
617
- background: #f7f7f7;
618
- text-decoration: none;
619
- padding: 6px;
620
- font-weight: bold;
621
- color: #555;
622
- font-size: 0.95em;
623
- margin-left: 5px;
624
- -webkit-user-select: none;
625
- -moz-user-select: none;
626
- -ms-user-select: none;
627
- -o-user-select: none;
628
- user-select: none;
629
- }
630
- .socss-button:hover {
631
- border-color: #b0b0b0;
632
- background: #fff;
633
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
634
- }
635
- .socss-button:hover .fa {
636
- color: #333;
637
- }
638
- .socss-button .fa {
639
- color: #555;
640
- }
641
- .CodeMirror-lint-tooltip,
642
- .CodeMirror-hints {
643
- /* This is above the editor in full-screen mode */
644
- z-index: 100002;
645
- }
1
+ #siteorigin-custom-css {
2
+ color: #333;
3
+ margin: 0 0 0 -20px;
4
+ }
5
+ #siteorigin-custom-css h2 {
6
+ background: #f8f8f8;
7
+ padding: 20px;
8
+ border-bottom: 1px solid #d0d0d0;
9
+ margin-bottom: 20px;
10
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.035);
11
+ }
12
+ #siteorigin-custom-css h2 .icon {
13
+ width: 40px;
14
+ height: auto;
15
+ margin: -8px 10px -8px 0;
16
+ }
17
+ #siteorigin-custom-css .notice {
18
+ margin: 0 20px 20px 20px;
19
+ }
20
+ #siteorigin-custom-css #poststuff {
21
+ padding: 0 20px;
22
+ }
23
+ #siteorigin-custom-css #poststuff .postbox {
24
+ border: 1px solid #D0D0D0;
25
+ }
26
+ #siteorigin-custom-css #poststuff .postbox h3.hndle {
27
+ cursor: default;
28
+ border-bottom: 1px solid #D0D0D0;
29
+ background: #efefef;
30
+ position: relative;
31
+ }
32
+ #siteorigin-custom-css #poststuff .postbox h3.hndle .hide {
33
+ position: absolute;
34
+ top: 50%;
35
+ line-height: 1em;
36
+ margin-top: -0.5em;
37
+ right: 12px;
38
+ }
39
+ #siteorigin-custom-css #poststuff #so-custom-css-getting-started .inside {
40
+ padding: 0 6px 6px 6px;
41
+ }
42
+ #siteorigin-custom-css #poststuff #so-custom-css-getting-started .inside img {
43
+ display: block;
44
+ width: 100%;
45
+ height: auto;
46
+ }
47
+ #so-custom-css-form {
48
+ margin-right: 340px;
49
+ }
50
+ #so-custom-css-info {
51
+ width: 315px;
52
+ float: right;
53
+ }
54
+ #so-custom-css-info *:first-child {
55
+ margin-top: 0;
56
+ }
57
+ #so-custom-css-info *:last-child {
58
+ margin-bottom: 0;
59
+ }
60
+ #so-custom-css-revisions ol {
61
+ list-style: none;
62
+ margin: 0;
63
+ }
64
+ #so-custom-css-revisions ol li {
65
+ margin: 0;
66
+ line-height: 2.2em;
67
+ }
68
+ #so-custom-css-form .custom-css-preview iframe,
69
+ #so-custom-css-form .custom-css-preview #preview-navigator {
70
+ display: none;
71
+ }
72
+ #so-custom-css-form .custom-css-toolbar {
73
+ border: 1px solid #D0D0D0;
74
+ border-bottom: none;
75
+ background: #efefef;
76
+ padding: 8px 10px;
77
+ overflow: auto;
78
+ }
79
+ #so-custom-css-form .custom-css-toolbar .toolbar-function-buttons {
80
+ float: left;
81
+ }
82
+ #so-custom-css-form .custom-css-toolbar .toolbar-function-buttons .toolbar-functions-dropdown {
83
+ display: none;
84
+ }
85
+ #so-custom-css-form .custom-css-toolbar .toolbar-function-buttons ul.toolbar-buttons {
86
+ margin: 0;
87
+ }
88
+ #so-custom-css-form .custom-css-toolbar .toolbar-function-buttons ul.toolbar-buttons li {
89
+ display: inline-block;
90
+ margin: 0;
91
+ padding: 0;
92
+ }
93
+ #so-custom-css-form .custom-css-toolbar .toolbar-action-buttons {
94
+ float: right;
95
+ }
96
+ #so-custom-css-form .custom-css-toolbar .toolbar-action-buttons a.active {
97
+ border-color: #b4c4cf;
98
+ background-color: #e9f9ff;
99
+ color: #596872;
100
+ }
101
+ #so-custom-css-form .custom-css-toolbar .toolbar-action-buttons .editor-expand {
102
+ float: right;
103
+ text-decoration: none;
104
+ color: #666;
105
+ }
106
+ #so-custom-css-form .custom-css-toolbar .toolbar-action-buttons .editor-expand .fa-compress {
107
+ display: none;
108
+ }
109
+ #so-custom-css-form .custom-css-toolbar .fa {
110
+ font-size: 14px;
111
+ }
112
+ #so-custom-css-form .custom-css-container {
113
+ border: 1px solid #D0D0D0;
114
+ background: #f7f7f7;
115
+ cursor: text;
116
+ overflow: hidden;
117
+ }
118
+ #so-custom-css-form .custom-css-container .CodeMirror {
119
+ height: auto;
120
+ }
121
+ #so-custom-css-form .custom-css-container .CodeMirror-scroll {
122
+ min-height: 300px;
123
+ }
124
+ #so-custom-css-form .custom-css-container .CodeMirror-lines {
125
+ padding: 8px 0 8px 0;
126
+ }
127
+ #so-custom-css-form .custom-css-container textarea {
128
+ border: 0;
129
+ padding: 8px 0 8px 4px;
130
+ width: 100%;
131
+ min-height: 300px;
132
+ display: block;
133
+ font-family: monospace;
134
+ font-size: 13px;
135
+ line-height: 1.4em;
136
+ border-left: 1px solid #ddd;
137
+ margin-left: 16px;
138
+ }
139
+ #so-custom-css-form .decoration {
140
+ display: none;
141
+ }
142
+ #so-custom-css-form.expanded {
143
+ z-index: 100000;
144
+ position: fixed;
145
+ top: 0;
146
+ left: 0;
147
+ bottom: 0;
148
+ width: 340px;
149
+ }
150
+ #so-custom-css-form.expanded .custom-css-toolbar .editor-expand .fa-expand {
151
+ display: none;
152
+ }
153
+ #so-custom-css-form.expanded .custom-css-toolbar .editor-expand .fa-compress {
154
+ display: inline-block;
155
+ }
156
+ #so-custom-css-form.expanded .decoration {
157
+ display: block;
158
+ position: absolute;
159
+ top: 0;
160
+ bottom: 0;
161
+ left: 339px;
162
+ width: 2px;
163
+ background: rgba(0, 0, 0, 0.1);
164
+ }
165
+ #so-custom-css-form.expanded .description {
166
+ display: none;
167
+ }
168
+ #so-custom-css-form.expanded .submit {
169
+ display: none;
170
+ }
171
+ #so-custom-css-form.expanded .custom-css-preview {
172
+ position: fixed;
173
+ display: block;
174
+ top: 40px;
175
+ right: 0;
176
+ bottom: 0;
177
+ left: 340px;
178
+ background: #ffffff;
179
+ }
180
+ #so-custom-css-form.expanded .custom-css-preview #preview-navigator {
181
+ display: block;
182
+ -ms-box-sizing: border-box;
183
+ -moz-box-sizing: border-box;
184
+ -webkit-box-sizing: border-box;
185
+ box-sizing: border-box;
186
+ padding: 6px 10px;
187
+ position: absolute;
188
+ width: 100%;
189
+ height: 40px;
190
+ top: -40px;
191
+ background: #bbb;
192
+ background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #bbb), color-stop(1, #eee));
193
+ background: -ms-linear-gradient(bottom, #bbb, #eee);
194
+ background: -moz-linear-gradient(center bottom, #bbb 0%, #eee 100%);
195
+ background: -o-linear-gradient(#eee, #bbb);
196
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eee', endColorstr='#bbb', GradientType=0);
197
+ border-bottom: 1px solid #888;
198
+ }
199
+ #so-custom-css-form.expanded .custom-css-preview #preview-navigator input {
200
+ width: 100%;
201
+ border: 1px solid #888;
202
+ border-radius: 2px;
203
+ color: #444;
204
+ -webkit-box-shadow: inset 2px 2px 2px rgba( 0,0,0,0.1 );
205
+ -moz-box-shadow: inset 2px 2px 2px rgba( 0,0,0,0.1 );
206
+ box-shadow: inset 2px 2px 2px rgba( 0,0,0,0.1 );
207
+ }
208
+ #so-custom-css-form.expanded .custom-css-preview #preview-iframe {
209
+ display: block;
210
+ width: 100%;
211
+ height: 100%;
212
+ overflow-x: hidden;
213
+ }
214
+ #so-custom-css-properties {
215
+ display: none;
216
+ position: fixed;
217
+ top: 0;
218
+ left: -338px;
219
+ bottom: 0;
220
+ width: 338px;
221
+ background: #ffffff;
222
+ border: 1px solid #D0D0D0;
223
+ overflow-y: auto;
224
+ z-index: 100000;
225
+ }
226
+ #so-custom-css-properties .toolbar {
227
+ display: block;
228
+ padding: 7px 10px;
229
+ border-bottom: 1px solid #aaa;
230
+ background: #F6F6F6;
231
+ text-align: left;
232
+ }
233
+ #so-custom-css-properties .toolbar select {
234
+ line-height: 1;
235
+ font-size: 13px;
236
+ max-width: 265px;
237
+ -webkit-transition: all 0.5s ease;
238
+ -moz-transition: all 0.5s ease;
239
+ -o-transition: all 0.5s ease;
240
+ transition: all 0.5s ease;
241
+ }
242
+ #so-custom-css-properties .toolbar select.highlighted {
243
+ background: #daeaf7;
244
+ }
245
+ #so-custom-css-properties .toolbar .close {
246
+ float: right;
247
+ margin: 2px 4px 0 0;
248
+ }
249
+ #so-custom-css-properties .section-tabs {
250
+ list-style: none;
251
+ height: auto;
252
+ margin: 0;
253
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
254
+ }
255
+ #so-custom-css-properties .section-tabs li {
256
+ box-sizing: border-box;
257
+ float: left;
258
+ width: 33.333%;
259
+ padding: 10px 7px;
260
+ border: 1px solid #aaa;
261
+ background: #F6F6F6;
262
+ font-weight: bold;
263
+ border-top: 0;
264
+ border-left: 0;
265
+ font-size: 13px;
266
+ line-height: 1em;
267
+ cursor: pointer;
268
+ white-space: nowrap;
269
+ overflow: hidden;
270
+ color: #666;
271
+ }
272
+ #so-custom-css-properties .section-tabs li:hover {
273
+ background: #fff;
274
+ }
275
+ #so-custom-css-properties .section-tabs li .fa {
276
+ float: left;
277
+ display: block;
278
+ margin: -1px 6px -1px 0;
279
+ font-size: 15px;
280
+ color: #666;
281
+ }
282
+ #so-custom-css-properties .section-tabs li:last-child {
283
+ border-right: 0;
284
+ }
285
+ #so-custom-css-properties .section-tabs li.active {
286
+ color: #444;
287
+ background: #e8e8e8;
288
+ }
289
+ #so-custom-css-properties .section-tabs li.active .fa {
290
+ color: #333;
291
+ }
292
+ #so-custom-css-properties .sections .section {
293
+ display: none;
294
+ padding: 10px;
295
+ }
296
+ #so-custom-css-properties .sections .fields-table {
297
+ width: 100%;
298
+ padding-top: 5px;
299
+ }
300
+ #so-custom-css-properties .sections .fields-table th,
301
+ #so-custom-css-properties .sections .fields-table td {
302
+ position: relative;
303
+ zoom: 1;
304
+ }
305
+ #so-custom-css-properties .sections .fields-table th:before,
306
+ #so-custom-css-properties .sections .fields-table td:before {
307
+ content: '';
308
+ display: block;
309
+ }
310
+ #so-custom-css-properties .sections .fields-table th:after,
311
+ #so-custom-css-properties .sections .fields-table td:after {
312
+ content: '';
313
+ display: table;
314
+ clear: both;
315
+ }
316
+ #so-custom-css-properties .sections .fields-table th[scope="row"] {
317
+ font-weight: bold;
318
+ font-size: 12px;
319
+ padding-right: 10px;
320
+ text-align: left;
321
+ width: 36%;
322
+ vertical-align: top;
323
+ }
324
+ #so-custom-css-properties .sections .fields-table td {
325
+ padding: 0 0 12px 0 ;
326
+ }
327
+ #so-custom-css-properties .sections .fields-table input,
328
+ #so-custom-css-properties .sections .fields-table select {
329
+ display: block;
330
+ margin: 0 25px 0 0;
331
+ border: 1px solid #c0c0c0;
332
+ width: 175px;
333
+ box-sizing: border-box;
334
+ border-radius: 0;
335
+ font-size: 12px;
336
+ padding: 5px 8px;
337
+ }
338
+ #so-custom-css-properties .sections .fields-table .minicolors input {
339
+ box-sizing: border-box;
340
+ height: 30px;
341
+ padding: 5px 0 5px 30px;
342
+ }
343
+ #so-custom-css-properties .sections .fields-table .select {
344
+ display: block;
345
+ position: absolute;
346
+ top: 0px;
347
+ right: 1px;
348
+ padding: 5px;
349
+ cursor: pointer;
350
+ font-size: 15px;
351
+ }
352
+ #so-custom-css-properties .sections .fields-table .select-tabs {
353
+ margin: 0;
354
+ height: 40px;
355
+ }
356
+ #so-custom-css-properties .sections .fields-table .select-tabs .select-tab {
357
+ cursor: pointer;
358
+ float: left;
359
+ -webkit-box-sizing: border-box;
360
+ -moz-box-sizing: border-box;
361
+ box-sizing: border-box;
362
+ text-align: center;
363
+ border: 1px solid #c0c0c0;
364
+ padding: 4px 2px;
365
+ border-right-width: 0;
366
+ background: #f7f7f7;
367
+ }
368
+ #so-custom-css-properties .sections .fields-table .select-tabs .select-tab .fa {
369
+ line-height: 14px;
370
+ font-size: 14px;
371
+ color: #777;
372
+ }
373
+ #so-custom-css-properties .sections .fields-table .select-tabs .select-tab:last-child {
374
+ border-right-width: 1px;
375
+ }
376
+ #so-custom-css-properties .sections .fields-table .select-tabs .select-tab:hover,
377
+ #so-custom-css-properties .sections .fields-table .select-tabs .select-tab.active {
378
+ background: #e9e9e9;
379
+ }
380
+ #so-custom-css-properties .sections .fields-table .select-tabs .select-tab:hover .fa,
381
+ #so-custom-css-properties .sections .fields-table .select-tabs .select-tab.active .fa {
382
+ color: #333;
383
+ }
384
+ #so-custom-css-properties .sections .fields-table .side-tabs {
385
+ height: 26px;
386
+ }
387
+ #so-custom-css-properties .sections .fields-table .side-tabs .side-tab {
388
+ width: 20%;
389
+ text-align: center;
390
+ padding: 5px;
391
+ line-height: 0;
392
+ }
393
+ #so-custom-css-properties .sections .fields-table .side-tabs .side-tab div {
394
+ display: inline-block;
395
+ width: 10px;
396
+ height: 10px;
397
+ border: 2px solid #aaa;
398
+ }
399
+ #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-all {
400
+ border-color: #12609b;
401
+ }
402
+ #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-top {
403
+ border-top-color: #12609b;
404
+ }
405
+ #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-left {
406
+ border-left-color: #12609b;
407
+ }
408
+ #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-bottom {
409
+ border-bottom-color: #12609b;
410
+ }
411
+ #so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-right {
412
+ border-right-color: #12609b;
413
+ }
414
+ #so-custom-css-properties .sections .fields-table .sides .side > div {
415
+ margin-bottom: 5px;
416
+ }
417
+ #so-custom-css-properties .sections .fields-table .sides .side > div:last-child {
418
+ margin-bottom: 0;
419
+ }
420
+ .css-editor-snippet-browser {
421
+ display: none;
422
+ }
423
+ .css-editor-snippet-browser .snippet-browser-overlay {
424
+ position: fixed;
425
+ z-index: 100000;
426
+ top: 0;
427
+ left: 0;
428
+ right: 0;
429
+ bottom: 0;
430
+ background: rgba(0, 0, 0, 0.8);
431
+ }
432
+ .css-editor-snippet-browser .snippet-browser-dialog > div {
433
+ position: fixed;
434
+ z-index: 100001;
435
+ background: #fff;
436
+ box-sizing: border-box;
437
+ }
438
+ .css-editor-snippet-browser .snippet-browser-dialog .toolbar {
439
+ top: 40px;
440
+ left: 40px;
441
+ right: 40px;
442
+ height: 50px;
443
+ background: #FCFCFC;
444
+ border-bottom: 1px solid #dddddd;
445
+ overflow: hidden;
446
+ }
447
+ .css-editor-snippet-browser .snippet-browser-dialog .toolbar h1 {
448
+ padding: 0 16px;
449
+ font-size: 22px;
450
+ line-height: 50px;
451
+ margin: 0;
452
+ color: #444;
453
+ }
454
+ .css-editor-snippet-browser .snippet-browser-dialog .toolbar .close {
455
+ cursor: pointer;
456
+ color: #777;
457
+ background-color: transparent;
458
+ height: 50px;
459
+ width: 50px;
460
+ padding: 15px 0 0 0;
461
+ position: absolute;
462
+ text-align: center;
463
+ border: 0;
464
+ border-left: 1px solid #ddd;
465
+ top: 0;
466
+ right: 0;
467
+ text-decoration: none;
468
+ box-sizing: border-box;
469
+ }
470
+ .css-editor-snippet-browser .snippet-browser-dialog .toolbar .close:hover {
471
+ background: #dddddd;
472
+ }
473
+ .css-editor-snippet-browser .snippet-browser-dialog .toolbar .close .icon:before {
474
+ content: '\f158';
475
+ font: normal 20px/1 'dashicons';
476
+ vertical-align: middle;
477
+ -webkit-font-smoothing: antialiased;
478
+ -moz-osx-font-smoothing: grayscale;
479
+ color: #666;
480
+ }
481
+ .css-editor-snippet-browser .snippet-browser-dialog .sidebar {
482
+ top: 90px;
483
+ left: 40px;
484
+ bottom: 90px;
485
+ width: 300px;
486
+ background: #f3f3f3;
487
+ border-right: 1px solid #dddddd;
488
+ padding: 16px;
489
+ overflow: auto;
490
+ }
491
+ .css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippet-search {
492
+ width: 100%;
493
+ margin-bottom: 20px;
494
+ padding: 8px;
495
+ }
496
+ .css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippets {
497
+ margin: 0;
498
+ }
499
+ .css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippets .snippet {
500
+ cursor: pointer;
501
+ font-size: 1.1em;
502
+ line-height: 1.35em;
503
+ margin-bottom: 20px;
504
+ }
505
+ .css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippets .snippet.active {
506
+ font-weight: bold;
507
+ }
508
+ .css-editor-snippet-browser .snippet-browser-dialog .main {
509
+ top: 90px;
510
+ left: 340px;
511
+ right: 40px;
512
+ bottom: 90px;
513
+ background: #fff;
514
+ overflow: auto;
515
+ }
516
+ .css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view {
517
+ padding: 20px;
518
+ }
519
+ .css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view .snippet-title {
520
+ margin: 0 0 0.75em 0;
521
+ padding: 0;
522
+ }
523
+ .css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view .snippet-description {
524
+ font-size: 1.1em;
525
+ color: #666;
526
+ margin-bottom: 2em;
527
+ }
528
+ .css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view .snippet-code {
529
+ padding: 20px;
530
+ border: 1px solid #d0d0d0;
531
+ background: #f8f8f8;
532
+ }
533
+ .css-editor-snippet-browser .snippet-browser-dialog .buttons {
534
+ bottom: 40px;
535
+ left: 40px;
536
+ right: 40px;
537
+ height: 50px;
538
+ background: #FCFCFC;
539
+ border-top: 1px solid #dddddd;
540
+ text-align: right;
541
+ padding: 10px 20px;
542
+ overflow: hidden;
543
+ }
544
+ .socss-field-measurement {
545
+ position: relative;
546
+ }
547
+ .socss-field-measurement input.socss-field-input {
548
+ min-height: 1.5em;
549
+ padding-right: 50px;
550
+ width: 120px !important;
551
+ box-sizing: border-box;
552
+ }
553
+ .socss-field-measurement .dashicons-arrow-down {
554
+ position: absolute;
555
+ top: 4px;
556
+ left: 97px;
557
+ cursor: pointer;
558
+ }
559
+ .socss-field-measurement .dropdown {
560
+ display: none;
561
+ background: #F5F5F5;
562
+ border: 1px solid #c0c0c0;
563
+ position: absolute;
564
+ top: 27px;
565
+ left: 71px;
566
+ width: 50px;
567
+ z-index: 2;
568
+ margin: 0;
569
+ box-sizing: border-box;
570
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
571
+ }
572
+ .socss-field-measurement .dropdown li {
573
+ padding: 5px 0;
574
+ text-align: center;
575
+ line-height: 1.1em;
576
+ font-size: 11px;
577
+ margin: 0;
578
+ }
579
+ .socss-field-measurement .dropdown li:hover,
580
+ .socss-field-measurement .dropdown li.active {
581
+ background: #e8e8e8;
582
+ cursor: pointer;
583
+ }
584
+ .socss-field-measurement .units {
585
+ position: absolute;
586
+ top: 5px;
587
+ left: 12px;
588
+ color: #bbb;
589
+ pointer-events: none;
590
+ }
591
+ .socss-diw {
592
+ position: absolute;
593
+ top: 0px;
594
+ left: 124px;
595
+ }
596
+ .socss-diw .inc-button,
597
+ .socss-diw .dec-button {
598
+ cursor: pointer;
599
+ box-sizing: border-box;
600
+ float: left;
601
+ padding: 8px;
602
+ user-select: none;
603
+ text-align: center;
604
+ margin: 0;
605
+ width: 27px;
606
+ height: 27px;
607
+ font-size: 10px;
608
+ }
609
+ .socss-diw .inc-button {
610
+ border-left: 0;
611
+ }
612
+ .socss-button {
613
+ cursor: pointer;
614
+ line-height: 1em;
615
+ display: inline-block;
616
+ border: 1px solid #c0c0c0;
617
+ background: #f7f7f7;
618
+ text-decoration: none;
619
+ padding: 6px;
620
+ font-weight: bold;
621
+ color: #555;
622
+ font-size: 0.95em;
623
+ margin-left: 5px;
624
+ -webkit-user-select: none;
625
+ -moz-user-select: none;
626
+ -ms-user-select: none;
627
+ -o-user-select: none;
628
+ user-select: none;
629
+ }
630
+ .socss-button:hover {
631
+ border-color: #b0b0b0;
632
+ background: #fff;
633
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
634
+ }
635
+ .socss-button:hover .fa {
636
+ color: #333;
637
+ }
638
+ .socss-button .fa {
639
+ color: #555;
640
+ }
641
+ .CodeMirror-lint-tooltip,
642
+ .CodeMirror-hints {
643
+ /* This is above the editor in full-screen mode */
644
+ z-index: 100002;
645
+ }
js/css.js CHANGED
@@ -399,6 +399,10 @@ process.off = noop;
399
  process.removeListener = noop;
400
  process.removeAllListeners = noop;
401
  process.emit = noop;
 
 
 
 
402
 
403
  process.binding = function (name) {
404
  throw new Error('process.binding is not supported');
@@ -414,126 +418,431 @@ process.umask = function() { return 0; };
414
  //This is for browserify to build the required CSS module into something we can use in the browser.
415
  window.css = require('css');
416
 
417
- },{"css":5}],5:[function(require,module,exports){
418
- exports.parse = require('./lib/parse');
419
- exports.stringify = require('./lib/stringify');
420
-
421
- },{"./lib/parse":6,"./lib/stringify":10}],6:[function(require,module,exports){
422
- // http://www.w3.org/TR/CSS21/grammar.html
423
- // https://github.com/visionmedia/css-parse/pull/49#issuecomment-30088027
424
- var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g
425
-
426
- module.exports = function(css, options){
427
- options = options || {};
428
-
429
- /**
430
- * Positional.
431
- */
432
-
433
- var lineno = 1;
434
- var column = 1;
435
 
436
- /**
437
- * Update lineno and column based on `str`.
438
- */
439
 
440
- function updatePosition(str) {
441
- var lines = str.match(/\n/g);
442
- if (lines) lineno += lines.length;
443
- var i = str.lastIndexOf('\n');
444
- column = ~i ? str.length - i : column + str.length;
445
- }
 
 
 
 
 
 
 
 
 
 
 
446
 
447
- /**
448
- * Mark position and patch `node.position`.
449
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
 
451
- function position() {
452
- var start = { line: lineno, column: column };
453
- return function(node){
454
- node.position = new Position(start);
455
- whitespace();
456
- return node;
457
- };
458
- }
459
 
460
- /**
461
- * Store position information for a node
462
- */
 
 
 
 
 
 
 
 
 
 
463
 
464
- function Position(start) {
465
- this.start = start;
466
- this.end = { line: lineno, column: column };
467
- this.source = options.source;
468
- }
469
 
470
- /**
471
- * Non-enumerable source string
472
- */
 
 
 
 
 
 
473
 
474
- Position.prototype.content = css;
 
 
 
475
 
476
- /**
477
- * Error `msg`.
478
- */
 
 
 
 
 
479
 
480
- var errorsList = [];
 
481
 
482
- function error(msg) {
483
- var err = new Error(options.source + ':' + lineno + ':' + column + ': ' + msg);
484
- err.reason = msg;
485
- err.filename = options.source;
486
- err.line = lineno;
487
- err.column = column;
488
- err.source = css;
489
 
490
- if (options.silent) {
491
- errorsList.push(err);
492
- } else {
493
- throw err;
494
- }
495
- }
496
 
497
- /**
498
- * Parse stylesheet.
499
- */
 
 
 
 
 
500
 
501
- function stylesheet() {
502
- var rulesList = rules();
 
 
 
 
 
503
 
504
- return {
505
- type: 'stylesheet',
506
- stylesheet: {
507
- rules: rulesList,
508
- parsingErrors: errorsList
509
- }
510
  };
511
- }
512
 
513
- /**
514
- * Opening brace.
515
- */
 
516
 
517
- function open() {
518
- return match(/^{\s*/);
519
- }
520
 
521
- /**
522
- * Closing brace.
523
- */
 
 
 
 
 
 
 
 
 
 
 
524
 
525
- function close() {
526
- return match(/^}/);
527
- }
 
 
 
 
528
 
529
- /**
530
- * Parse ruleset.
531
- */
 
 
 
 
532
 
533
- function rules() {
534
- var node;
535
- var rules = [];
536
- whitespace();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
537
  comments(rules);
538
  while (css.length && css.charAt(0) != '}' && (node = atrule() || rule())) {
539
  if (node !== false) {
@@ -1022,7 +1331,7 @@ function addParent(obj, parent) {
1022
  return obj;
1023
  }
1024
 
1025
- },{}],7:[function(require,module,exports){
1026
 
1027
  /**
1028
  * Expose `Compiler`.
@@ -1074,7 +1383,7 @@ Compiler.prototype.mapVisit = function(nodes, delim){
1074
  return buf;
1075
  };
1076
 
1077
- },{}],8:[function(require,module,exports){
1078
 
1079
  /**
1080
  * Module dependencies.
@@ -1275,7 +1584,7 @@ Compiler.prototype.declaration = function(node){
1275
  };
1276
 
1277
 
1278
- },{"./compiler":7,"inherits":12}],9:[function(require,module,exports){
1279
 
1280
  /**
1281
  * Module dependencies.
@@ -1531,7 +1840,7 @@ Compiler.prototype.indent = function(level) {
1531
  return Array(this.level).join(this.indentation || ' ');
1532
  };
1533
 
1534
- },{"./compiler":7,"inherits":12}],10:[function(require,module,exports){
1535
 
1536
  /**
1537
  * Module dependencies.
@@ -1580,7 +1889,7 @@ module.exports = function(node, options){
1580
  return code;
1581
  };
1582
 
1583
- },{"./compress":8,"./identity":9,"./source-map-support":11}],11:[function(require,module,exports){
1584
 
1585
  /**
1586
  * Module dependencies.
@@ -1708,7 +2017,7 @@ exports.comment = function(node) {
1708
  return this._comment(node);
1709
  };
1710
 
1711
- },{"fs":1,"path":2,"source-map":16,"source-map-resolve":15,"urix":27}],12:[function(require,module,exports){
1712
  if (typeof Object.create === 'function') {
1713
  // implementation from standard node.js 'util' module
1714
  module.exports = function inherits(ctor, superCtor) {
@@ -1733,7 +2042,7 @@ if (typeof Object.create === 'function') {
1733
  }
1734
  }
1735
 
1736
- },{}],13:[function(require,module,exports){
1737
  // Copyright 2014 Simon Lydell
1738
  // X11 (“MIT”) Licensed. (See LICENSE.)
1739
 
@@ -1782,80 +2091,21 @@ void (function(root, factory) {
1782
 
1783
  }));
1784
 
1785
- },{}],14:[function(require,module,exports){
1786
  // Copyright 2014 Simon Lydell
1787
  // X11 (“MIT”) Licensed. (See LICENSE.)
1788
 
 
 
 
 
1789
  void (function(root, factory) {
1790
  if (typeof define === "function" && define.amd) {
1791
- define(factory)
1792
  } else if (typeof exports === "object") {
1793
- module.exports = factory()
1794
- } else {
1795
- root.sourceMappingURL = factory()
1796
- }
1797
- }(this, function() {
1798
-
1799
- var innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/
1800
-
1801
- var regex = RegExp(
1802
- "(?:" +
1803
- "/\\*" +
1804
- "(?:\\s*\r?\n(?://)?)?" +
1805
- "(?:" + innerRegex.source + ")" +
1806
- "\\s*" +
1807
- "\\*/" +
1808
- "|" +
1809
- "//(?:" + innerRegex.source + ")" +
1810
- ")" +
1811
- "\\s*$"
1812
- )
1813
-
1814
- return {
1815
-
1816
- regex: regex,
1817
- _innerRegex: innerRegex,
1818
-
1819
- getFrom: function(code) {
1820
- var match = code.match(regex)
1821
- return (match ? match[1] || match[2] || "" : null)
1822
- },
1823
-
1824
- existsIn: function(code) {
1825
- return regex.test(code)
1826
- },
1827
-
1828
- removeFrom: function(code) {
1829
- return code.replace(regex, "")
1830
- },
1831
-
1832
- insertBefore: function(code, string) {
1833
- var match = code.match(regex)
1834
- if (match) {
1835
- return code.slice(0, match.index) + string + code.slice(match.index)
1836
- } else {
1837
- return code + string
1838
- }
1839
- }
1840
- }
1841
-
1842
- }));
1843
-
1844
- },{}],15:[function(require,module,exports){
1845
- // Copyright 2014 Simon Lydell
1846
- // X11 (“MIT”) Licensed. (See LICENSE.)
1847
-
1848
- // Note: source-map-resolve.js is generated from source-map-resolve-node.js and
1849
- // source-map-resolve-template.js. Only edit the two latter files, _not_
1850
- // source-map-resolve.js!
1851
-
1852
- void (function(root, factory) {
1853
- if (typeof define === "function" && define.amd) {
1854
- define(["source-map-url", "resolve-url"], factory)
1855
- } else if (typeof exports === "object") {
1856
- var sourceMappingURL = require("source-map-url")
1857
- var resolveUrl = require("resolve-url")
1858
- module.exports = factory(sourceMappingURL, resolveUrl)
1859
  } else {
1860
  root.sourceMapResolve = factory(root.sourceMappingURL, root.resolveUrl)
1861
  }
@@ -2066,7 +2316,66 @@ void (function(root, factory) {
2066
 
2067
  }));
2068
 
2069
- },{"resolve-url":13,"source-map-url":14}],16:[function(require,module,exports){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2070
  /*
2071
  * Copyright 2009-2011 Mozilla Foundation and contributors
2072
  * Licensed under the New BSD license. See LICENSE.txt or:
@@ -2076,7 +2385,7 @@ exports.SourceMapGenerator = require('./source-map/source-map-generator').Source
2076
  exports.SourceMapConsumer = require('./source-map/source-map-consumer').SourceMapConsumer;
2077
  exports.SourceNode = require('./source-map/source-node').SourceNode;
2078
 
2079
- },{"./source-map/source-map-consumer":22,"./source-map/source-map-generator":23,"./source-map/source-node":24}],17:[function(require,module,exports){
2080
  /* -*- Mode: js; js-indent-level: 2; -*- */
2081
  /*
2082
  * Copyright 2011 Mozilla Foundation and contributors
@@ -2175,7 +2484,7 @@ define(function (require, exports, module) {
2175
 
2176
  });
2177
 
2178
- },{"./util":25,"amdefine":26}],18:[function(require,module,exports){
2179
  /* -*- Mode: js; js-indent-level: 2; -*- */
2180
  /*
2181
  * Copyright 2011 Mozilla Foundation and contributors
@@ -2319,7 +2628,7 @@ define(function (require, exports, module) {
2319
 
2320
  });
2321
 
2322
- },{"./base64":19,"amdefine":26}],19:[function(require,module,exports){
2323
  /* -*- Mode: js; js-indent-level: 2; -*- */
2324
  /*
2325
  * Copyright 2011 Mozilla Foundation and contributors
@@ -2363,7 +2672,7 @@ define(function (require, exports, module) {
2363
 
2364
  });
2365
 
2366
- },{"amdefine":26}],20:[function(require,module,exports){
2367
  /* -*- Mode: js; js-indent-level: 2; -*- */
2368
  /*
2369
  * Copyright 2011 Mozilla Foundation and contributors
@@ -2445,7 +2754,7 @@ define(function (require, exports, module) {
2445
 
2446
  });
2447
 
2448
- },{"amdefine":26}],21:[function(require,module,exports){
2449
  /* -*- Mode: js; js-indent-level: 2; -*- */
2450
  /*
2451
  * Copyright 2014 Mozilla Foundation and contributors
@@ -2533,7 +2842,7 @@ define(function (require, exports, module) {
2533
 
2534
  });
2535
 
2536
- },{"./util":25,"amdefine":26}],22:[function(require,module,exports){
2537
  /* -*- Mode: js; js-indent-level: 2; -*- */
2538
  /*
2539
  * Copyright 2011 Mozilla Foundation and contributors
@@ -3110,7 +3419,7 @@ define(function (require, exports, module) {
3110
 
3111
  });
3112
 
3113
- },{"./array-set":17,"./base64-vlq":18,"./binary-search":20,"./util":25,"amdefine":26}],23:[function(require,module,exports){
3114
  /* -*- Mode: js; js-indent-level: 2; -*- */
3115
  /*
3116
  * Copyright 2011 Mozilla Foundation and contributors
@@ -3512,7 +3821,7 @@ define(function (require, exports, module) {
3512
 
3513
  });
3514
 
3515
- },{"./array-set":17,"./base64-vlq":18,"./mapping-list":21,"./util":25,"amdefine":26}],24:[function(require,module,exports){
3516
  /* -*- Mode: js; js-indent-level: 2; -*- */
3517
  /*
3518
  * Copyright 2011 Mozilla Foundation and contributors
@@ -3928,7 +4237,7 @@ define(function (require, exports, module) {
3928
 
3929
  });
3930
 
3931
- },{"./source-map-generator":23,"./util":25,"amdefine":26}],25:[function(require,module,exports){
3932
  /* -*- Mode: js; js-indent-level: 2; -*- */
3933
  /*
3934
  * Copyright 2011 Mozilla Foundation and contributors
@@ -4249,312 +4558,7 @@ define(function (require, exports, module) {
4249
 
4250
  });
4251
 
4252
- },{"amdefine":26}],26:[function(require,module,exports){
4253
- (function (process,__filename){
4254
- /** vim: et:ts=4:sw=4:sts=4
4255
- * @license amdefine 1.0.1 Copyright (c) 2011-2016, The Dojo Foundation All Rights Reserved.
4256
- * Available via the MIT or new BSD license.
4257
- * see: http://github.com/jrburke/amdefine for details
4258
- */
4259
-
4260
- /*jslint node: true */
4261
- /*global module, process */
4262
- 'use strict';
4263
-
4264
- /**
4265
- * Creates a define for node.
4266
- * @param {Object} module the "module" object that is defined by Node for the
4267
- * current module.
4268
- * @param {Function} [requireFn]. Node's require function for the current module.
4269
- * It only needs to be passed in Node versions before 0.5, when module.require
4270
- * did not exist.
4271
- * @returns {Function} a define function that is usable for the current node
4272
- * module.
4273
- */
4274
- function amdefine(module, requireFn) {
4275
- 'use strict';
4276
- var defineCache = {},
4277
- loaderCache = {},
4278
- alreadyCalled = false,
4279
- path = require('path'),
4280
- makeRequire, stringRequire;
4281
-
4282
- /**
4283
- * Trims the . and .. from an array of path segments.
4284
- * It will keep a leading path segment if a .. will become
4285
- * the first path segment, to help with module name lookups,
4286
- * which act like paths, but can be remapped. But the end result,
4287
- * all paths that use this function should look normalized.
4288
- * NOTE: this method MODIFIES the input array.
4289
- * @param {Array} ary the array of path segments.
4290
- */
4291
- function trimDots(ary) {
4292
- var i, part;
4293
- for (i = 0; ary[i]; i+= 1) {
4294
- part = ary[i];
4295
- if (part === '.') {
4296
- ary.splice(i, 1);
4297
- i -= 1;
4298
- } else if (part === '..') {
4299
- if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
4300
- //End of the line. Keep at least one non-dot
4301
- //path segment at the front so it can be mapped
4302
- //correctly to disk. Otherwise, there is likely
4303
- //no path mapping for a path starting with '..'.
4304
- //This can still fail, but catches the most reasonable
4305
- //uses of ..
4306
- break;
4307
- } else if (i > 0) {
4308
- ary.splice(i - 1, 2);
4309
- i -= 2;
4310
- }
4311
- }
4312
- }
4313
- }
4314
-
4315
- function normalize(name, baseName) {
4316
- var baseParts;
4317
-
4318
- //Adjust any relative paths.
4319
- if (name && name.charAt(0) === '.') {
4320
- //If have a base name, try to normalize against it,
4321
- //otherwise, assume it is a top-level require that will
4322
- //be relative to baseUrl in the end.
4323
- if (baseName) {
4324
- baseParts = baseName.split('/');
4325
- baseParts = baseParts.slice(0, baseParts.length - 1);
4326
- baseParts = baseParts.concat(name.split('/'));
4327
- trimDots(baseParts);
4328
- name = baseParts.join('/');
4329
- }
4330
- }
4331
-
4332
- return name;
4333
- }
4334
-
4335
- /**
4336
- * Create the normalize() function passed to a loader plugin's
4337
- * normalize method.
4338
- */
4339
- function makeNormalize(relName) {
4340
- return function (name) {
4341
- return normalize(name, relName);
4342
- };
4343
- }
4344
-
4345
- function makeLoad(id) {
4346
- function load(value) {
4347
- loaderCache[id] = value;
4348
- }
4349
-
4350
- load.fromText = function (id, text) {
4351
- //This one is difficult because the text can/probably uses
4352
- //define, and any relative paths and requires should be relative
4353
- //to that id was it would be found on disk. But this would require
4354
- //bootstrapping a module/require fairly deeply from node core.
4355
- //Not sure how best to go about that yet.
4356
- throw new Error('amdefine does not implement load.fromText');
4357
- };
4358
-
4359
- return load;
4360
- }
4361
-
4362
- makeRequire = function (systemRequire, exports, module, relId) {
4363
- function amdRequire(deps, callback) {
4364
- if (typeof deps === 'string') {
4365
- //Synchronous, single module require('')
4366
- return stringRequire(systemRequire, exports, module, deps, relId);
4367
- } else {
4368
- //Array of dependencies with a callback.
4369
-
4370
- //Convert the dependencies to modules.
4371
- deps = deps.map(function (depName) {
4372
- return stringRequire(systemRequire, exports, module, depName, relId);
4373
- });
4374
-
4375
- //Wait for next tick to call back the require call.
4376
- if (callback) {
4377
- process.nextTick(function () {
4378
- callback.apply(null, deps);
4379
- });
4380
- }
4381
- }
4382
- }
4383
-
4384
- amdRequire.toUrl = function (filePath) {
4385
- if (filePath.indexOf('.') === 0) {
4386
- return normalize(filePath, path.dirname(module.filename));
4387
- } else {
4388
- return filePath;
4389
- }
4390
- };
4391
-
4392
- return amdRequire;
4393
- };
4394
-
4395
- //Favor explicit value, passed in if the module wants to support Node 0.4.
4396
- requireFn = requireFn || function req() {
4397
- return module.require.apply(module, arguments);
4398
- };
4399
-
4400
- function runFactory(id, deps, factory) {
4401
- var r, e, m, result;
4402
-
4403
- if (id) {
4404
- e = loaderCache[id] = {};
4405
- m = {
4406
- id: id,
4407
- uri: __filename,
4408
- exports: e
4409
- };
4410
- r = makeRequire(requireFn, e, m, id);
4411
- } else {
4412
- //Only support one define call per file
4413
- if (alreadyCalled) {
4414
- throw new Error('amdefine with no module ID cannot be called more than once per file.');
4415
- }
4416
- alreadyCalled = true;
4417
-
4418
- //Use the real variables from node
4419
- //Use module.exports for exports, since
4420
- //the exports in here is amdefine exports.
4421
- e = module.exports;
4422
- m = module;
4423
- r = makeRequire(requireFn, e, m, module.id);
4424
- }
4425
-
4426
- //If there are dependencies, they are strings, so need
4427
- //to convert them to dependency values.
4428
- if (deps) {
4429
- deps = deps.map(function (depName) {
4430
- return r(depName);
4431
- });
4432
- }
4433
-
4434
- //Call the factory with the right dependencies.
4435
- if (typeof factory === 'function') {
4436
- result = factory.apply(m.exports, deps);
4437
- } else {
4438
- result = factory;
4439
- }
4440
-
4441
- if (result !== undefined) {
4442
- m.exports = result;
4443
- if (id) {
4444
- loaderCache[id] = m.exports;
4445
- }
4446
- }
4447
- }
4448
-
4449
- stringRequire = function (systemRequire, exports, module, id, relId) {
4450
- //Split the ID by a ! so that
4451
- var index = id.indexOf('!'),
4452
- originalId = id,
4453
- prefix, plugin;
4454
-
4455
- if (index === -1) {
4456
- id = normalize(id, relId);
4457
-
4458
- //Straight module lookup. If it is one of the special dependencies,
4459
- //deal with it, otherwise, delegate to node.
4460
- if (id === 'require') {
4461
- return makeRequire(systemRequire, exports, module, relId);
4462
- } else if (id === 'exports') {
4463
- return exports;
4464
- } else if (id === 'module') {
4465
- return module;
4466
- } else if (loaderCache.hasOwnProperty(id)) {
4467
- return loaderCache[id];
4468
- } else if (defineCache[id]) {
4469
- runFactory.apply(null, defineCache[id]);
4470
- return loaderCache[id];
4471
- } else {
4472
- if(systemRequire) {
4473
- return systemRequire(originalId);
4474
- } else {
4475
- throw new Error('No module with ID: ' + id);
4476
- }
4477
- }
4478
- } else {
4479
- //There is a plugin in play.
4480
- prefix = id.substring(0, index);
4481
- id = id.substring(index + 1, id.length);
4482
-
4483
- plugin = stringRequire(systemRequire, exports, module, prefix, relId);
4484
-
4485
- if (plugin.normalize) {
4486
- id = plugin.normalize(id, makeNormalize(relId));
4487
- } else {
4488
- //Normalize the ID normally.
4489
- id = normalize(id, relId);
4490
- }
4491
-
4492
- if (loaderCache[id]) {
4493
- return loaderCache[id];
4494
- } else {
4495
- plugin.load(id, makeRequire(systemRequire, exports, module, relId), makeLoad(id), {});
4496
-
4497
- return loaderCache[id];
4498
- }
4499
- }
4500
- };
4501
-
4502
- //Create a define function specific to the module asking for amdefine.
4503
- function define(id, deps, factory) {
4504
- if (Array.isArray(id)) {
4505
- factory = deps;
4506
- deps = id;
4507
- id = undefined;
4508
- } else if (typeof id !== 'string') {
4509
- factory = id;
4510
- id = deps = undefined;
4511
- }
4512
-
4513
- if (deps && !Array.isArray(deps)) {
4514
- factory = deps;
4515
- deps = undefined;
4516
- }
4517
-
4518
- if (!deps) {
4519
- deps = ['require', 'exports', 'module'];
4520
- }
4521
-
4522
- //Set up properties for this module. If an ID, then use
4523
- //internal cache. If no ID, then use the external variables
4524
- //for this node module.
4525
- if (id) {
4526
- //Put the module in deep freeze until there is a
4527
- //require call for it.
4528
- defineCache[id] = [id, deps, factory];
4529
- } else {
4530
- runFactory(id, deps, factory);
4531
- }
4532
- }
4533
-
4534
- //define.require, which has access to all the values in the
4535
- //cache. Useful for AMD modules that all have IDs in the file,
4536
- //but need to finally export a value to node based on one of those
4537
- //IDs.
4538
- define.require = function (id) {
4539
- if (loaderCache[id]) {
4540
- return loaderCache[id];
4541
- }
4542
-
4543
- if (defineCache[id]) {
4544
- runFactory.apply(null, defineCache[id]);
4545
- return loaderCache[id];
4546
- }
4547
- };
4548
-
4549
- define.amd = {};
4550
-
4551
- return define;
4552
- }
4553
-
4554
- module.exports = amdefine;
4555
-
4556
- }).call(this,require('_process'),"/node_modules/css/node_modules/source-map/node_modules/amdefine/amdefine.js")
4557
- },{"_process":3,"path":2}],27:[function(require,module,exports){
4558
  // Copyright 2014 Simon Lydell
4559
  // X11 (“MIT”) Licensed. (See LICENSE.)
4560
 
399
  process.removeListener = noop;
400
  process.removeAllListeners = noop;
401
  process.emit = noop;
402
+ process.prependListener = noop;
403
+ process.prependOnceListener = noop;
404
+
405
+ process.listeners = function (name) { return [] }
406
 
407
  process.binding = function (name) {
408
  throw new Error('process.binding is not supported');
418
  //This is for browserify to build the required CSS module into something we can use in the browser.
419
  window.css = require('css');
420
 
421
+ },{"css":6}],5:[function(require,module,exports){
422
+ (function (process,__filename){
423
+ /** vim: et:ts=4:sw=4:sts=4
424
+ * @license amdefine 1.0.1 Copyright (c) 2011-2016, The Dojo Foundation All Rights Reserved.
425
+ * Available via the MIT or new BSD license.
426
+ * see: http://github.com/jrburke/amdefine for details
427
+ */
 
 
 
 
 
 
 
 
 
 
 
428
 
429
+ /*jslint node: true */
430
+ /*global module, process */
431
+ 'use strict';
432
 
433
+ /**
434
+ * Creates a define for node.
435
+ * @param {Object} module the "module" object that is defined by Node for the
436
+ * current module.
437
+ * @param {Function} [requireFn]. Node's require function for the current module.
438
+ * It only needs to be passed in Node versions before 0.5, when module.require
439
+ * did not exist.
440
+ * @returns {Function} a define function that is usable for the current node
441
+ * module.
442
+ */
443
+ function amdefine(module, requireFn) {
444
+ 'use strict';
445
+ var defineCache = {},
446
+ loaderCache = {},
447
+ alreadyCalled = false,
448
+ path = require('path'),
449
+ makeRequire, stringRequire;
450
 
451
+ /**
452
+ * Trims the . and .. from an array of path segments.
453
+ * It will keep a leading path segment if a .. will become
454
+ * the first path segment, to help with module name lookups,
455
+ * which act like paths, but can be remapped. But the end result,
456
+ * all paths that use this function should look normalized.
457
+ * NOTE: this method MODIFIES the input array.
458
+ * @param {Array} ary the array of path segments.
459
+ */
460
+ function trimDots(ary) {
461
+ var i, part;
462
+ for (i = 0; ary[i]; i+= 1) {
463
+ part = ary[i];
464
+ if (part === '.') {
465
+ ary.splice(i, 1);
466
+ i -= 1;
467
+ } else if (part === '..') {
468
+ if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
469
+ //End of the line. Keep at least one non-dot
470
+ //path segment at the front so it can be mapped
471
+ //correctly to disk. Otherwise, there is likely
472
+ //no path mapping for a path starting with '..'.
473
+ //This can still fail, but catches the most reasonable
474
+ //uses of ..
475
+ break;
476
+ } else if (i > 0) {
477
+ ary.splice(i - 1, 2);
478
+ i -= 2;
479
+ }
480
+ }
481
+ }
482
+ }
483
 
484
+ function normalize(name, baseName) {
485
+ var baseParts;
 
 
 
 
 
 
486
 
487
+ //Adjust any relative paths.
488
+ if (name && name.charAt(0) === '.') {
489
+ //If have a base name, try to normalize against it,
490
+ //otherwise, assume it is a top-level require that will
491
+ //be relative to baseUrl in the end.
492
+ if (baseName) {
493
+ baseParts = baseName.split('/');
494
+ baseParts = baseParts.slice(0, baseParts.length - 1);
495
+ baseParts = baseParts.concat(name.split('/'));
496
+ trimDots(baseParts);
497
+ name = baseParts.join('/');
498
+ }
499
+ }
500
 
501
+ return name;
502
+ }
 
 
 
503
 
504
+ /**
505
+ * Create the normalize() function passed to a loader plugin's
506
+ * normalize method.
507
+ */
508
+ function makeNormalize(relName) {
509
+ return function (name) {
510
+ return normalize(name, relName);
511
+ };
512
+ }
513
 
514
+ function makeLoad(id) {
515
+ function load(value) {
516
+ loaderCache[id] = value;
517
+ }
518
 
519
+ load.fromText = function (id, text) {
520
+ //This one is difficult because the text can/probably uses
521
+ //define, and any relative paths and requires should be relative
522
+ //to that id was it would be found on disk. But this would require
523
+ //bootstrapping a module/require fairly deeply from node core.
524
+ //Not sure how best to go about that yet.
525
+ throw new Error('amdefine does not implement load.fromText');
526
+ };
527
 
528
+ return load;
529
+ }
530
 
531
+ makeRequire = function (systemRequire, exports, module, relId) {
532
+ function amdRequire(deps, callback) {
533
+ if (typeof deps === 'string') {
534
+ //Synchronous, single module require('')
535
+ return stringRequire(systemRequire, exports, module, deps, relId);
536
+ } else {
537
+ //Array of dependencies with a callback.
538
 
539
+ //Convert the dependencies to modules.
540
+ deps = deps.map(function (depName) {
541
+ return stringRequire(systemRequire, exports, module, depName, relId);
542
+ });
 
 
543
 
544
+ //Wait for next tick to call back the require call.
545
+ if (callback) {
546
+ process.nextTick(function () {
547
+ callback.apply(null, deps);
548
+ });
549
+ }
550
+ }
551
+ }
552
 
553
+ amdRequire.toUrl = function (filePath) {
554
+ if (filePath.indexOf('.') === 0) {
555
+ return normalize(filePath, path.dirname(module.filename));
556
+ } else {
557
+ return filePath;
558
+ }
559
+ };
560
 
561
+ return amdRequire;
 
 
 
 
 
562
  };
 
563
 
564
+ //Favor explicit value, passed in if the module wants to support Node 0.4.
565
+ requireFn = requireFn || function req() {
566
+ return module.require.apply(module, arguments);
567
+ };
568
 
569
+ function runFactory(id, deps, factory) {
570
+ var r, e, m, result;
 
571
 
572
+ if (id) {
573
+ e = loaderCache[id] = {};
574
+ m = {
575
+ id: id,
576
+ uri: __filename,
577
+ exports: e
578
+ };
579
+ r = makeRequire(requireFn, e, m, id);
580
+ } else {
581
+ //Only support one define call per file
582
+ if (alreadyCalled) {
583
+ throw new Error('amdefine with no module ID cannot be called more than once per file.');
584
+ }
585
+ alreadyCalled = true;
586
 
587
+ //Use the real variables from node
588
+ //Use module.exports for exports, since
589
+ //the exports in here is amdefine exports.
590
+ e = module.exports;
591
+ m = module;
592
+ r = makeRequire(requireFn, e, m, module.id);
593
+ }
594
 
595
+ //If there are dependencies, they are strings, so need
596
+ //to convert them to dependency values.
597
+ if (deps) {
598
+ deps = deps.map(function (depName) {
599
+ return r(depName);
600
+ });
601
+ }
602
 
603
+ //Call the factory with the right dependencies.
604
+ if (typeof factory === 'function') {
605
+ result = factory.apply(m.exports, deps);
606
+ } else {
607
+ result = factory;
608
+ }
609
+
610
+ if (result !== undefined) {
611
+ m.exports = result;
612
+ if (id) {
613
+ loaderCache[id] = m.exports;
614
+ }
615
+ }
616
+ }
617
+
618
+ stringRequire = function (systemRequire, exports, module, id, relId) {
619
+ //Split the ID by a ! so that
620
+ var index = id.indexOf('!'),
621
+ originalId = id,
622
+ prefix, plugin;
623
+
624
+ if (index === -1) {
625
+ id = normalize(id, relId);
626
+
627
+ //Straight module lookup. If it is one of the special dependencies,
628
+ //deal with it, otherwise, delegate to node.
629
+ if (id === 'require') {
630
+ return makeRequire(systemRequire, exports, module, relId);
631
+ } else if (id === 'exports') {
632
+ return exports;
633
+ } else if (id === 'module') {
634
+ return module;
635
+ } else if (loaderCache.hasOwnProperty(id)) {
636
+ return loaderCache[id];
637
+ } else if (defineCache[id]) {
638
+ runFactory.apply(null, defineCache[id]);
639
+ return loaderCache[id];
640
+ } else {
641
+ if(systemRequire) {
642
+ return systemRequire(originalId);
643
+ } else {
644
+ throw new Error('No module with ID: ' + id);
645
+ }
646
+ }
647
+ } else {
648
+ //There is a plugin in play.
649
+ prefix = id.substring(0, index);
650
+ id = id.substring(index + 1, id.length);
651
+
652
+ plugin = stringRequire(systemRequire, exports, module, prefix, relId);
653
+
654
+ if (plugin.normalize) {
655
+ id = plugin.normalize(id, makeNormalize(relId));
656
+ } else {
657
+ //Normalize the ID normally.
658
+ id = normalize(id, relId);
659
+ }
660
+
661
+ if (loaderCache[id]) {
662
+ return loaderCache[id];
663
+ } else {
664
+ plugin.load(id, makeRequire(systemRequire, exports, module, relId), makeLoad(id), {});
665
+
666
+ return loaderCache[id];
667
+ }
668
+ }
669
+ };
670
+
671
+ //Create a define function specific to the module asking for amdefine.
672
+ function define(id, deps, factory) {
673
+ if (Array.isArray(id)) {
674
+ factory = deps;
675
+ deps = id;
676
+ id = undefined;
677
+ } else if (typeof id !== 'string') {
678
+ factory = id;
679
+ id = deps = undefined;
680
+ }
681
+
682
+ if (deps && !Array.isArray(deps)) {
683
+ factory = deps;
684
+ deps = undefined;
685
+ }
686
+
687
+ if (!deps) {
688
+ deps = ['require', 'exports', 'module'];
689
+ }
690
+
691
+ //Set up properties for this module. If an ID, then use
692
+ //internal cache. If no ID, then use the external variables
693
+ //for this node module.
694
+ if (id) {
695
+ //Put the module in deep freeze until there is a
696
+ //require call for it.
697
+ defineCache[id] = [id, deps, factory];
698
+ } else {
699
+ runFactory(id, deps, factory);
700
+ }
701
+ }
702
+
703
+ //define.require, which has access to all the values in the
704
+ //cache. Useful for AMD modules that all have IDs in the file,
705
+ //but need to finally export a value to node based on one of those
706
+ //IDs.
707
+ define.require = function (id) {
708
+ if (loaderCache[id]) {
709
+ return loaderCache[id];
710
+ }
711
+
712
+ if (defineCache[id]) {
713
+ runFactory.apply(null, defineCache[id]);
714
+ return loaderCache[id];
715
+ }
716
+ };
717
+
718
+ define.amd = {};
719
+
720
+ return define;
721
+ }
722
+
723
+ module.exports = amdefine;
724
+
725
+ }).call(this,require('_process'),"/node_modules\\amdefine\\amdefine.js")
726
+ },{"_process":3,"path":2}],6:[function(require,module,exports){
727
+ exports.parse = require('./lib/parse');
728
+ exports.stringify = require('./lib/stringify');
729
+
730
+ },{"./lib/parse":7,"./lib/stringify":11}],7:[function(require,module,exports){
731
+ // http://www.w3.org/TR/CSS21/grammar.html
732
+ // https://github.com/visionmedia/css-parse/pull/49#issuecomment-30088027
733
+ var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g
734
+
735
+ module.exports = function(css, options){
736
+ options = options || {};
737
+
738
+ /**
739
+ * Positional.
740
+ */
741
+
742
+ var lineno = 1;
743
+ var column = 1;
744
+
745
+ /**
746
+ * Update lineno and column based on `str`.
747
+ */
748
+
749
+ function updatePosition(str) {
750
+ var lines = str.match(/\n/g);
751
+ if (lines) lineno += lines.length;
752
+ var i = str.lastIndexOf('\n');
753
+ column = ~i ? str.length - i : column + str.length;
754
+ }
755
+
756
+ /**
757
+ * Mark position and patch `node.position`.
758
+ */
759
+
760
+ function position() {
761
+ var start = { line: lineno, column: column };
762
+ return function(node){
763
+ node.position = new Position(start);
764
+ whitespace();
765
+ return node;
766
+ };
767
+ }
768
+
769
+ /**
770
+ * Store position information for a node
771
+ */
772
+
773
+ function Position(start) {
774
+ this.start = start;
775
+ this.end = { line: lineno, column: column };
776
+ this.source = options.source;
777
+ }
778
+
779
+ /**
780
+ * Non-enumerable source string
781
+ */
782
+
783
+ Position.prototype.content = css;
784
+
785
+ /**
786
+ * Error `msg`.
787
+ */
788
+
789
+ var errorsList = [];
790
+
791
+ function error(msg) {
792
+ var err = new Error(options.source + ':' + lineno + ':' + column + ': ' + msg);
793
+ err.reason = msg;
794
+ err.filename = options.source;
795
+ err.line = lineno;
796
+ err.column = column;
797
+ err.source = css;
798
+
799
+ if (options.silent) {
800
+ errorsList.push(err);
801
+ } else {
802
+ throw err;
803
+ }
804
+ }
805
+
806
+ /**
807
+ * Parse stylesheet.
808
+ */
809
+
810
+ function stylesheet() {
811
+ var rulesList = rules();
812
+
813
+ return {
814
+ type: 'stylesheet',
815
+ stylesheet: {
816
+ rules: rulesList,
817
+ parsingErrors: errorsList
818
+ }
819
+ };
820
+ }
821
+
822
+ /**
823
+ * Opening brace.
824
+ */
825
+
826
+ function open() {
827
+ return match(/^{\s*/);
828
+ }
829
+
830
+ /**
831
+ * Closing brace.
832
+ */
833
+
834
+ function close() {
835
+ return match(/^}/);
836
+ }
837
+
838
+ /**
839
+ * Parse ruleset.
840
+ */
841
+
842
+ function rules() {
843
+ var node;
844
+ var rules = [];
845
+ whitespace();
846
  comments(rules);
847
  while (css.length && css.charAt(0) != '}' && (node = atrule() || rule())) {
848
  if (node !== false) {
1331
  return obj;
1332
  }
1333
 
1334
+ },{}],8:[function(require,module,exports){
1335
 
1336
  /**
1337
  * Expose `Compiler`.
1383
  return buf;
1384
  };
1385
 
1386
+ },{}],9:[function(require,module,exports){
1387
 
1388
  /**
1389
  * Module dependencies.
1584
  };
1585
 
1586
 
1587
+ },{"./compiler":8,"inherits":13}],10:[function(require,module,exports){
1588
 
1589
  /**
1590
  * Module dependencies.
1840
  return Array(this.level).join(this.indentation || ' ');
1841
  };
1842
 
1843
+ },{"./compiler":8,"inherits":13}],11:[function(require,module,exports){
1844
 
1845
  /**
1846
  * Module dependencies.
1889
  return code;
1890
  };
1891
 
1892
+ },{"./compress":9,"./identity":10,"./source-map-support":12}],12:[function(require,module,exports){
1893
 
1894
  /**
1895
  * Module dependencies.
2017
  return this._comment(node);
2018
  };
2019
 
2020
+ },{"fs":1,"path":2,"source-map":17,"source-map-resolve":15,"urix":27}],13:[function(require,module,exports){
2021
  if (typeof Object.create === 'function') {
2022
  // implementation from standard node.js 'util' module
2023
  module.exports = function inherits(ctor, superCtor) {
2042
  }
2043
  }
2044
 
2045
+ },{}],14:[function(require,module,exports){
2046
  // Copyright 2014 Simon Lydell
2047
  // X11 (“MIT”) Licensed. (See LICENSE.)
2048
 
2091
 
2092
  }));
2093
 
2094
+ },{}],15:[function(require,module,exports){
2095
  // Copyright 2014 Simon Lydell
2096
  // X11 (“MIT”) Licensed. (See LICENSE.)
2097
 
2098
+ // Note: source-map-resolve.js is generated from source-map-resolve-node.js and
2099
+ // source-map-resolve-template.js. Only edit the two latter files, _not_
2100
+ // source-map-resolve.js!
2101
+
2102
  void (function(root, factory) {
2103
  if (typeof define === "function" && define.amd) {
2104
+ define(["source-map-url", "resolve-url"], factory)
2105
  } else if (typeof exports === "object") {
2106
+ var sourceMappingURL = require("source-map-url")
2107
+ var resolveUrl = require("resolve-url")
2108
+ module.exports = factory(sourceMappingURL, resolveUrl)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2109
  } else {
2110
  root.sourceMapResolve = factory(root.sourceMappingURL, root.resolveUrl)
2111
  }
2316
 
2317
  }));
2318
 
2319
+ },{"resolve-url":14,"source-map-url":16}],16:[function(require,module,exports){
2320
+ // Copyright 2014 Simon Lydell
2321
+ // X11 (“MIT”) Licensed. (See LICENSE.)
2322
+
2323
+ void (function(root, factory) {
2324
+ if (typeof define === "function" && define.amd) {
2325
+ define(factory)
2326
+ } else if (typeof exports === "object") {
2327
+ module.exports = factory()
2328
+ } else {
2329
+ root.sourceMappingURL = factory()
2330
+ }
2331
+ }(this, function() {
2332
+
2333
+ var innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/
2334
+
2335
+ var regex = RegExp(
2336
+ "(?:" +
2337
+ "/\\*" +
2338
+ "(?:\\s*\r?\n(?://)?)?" +
2339
+ "(?:" + innerRegex.source + ")" +
2340
+ "\\s*" +
2341
+ "\\*/" +
2342
+ "|" +
2343
+ "//(?:" + innerRegex.source + ")" +
2344
+ ")" +
2345
+ "\\s*$"
2346
+ )
2347
+
2348
+ return {
2349
+
2350
+ regex: regex,
2351
+ _innerRegex: innerRegex,
2352
+
2353
+ getFrom: function(code) {
2354
+ var match = code.match(regex)
2355
+ return (match ? match[1] || match[2] || "" : null)
2356
+ },
2357
+
2358
+ existsIn: function(code) {
2359
+ return regex.test(code)
2360
+ },
2361
+
2362
+ removeFrom: function(code) {
2363
+ return code.replace(regex, "")
2364
+ },
2365
+
2366
+ insertBefore: function(code, string) {
2367
+ var match = code.match(regex)
2368
+ if (match) {
2369
+ return code.slice(0, match.index) + string + code.slice(match.index)
2370
+ } else {
2371
+ return code + string
2372
+ }
2373
+ }
2374
+ }
2375
+
2376
+ }));
2377
+
2378
+ },{}],17:[function(require,module,exports){
2379
  /*
2380
  * Copyright 2009-2011 Mozilla Foundation and contributors
2381
  * Licensed under the New BSD license. See LICENSE.txt or:
2385
  exports.SourceMapConsumer = require('./source-map/source-map-consumer').SourceMapConsumer;
2386
  exports.SourceNode = require('./source-map/source-node').SourceNode;
2387
 
2388
+ },{"./source-map/source-map-consumer":23,"./source-map/source-map-generator":24,"./source-map/source-node":25}],18:[function(require,module,exports){
2389
  /* -*- Mode: js; js-indent-level: 2; -*- */
2390
  /*
2391
  * Copyright 2011 Mozilla Foundation and contributors
2484
 
2485
  });
2486
 
2487
+ },{"./util":26,"amdefine":5}],19:[function(require,module,exports){
2488
  /* -*- Mode: js; js-indent-level: 2; -*- */
2489
  /*
2490
  * Copyright 2011 Mozilla Foundation and contributors
2628
 
2629
  });
2630
 
2631
+ },{"./base64":20,"amdefine":5}],20:[function(require,module,exports){
2632
  /* -*- Mode: js; js-indent-level: 2; -*- */
2633
  /*
2634
  * Copyright 2011 Mozilla Foundation and contributors
2672
 
2673
  });
2674
 
2675
+ },{"amdefine":5}],21:[function(require,module,exports){
2676
  /* -*- Mode: js; js-indent-level: 2; -*- */
2677
  /*
2678
  * Copyright 2011 Mozilla Foundation and contributors
2754
 
2755
  });
2756
 
2757
+ },{"amdefine":5}],22:[function(require,module,exports){
2758
  /* -*- Mode: js; js-indent-level: 2; -*- */
2759
  /*
2760
  * Copyright 2014 Mozilla Foundation and contributors
2842
 
2843
  });
2844
 
2845
+ },{"./util":26,"amdefine":5}],23:[function(require,module,exports){
2846
  /* -*- Mode: js; js-indent-level: 2; -*- */
2847
  /*
2848
  * Copyright 2011 Mozilla Foundation and contributors
3419
 
3420
  });
3421
 
3422
+ },{"./array-set":18,"./base64-vlq":19,"./binary-search":21,"./util":26,"amdefine":5}],24:[function(require,module,exports){
3423
  /* -*- Mode: js; js-indent-level: 2; -*- */
3424
  /*
3425
  * Copyright 2011 Mozilla Foundation and contributors
3821
 
3822
  });
3823
 
3824
+ },{"./array-set":18,"./base64-vlq":19,"./mapping-list":22,"./util":26,"amdefine":5}],25:[function(require,module,exports){
3825
  /* -*- Mode: js; js-indent-level: 2; -*- */
3826
  /*
3827
  * Copyright 2011 Mozilla Foundation and contributors
4237
 
4238
  });
4239
 
4240
+ },{"./source-map-generator":24,"./util":26,"amdefine":5}],26:[function(require,module,exports){
4241
  /* -*- Mode: js; js-indent-level: 2; -*- */
4242
  /*
4243
  * Copyright 2011 Mozilla Foundation and contributors
4558
 
4559
  });
4560
 
4561
+ },{"amdefine":5}],27:[function(require,module,exports){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4562
  // Copyright 2014 Simon Lydell
4563
  // X11 (“MIT”) Licensed. (See LICENSE.)
4564
 
js/css.min.js CHANGED
@@ -1,2 +1,2 @@
1
- !function e(t,n,r){function i(s,u){if(!n[s]){if(!t[s]){var a="function"==typeof require&&require;if(!u&&a)return a(s,!0);if(o)return o(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[s]={exports:{}};t[s][0].call(l.exports,function(e){var n=t[s][1][e];return i(n||e)},l,l.exports,e,t,n,r)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;s<r.length;s++)i(r[s]);return i}({1:[function(e,t,n){},{}],2:[function(e,t,n){(function(e){function t(e,t){for(var n=0,r=e.length-1;r>=0;r--){var i=e[r];"."===i?e.splice(r,1):".."===i?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r<e.length;r++)t(e[r],r,e)&&n.push(e[r]);return n}var i=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,o=function(e){return i.exec(e).slice(1)};n.resolve=function(){for(var n="",i=!1,o=arguments.length-1;o>=-1&&!i;o--){var s=o>=0?arguments[o]:e.cwd();if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(n=s+"/"+n,i="/"===s.charAt(0))}return n=t(r(n.split("/"),function(e){return!!e}),!i).join("/"),(i?"/":"")+n||"."},n.normalize=function(e){var i=n.isAbsolute(e),o="/"===s(e,-1);return e=t(r(e.split("/"),function(e){return!!e}),!i).join("/"),e||i||(e="."),e&&o&&(e+="/"),(i?"/":"")+e},n.isAbsolute=function(e){return"/"===e.charAt(0)},n.join=function(){var e=Array.prototype.slice.call(arguments,0);return n.normalize(r(e,function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e}).join("/"))},n.relative=function(e,t){function r(e){for(var t=0;t<e.length&&""===e[t];t++);for(var n=e.length-1;n>=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=n.resolve(e).substr(1),t=n.resolve(t).substr(1);for(var i=r(e.split("/")),o=r(t.split("/")),s=Math.min(i.length,o.length),u=s,a=0;a<s;a++)if(i[a]!==o[a]){u=a;break}for(var c=[],a=u;a<i.length;a++)c.push("..");return c=c.concat(o.slice(u)),c.join("/")},n.sep="/",n.delimiter=":",n.dirname=function(e){var t=o(e),n=t[0],r=t[1];return n||r?(r&&(r=r.substr(0,r.length-1)),n+r):"."},n.basename=function(e,t){var n=o(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},n.extname=function(e){return o(e)[3]};var s="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,e("_process"))},{_process:3}],3:[function(e,t,n){function r(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function o(e){if(p===setTimeout)return setTimeout(e,0);if((p===r||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function s(e){if(f===clearTimeout)return clearTimeout(e);if((f===i||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(e);try{return f(e)}catch(t){try{return f.call(null,e)}catch(t){return f.call(this,e)}}}function u(){d&&m&&(d=!1,m.length?g=m.concat(g):v=-1,g.length&&a())}function a(){if(!d){var e=o(u);d=!0;for(var t=g.length;t;){for(m=g,g=[];++v<t;)m&&m[v].run();v=-1,t=g.length}m=null,d=!1,s(e)}}function c(e,t){this.fun=e,this.array=t}function l(){}var p,f,h=t.exports={};!function(){try{p="function"==typeof setTimeout?setTimeout:r}catch(e){p=r}try{f="function"==typeof clearTimeout?clearTimeout:i}catch(e){f=i}}();var m,g=[],d=!1,v=-1;h.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];g.push(new c(e,t)),1!==g.length||d||o(a)},c.prototype.run=function(){this.fun.apply(null,this.array)},h.title="browser",h.browser=!0,h.env={},h.argv=[],h.version="",h.versions={},h.on=l,h.addListener=l,h.once=l,h.off=l,h.removeListener=l,h.removeAllListeners=l,h.emit=l,h.binding=function(e){throw new Error("process.binding is not supported")},h.cwd=function(){return"/"},h.chdir=function(e){throw new Error("process.chdir is not supported")},h.umask=function(){return 0}},{}],4:[function(e,t,n){window.css=e("css")},{css:5}],5:[function(e,t,n){n.parse=e("./lib/parse"),n.stringify=e("./lib/stringify")},{"./lib/parse":6,"./lib/stringify":10}],6:[function(e,t,n){function r(e){return e?e.replace(/^\s+|\s+$/g,""):""}function i(e,t){var n=e&&"string"==typeof e.type,r=n?e:t;for(var o in e){var s=e[o];Array.isArray(s)?s.forEach(function(e){i(e,r)}):s&&"object"==typeof s&&i(s,r)}return n&&Object.defineProperty(e,"parent",{configurable:!0,writable:!0,enumerable:!1,value:t||null}),e}var o=/\/\*[^*]*\*+([^\/*][^*]*\*+)*\//g;t.exports=function(e,t){function n(e){var t=e.match(/\n/g);t&&(j+=t.length);var n=e.lastIndexOf("\n");T=~n?e.length-n:T+e.length}function s(){var e={line:j,column:T};return function(t){return t.position=new u(e),h(),t}}function u(e){this.start=e,this.end={line:j,column:T},this.source=t.source}function a(n){var r=new Error(t.source+":"+j+":"+T+": "+n);if(r.reason=n,r.filename=t.source,r.line=j,r.column=T,r.source=e,!t.silent)throw r;k.push(r)}function c(){return f(/^{\s*/)}function l(){return f(/^}/)}function p(){var t,n=[];for(h(),m(n);e.length&&"}"!=e.charAt(0)&&(t=L()||O());)!1!==t&&(n.push(t),m(n));return n}function f(t){var r=t.exec(e);if(r){var i=r[0];return n(i),e=e.slice(i.length),r}}function h(){f(/^\s*/)}function m(e){var t;for(e=e||[];t=g();)!1!==t&&e.push(t);return e}function g(){var t=s();if("/"==e.charAt(0)&&"*"==e.charAt(1)){for(var r=2;""!=e.charAt(r)&&("*"!=e.charAt(r)||"/"!=e.charAt(r+1));)++r;if(r+=2,""===e.charAt(r-1))return a("End of comment missing");var i=e.slice(2,r-2);return T+=2,n(i),e=e.slice(r),T+=2,t({type:"comment",comment:i})}}function d(){var e=f(/^([^{]+)/);if(e)return r(e[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*\/+/g,"").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g,function(e){return e.replace(/,/g,"‌")}).split(/\s*(?![^(]*\)),\s*/).map(function(e){return e.replace(/\u200C/g,",")})}function v(){var e=s(),t=f(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);if(t){if(t=r(t[0]),!f(/^:\s*/))return a("property missing ':'");var n=f(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/),i=e({type:"declaration",property:t.replace(o,""),value:n?r(n[0]).replace(o,""):""});return f(/^[;\s]*/),i}}function y(){var e=[];if(!c())return a("missing '{'");m(e);for(var t;t=v();)!1!==t&&(e.push(t),m(e));return l()?e:a("missing '}'")}function _(){for(var e,t=[],n=s();e=f(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/);)t.push(e[1]),f(/^,\s*/);if(t.length)return n({type:"keyframe",values:t,declarations:y()})}function C(){var e=s(),t=f(/^@([-\w]+)?keyframes\s*/);if(t){var n=t[1],t=f(/^([-\w]+)\s*/);if(!t)return a("@keyframes missing name");var r=t[1];if(!c())return a("@keyframes missing '{'");for(var i,o=m();i=_();)o.push(i),o=o.concat(m());return l()?e({type:"keyframes",name:r,vendor:n,keyframes:o}):a("@keyframes missing '}'")}}function w(){var e=s(),t=f(/^@supports *([^{]+)/);if(t){var n=r(t[1]);if(!c())return a("@supports missing '{'");var i=m().concat(p());return l()?e({type:"supports",supports:n,rules:i}):a("@supports missing '}'")}}function S(){var e=s();if(f(/^@host\s*/)){if(!c())return a("@host missing '{'");var t=m().concat(p());return l()?e({type:"host",rules:t}):a("@host missing '}'")}}function A(){var e=s(),t=f(/^@media *([^{]+)/);if(t){var n=r(t[1]);if(!c())return a("@media missing '{'");var i=m().concat(p());return l()?e({type:"media",media:n,rules:i}):a("@media missing '}'")}}function M(){var e=s(),t=f(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);if(t)return e({type:"custom-media",name:r(t[1]),media:r(t[2])})}function b(){var e=s();if(f(/^@page */)){var t=d()||[];if(!c())return a("@page missing '{'");for(var n,r=m();n=v();)r.push(n),r=r.concat(m());return l()?e({type:"page",selectors:t,declarations:r}):a("@page missing '}'")}}function R(){var e=s(),t=f(/^@([-\w]+)?document *([^{]+)/);if(t){var n=r(t[1]),i=r(t[2]);if(!c())return a("@document missing '{'");var o=m().concat(p());return l()?e({type:"document",document:i,vendor:n,rules:o}):a("@document missing '}'")}}function x(){var e=s();if(f(/^@font-face\s*/)){if(!c())return a("@font-face missing '{'");for(var t,n=m();t=v();)n.push(t),n=n.concat(m());return l()?e({type:"font-face",declarations:n}):a("@font-face missing '}'")}}function E(e){var t=new RegExp("^@"+e+"\\s*([^;]+);");return function(){var n=s(),r=f(t);if(r){var i={type:e};return i[e]=r[1].trim(),n(i)}}}function L(){if("@"==e[0])return C()||A()||M()||w()||P()||G()||N()||R()||b()||S()||x()}function O(){var e=s(),t=d();return t?(m(),e({type:"rule",selectors:t,declarations:y()})):a("selector missing")}t=t||{};var j=1,T=1;u.prototype.content=e;var k=[],P=E("import"),G=E("charset"),N=E("namespace");return i(function(){return{type:"stylesheet",stylesheet:{rules:p(),parsingErrors:k}}}())}},{}],7:[function(e,t,n){function r(e){this.options=e||{}}t.exports=r,r.prototype.emit=function(e){return e},r.prototype.visit=function(e){return this[e.type](e)},r.prototype.mapVisit=function(e,t){var n="";t=t||"";for(var r=0,i=e.length;r<i;r++)n+=this.visit(e[r]),t&&r<i-1&&(n+=this.emit(t));return n}},{}],8:[function(e,t,n){function r(e){i.call(this,e)}var i=e("./compiler"),o=e("inherits");t.exports=r,o(r,i),r.prototype.compile=function(e){return e.stylesheet.rules.map(this.visit,this).join("")},r.prototype.comment=function(e){return this.emit("",e.position)},r.prototype.import=function(e){return this.emit("@import "+e.import+";",e.position)},r.prototype.media=function(e){return this.emit("@media "+e.media,e.position)+this.emit("{")+this.mapVisit(e.rules)+this.emit("}")},r.prototype.document=function(e){var t="@"+(e.vendor||"")+"document "+e.document;return this.emit(t,e.position)+this.emit("{")+this.mapVisit(e.rules)+this.emit("}")},r.prototype.charset=function(e){return this.emit("@charset "+e.charset+";",e.position)},r.prototype.namespace=function(e){return this.emit("@namespace "+e.namespace+";",e.position)},r.prototype.supports=function(e){return this.emit("@supports "+e.supports,e.position)+this.emit("{")+this.mapVisit(e.rules)+this.emit("}")},r.prototype.keyframes=function(e){return this.emit("@"+(e.vendor||"")+"keyframes "+e.name,e.position)+this.emit("{")+this.mapVisit(e.keyframes)+this.emit("}")},r.prototype.keyframe=function(e){var t=e.declarations;return this.emit(e.values.join(","),e.position)+this.emit("{")+this.mapVisit(t)+this.emit("}")},r.prototype.page=function(e){var t=e.selectors.length?e.selectors.join(", "):"";return this.emit("@page "+t,e.position)+this.emit("{")+this.mapVisit(e.declarations)+this.emit("}")},r.prototype["font-face"]=function(e){return this.emit("@font-face",e.position)+this.emit("{")+this.mapVisit(e.declarations)+this.emit("}")},r.prototype.host=function(e){return this.emit("@host",e.position)+this.emit("{")+this.mapVisit(e.rules)+this.emit("}")},r.prototype["custom-media"]=function(e){return this.emit("@custom-media "+e.name+" "+e.media+";",e.position)},r.prototype.rule=function(e){var t=e.declarations;return t.length?this.emit(e.selectors.join(","),e.position)+this.emit("{")+this.mapVisit(t)+this.emit("}"):""},r.prototype.declaration=function(e){return this.emit(e.property+":"+e.value,e.position)+this.emit(";")}},{"./compiler":7,inherits:12}],9:[function(e,t,n){function r(e){e=e||{},i.call(this,e),this.indentation=e.indent}var i=e("./compiler"),o=e("inherits");t.exports=r,o(r,i),r.prototype.compile=function(e){return this.stylesheet(e)},r.prototype.stylesheet=function(e){return this.mapVisit(e.stylesheet.rules,"\n\n")},r.prototype.comment=function(e){return this.emit(this.indent()+"/*"+e.comment+"*/",e.position)},r.prototype.import=function(e){return this.emit("@import "+e.import+";",e.position)},r.prototype.media=function(e){return this.emit("@media "+e.media,e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},r.prototype.document=function(e){var t="@"+(e.vendor||"")+"document "+e.document;return this.emit(t,e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},r.prototype.charset=function(e){return this.emit("@charset "+e.charset+";",e.position)},r.prototype.namespace=function(e){return this.emit("@namespace "+e.namespace+";",e.position)},r.prototype.supports=function(e){return this.emit("@supports "+e.supports,e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},r.prototype.keyframes=function(e){return this.emit("@"+(e.vendor||"")+"keyframes "+e.name,e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.keyframes,"\n")+this.emit(this.indent(-1)+"}")},r.prototype.keyframe=function(e){var t=e.declarations;return this.emit(this.indent())+this.emit(e.values.join(", "),e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(t,"\n")+this.emit(this.indent(-1)+"\n"+this.indent()+"}\n")},r.prototype.page=function(e){var t=e.selectors.length?e.selectors.join(", ")+" ":"";return this.emit("@page "+t,e.position)+this.emit("{\n")+this.emit(this.indent(1))+this.mapVisit(e.declarations,"\n")+this.emit(this.indent(-1))+this.emit("\n}")},r.prototype["font-face"]=function(e){return this.emit("@font-face ",e.position)+this.emit("{\n")+this.emit(this.indent(1))+this.mapVisit(e.declarations,"\n")+this.emit(this.indent(-1))+this.emit("\n}")},r.prototype.host=function(e){return this.emit("@host",e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},r.prototype["custom-media"]=function(e){return this.emit("@custom-media "+e.name+" "+e.media+";",e.position)},r.prototype.rule=function(e){var t=this.indent(),n=e.declarations;return n.length?this.emit(e.selectors.map(function(e){return t+e}).join(",\n"),e.position)+this.emit(" {\n")+this.emit(this.indent(1))+this.mapVisit(n,"\n")+this.emit(this.indent(-1))+this.emit("\n"+this.indent()+"}"):""},r.prototype.declaration=function(e){return this.emit(this.indent())+this.emit(e.property+": "+e.value,e.position)+this.emit(";")},r.prototype.indent=function(e){return this.level=this.level||1,null!=e?(this.level+=e,""):Array(this.level).join(this.indentation||" ")}},{"./compiler":7,inherits:12}],10:[function(e,t,n){var r=e("./compress"),i=e("./identity");t.exports=function(t,n){n=n||{};var o=n.compress?new r(n):new i(n);if(n.sourcemap){e("./source-map-support")(o);var s=o.compile(t);o.applySourceMaps();return{code:s,map:"generator"===n.sourcemap?o.map:o.map.toJSON()}}var s=o.compile(t);return s}},{"./compress":8,"./identity":9,"./source-map-support":11}],11:[function(e,t,n){function r(e){e._comment=e.comment,e.map=new i,e.position={line:1,column:1},e.files={};for(var t in n)e[t]=n[t]}var i=e("source-map").SourceMapGenerator,o=e("source-map").SourceMapConsumer,s=e("source-map-resolve"),u=e("urix"),a=e("fs"),c=e("path");t.exports=r,n.updatePosition=function(e){var t=e.match(/\n/g);t&&(this.position.line+=t.length);var n=e.lastIndexOf("\n");this.position.column=~n?e.length-n:this.position.column+e.length},n.emit=function(e,t){if(t){var n=u(t.source||"source.css");this.map.addMapping({source:n,generated:{line:this.position.line,column:Math.max(this.position.column-1,0)},original:{line:t.start.line,column:t.start.column-1}}),this.addFile(n,t)}return this.updatePosition(e),e},n.addFile=function(e,t){"string"==typeof t.content&&(Object.prototype.hasOwnProperty.call(this.files,e)||(this.files[e]=t.content))},n.applySourceMaps=function(){Object.keys(this.files).forEach(function(e){var t=this.files[e];if(this.map.setSourceContent(e,t),!1!==this.options.inputSourcemaps){var n=s.resolveSync(t,e,a.readFileSync);if(n){var r=new o(n.map),i=n.sourcesRelativeTo;this.map.applySourceMap(r,e,u(c.dirname(i)))}}},this)},n.comment=function(e){return/^# sourceMappingURL=/.test(e.comment)?this.emit("",e.position):this._comment(e)}},{fs:1,path:2,"source-map":16,"source-map-resolve":15,urix:27}],12:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],13:[function(e,t,n){!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof n?t.exports=r():e.resolveUrl=r()}(this,function(){function e(){var e=arguments.length;if(0===e)throw new Error("resolveUrl requires at least one argument; got none.");var t=document.createElement("base");if(t.href=arguments[0],1===e)return t.href;var n=document.getElementsByTagName("head")[0];n.insertBefore(t,n.firstChild);for(var r,i=document.createElement("a"),o=1;o<e;o++)i.href=arguments[o],r=i.href,t.href=r;return n.removeChild(t),r}return e})},{}],14:[function(e,t,n){!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof n?t.exports=r():e.sourceMappingURL=r()}(this,function(){var e=/[#@] sourceMappingURL=([^\s'"]*)/,t=RegExp("(?:/\\*(?:\\s*\r?\n(?://)?)?(?:"+e.source+")\\s*\\*/|//(?:"+e.source+"))\\s*$");return{regex:t,_innerRegex:e,getFrom:function(e){var n=e.match(t);return n?n[1]||n[2]||"":null},existsIn:function(e){return t.test(e)},removeFrom:function(e){return e.replace(t,"")},insertBefore:function(e,n){var r=e.match(t);return r?e.slice(0,r.index)+n+e.slice(r.index):e+n}}})},{}],15:[function(e,t,n){!function(r,i){if("function"==typeof define&&define.amd)define(["source-map-url","resolve-url"],i);else if("object"==typeof n){var o=e("source-map-url"),s=e("resolve-url");t.exports=i(o,s)}else r.sourceMapResolve=i(r.sourceMappingURL,r.resolveUrl)}(this,function(e,t){function n(e,t,n){setImmediate(function(){e(t,n)})}function r(e){return JSON.parse(e.replace(/^\)\]\}'/,""))}function i(e,t,i,o){var u;try{u=s(e,t)}catch(e){return n(o,e)}if(!u||u.map)return n(o,null,u);i(u.url,function(e,t){if(e)return o(e);try{u.map=r(String(t))}catch(e){return o(e)}o(null,u)})}function o(e,t,n){var i=s(e,t);return!i||i.map?i:(i.map=r(String(n(i.url))),i)}function s(n,i){var o=e.getFrom(n);if(!o)return null;var s=o.match(f);if(s){var u=s[1],a=s[2],c=s[3];if(!h.test(u))throw new Error("Unuseful data uri mime type: "+(u||"text/plain"));return{sourceMappingURL:o,url:null,sourcesRelativeTo:i,map:r(";base64"===a?atob(c):decodeURIComponent(c))}}var l=t(i,o);return{sourceMappingURL:o,url:l,sourcesRelativeTo:l,map:null}}function u(e,t,r,i,o){"function"==typeof i&&(o=i,i={});var s=e.sources.length,u=!1,a={sourcesResolved:[],sourcesContent:[]},l=function(e){if(!u){if(e)return u=!0,o(e);s--,0===s&&o(null,a)}};c(e,t,i,function(e,t,i){a.sourcesResolved[i]=e,"string"==typeof t?(a.sourcesContent[i]=t,n(l,null)):r(e,function(e,t){a.sourcesContent[i]=String(t),l(e)})})}function a(e,t,n,r){var i={sourcesResolved:[],sourcesContent:[]};return c(e,t,r,function(e,t,r){i.sourcesResolved[r]=e,null!==n&&(i.sourcesContent[r]="string"==typeof t?t:String(n(e)))}),i}function c(e,n,r,i){r=r||{};for(var o,s,u=0,a=e.sources.length;u<a;u++)o=e.sourceRoot&&!r.ignoreSourceRoot?t(n,e.sourceRoot.replace(m,"/"),e.sources[u]):t(n,e.sources[u]),s=(e.sourcesContent||[])[u],i(o,s,u)}function l(e,t,n,r,o){"function"==typeof r&&(o=r,r={}),i(e,t,n,function(e,t){return e?o(e):t?void u(t.map,t.sourcesRelativeTo,n,r,function(e,n){if(e)return o(e);t.sourcesResolved=n.sourcesResolved,t.sourcesContent=n.sourcesContent,o(null,t)}):o(null,null)})}function p(e,t,n,r){var i=o(e,t,n);if(!i)return null;var s=a(i.map,i.sourcesRelativeTo,n,r);return i.sourcesResolved=s.sourcesResolved,i.sourcesContent=s.sourcesContent,i}var f=/^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/,h=/^(?:application|text)\/json$/,m=/\/?$/;return{resolveSourceMap:i,resolveSourceMapSync:o,resolveSources:u,resolveSourcesSync:a,resolve:l,resolveSync:p}})},{"resolve-url":13,"source-map-url":14}],16:[function(e,t,n){n.SourceMapGenerator=e("./source-map/source-map-generator").SourceMapGenerator,n.SourceMapConsumer=e("./source-map/source-map-consumer").SourceMapConsumer,n.SourceNode=e("./source-map/source-node").SourceNode},{"./source-map/source-map-consumer":22,"./source-map/source-map-generator":23,"./source-map/source-node":24}],17:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(){this._array=[],this._set={}}var i=e("./util");r.fromArray=function(e,t){for(var n=new r,i=0,o=e.length;i<o;i++)n.add(e[i],t);return n},r.prototype.add=function(e,t){var n=this.has(e),r=this._array.length;n&&!t||this._array.push(e),n||(this._set[i.toSetString(e)]=r)},r.prototype.has=function(e){return Object.prototype.hasOwnProperty.call(this._set,i.toSetString(e))},r.prototype.indexOf=function(e){if(this.has(e))return this._set[i.toSetString(e)];throw new Error('"'+e+'" is not in the set.')},r.prototype.at=function(e){if(e>=0&&e<this._array.length)return this._array[e];throw new Error("No element indexed by "+e)},r.prototype.toArray=function(){return this._array.slice()},t.ArraySet=r})},{"./util":25,amdefine:26}],18:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e){return e<0?1+(-e<<1):0+(e<<1)}function i(e){var t=1==(1&e),n=e>>1;return t?-n:n}var o=e("./base64");t.encode=function(e){var t,n="",i=r(e);do{t=31&i,i>>>=5,i>0&&(t|=32),n+=o.encode(t)}while(i>0);return n},t.decode=function(e,t){var n,r,s=0,u=e.length,a=0,c=0;do{if(s>=u)throw new Error("Expected more digits in base 64 VLQ value.");r=o.decode(e.charAt(s++)),n=!!(32&r),r&=31,a+=r<<c,c+=5}while(n);t.value=i(a),t.rest=e.slice(s)}})},{"./base64":19,amdefine:26}],19:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){var r={},i={};"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("").forEach(function(e,t){r[e]=t,i[t]=e}),t.encode=function(e){if(e in i)return i[e];throw new TypeError("Must be between 0 and 63: "+e)},t.decode=function(e){if(e in r)return r[e];throw new TypeError("Not a valid base 64 digit: "+e)}})},{amdefine:26}],20:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e,t,n,i,o){var s=Math.floor((t-e)/2)+e,u=o(n,i[s],!0);return 0===u?s:u>0?t-s>1?r(s,t,n,i,o):s:s-e>1?r(e,s,n,i,o):e<0?-1:e}t.search=function(e,t,n){return 0===t.length?-1:r(-1,t.length,e,t,n)}})},{amdefine:26}],21:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e,t){var n=e.generatedLine,r=t.generatedLine,i=e.generatedColumn,s=t.generatedColumn;return r>n||r==n&&s>=i||o.compareByGeneratedPositions(e,t)<=0}function i(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}var o=e("./util");i.prototype.unsortedForEach=function(e,t){this._array.forEach(e,t)},i.prototype.add=function(e){r(this._last,e)?(this._last=e,this._array.push(e)):(this._sorted=!1,this._array.push(e))},i.prototype.toArray=function(){return this._sorted||(this._array.sort(o.compareByGeneratedPositions),this._sorted=!0),this._array},t.MappingList=i})},{"./util":25,amdefine:26}],22:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e){var t=e;"string"==typeof e&&(t=JSON.parse(e.replace(/^\)\]\}'/,"")));var n=i.getArg(t,"version"),r=i.getArg(t,"sources"),o=i.getArg(t,"names",[]),u=i.getArg(t,"sourceRoot",null),a=i.getArg(t,"sourcesContent",null),c=i.getArg(t,"mappings"),l=i.getArg(t,"file",null);if(n!=this._version)throw new Error("Unsupported version: "+n);r=r.map(i.normalize),this._names=s.fromArray(o,!0),this._sources=s.fromArray(r,!0),this.sourceRoot=u,this.sourcesContent=a,this._mappings=c,this.file=l}var i=e("./util"),o=e("./binary-search"),s=e("./array-set").ArraySet,u=e("./base64-vlq");r.fromSourceMap=function(e){var t=Object.create(r.prototype);return t._names=s.fromArray(e._names.toArray(),!0),t._sources=s.fromArray(e._sources.toArray(),!0),t.sourceRoot=e._sourceRoot,t.sourcesContent=e._generateSourcesContent(t._sources.toArray(),t.sourceRoot),t.file=e._file,t.__generatedMappings=e._mappings.toArray().slice(),t.__originalMappings=e._mappings.toArray().slice().sort(i.compareByOriginalPositions),t},r.prototype._version=3,Object.defineProperty(r.prototype,"sources",{get:function(){return this._sources.toArray().map(function(e){return null!=this.sourceRoot?i.join(this.sourceRoot,e):e},this)}}),r.prototype.__generatedMappings=null,Object.defineProperty(r.prototype,"_generatedMappings",{get:function(){return this.__generatedMappings||(this.__generatedMappings=[],this.__originalMappings=[],this._parseMappings(this._mappings,this.sourceRoot)),this.__generatedMappings}}),r.prototype.__originalMappings=null,Object.defineProperty(r.prototype,"_originalMappings",{get:function(){return this.__originalMappings||(this.__generatedMappings=[],this.__originalMappings=[],this._parseMappings(this._mappings,this.sourceRoot)),this.__originalMappings}}),r.prototype._nextCharIsMappingSeparator=function(e){var t=e.charAt(0);return";"===t||","===t},r.prototype._parseMappings=function(e,t){for(var n,r=1,o=0,s=0,a=0,c=0,l=0,p=e,f={};p.length>0;)if(";"===p.charAt(0))r++,p=p.slice(1),o=0;else if(","===p.charAt(0))p=p.slice(1);else{if(n={},n.generatedLine=r,u.decode(p,f),n.generatedColumn=o+f.value,o=n.generatedColumn,p=f.rest,p.length>0&&!this._nextCharIsMappingSeparator(p)){if(u.decode(p,f),n.source=this._sources.at(c+f.value),c+=f.value,p=f.rest,0===p.length||this._nextCharIsMappingSeparator(p))throw new Error("Found a source, but no line and column");if(u.decode(p,f),n.originalLine=s+f.value,s=n.originalLine,n.originalLine+=1,p=f.rest,0===p.length||this._nextCharIsMappingSeparator(p))throw new Error("Found a source and line, but no column");u.decode(p,f),n.originalColumn=a+f.value,a=n.originalColumn,p=f.rest,p.length>0&&!this._nextCharIsMappingSeparator(p)&&(u.decode(p,f),n.name=this._names.at(l+f.value),l+=f.value,p=f.rest)}this.__generatedMappings.push(n),"number"==typeof n.originalLine&&this.__originalMappings.push(n)}this.__generatedMappings.sort(i.compareByGeneratedPositions),this.__originalMappings.sort(i.compareByOriginalPositions)},r.prototype._findMapping=function(e,t,n,r,i){if(e[n]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+e[n]);if(e[r]<0)throw new TypeError("Column must be greater than or equal to 0, got "+e[r]);return o.search(e,t,i)},r.prototype.computeColumnSpans=function(){for(var e=0;e<this._generatedMappings.length;++e){var t=this._generatedMappings[e];if(e+1<this._generatedMappings.length){var n=this._generatedMappings[e+1];if(t.generatedLine===n.generatedLine){t.lastGeneratedColumn=n.generatedColumn-1;continue}}t.lastGeneratedColumn=1/0}},r.prototype.originalPositionFor=function(e){var t={generatedLine:i.getArg(e,"line"),generatedColumn:i.getArg(e,"column")},n=this._findMapping(t,this._generatedMappings,"generatedLine","generatedColumn",i.compareByGeneratedPositions);if(n>=0){var r=this._generatedMappings[n];if(r.generatedLine===t.generatedLine){var o=i.getArg(r,"source",null);return null!=o&&null!=this.sourceRoot&&(o=i.join(this.sourceRoot,o)),{source:o,line:i.getArg(r,"originalLine",null),column:i.getArg(r,"originalColumn",null),name:i.getArg(r,"name",null)}}}return{source:null,line:null,column:null,name:null}},r.prototype.sourceContentFor=function(e){if(!this.sourcesContent)return null;if(null!=this.sourceRoot&&(e=i.relative(this.sourceRoot,e)),this._sources.has(e))return this.sourcesContent[this._sources.indexOf(e)];var t;if(null!=this.sourceRoot&&(t=i.urlParse(this.sourceRoot))){var n=e.replace(/^file:\/\//,"");if("file"==t.scheme&&this._sources.has(n))return this.sourcesContent[this._sources.indexOf(n)];if((!t.path||"/"==t.path)&&this._sources.has("/"+e))return this.sourcesContent[this._sources.indexOf("/"+e)]}throw new Error('"'+e+'" is not in the SourceMap.')},r.prototype.generatedPositionFor=function(e){var t={source:i.getArg(e,"source"),originalLine:i.getArg(e,"line"),originalColumn:i.getArg(e,"column")};null!=this.sourceRoot&&(t.source=i.relative(this.sourceRoot,t.source));var n=this._findMapping(t,this._originalMappings,"originalLine","originalColumn",i.compareByOriginalPositions);if(n>=0){var r=this._originalMappings[n];return{line:i.getArg(r,"generatedLine",null),column:i.getArg(r,"generatedColumn",null),lastColumn:i.getArg(r,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}},r.prototype.allGeneratedPositionsFor=function(e){var t={source:i.getArg(e,"source"),originalLine:i.getArg(e,"line"),originalColumn:1/0};null!=this.sourceRoot&&(t.source=i.relative(this.sourceRoot,t.source));var n=[],r=this._findMapping(t,this._originalMappings,"originalLine","originalColumn",i.compareByOriginalPositions);if(r>=0)for(var o=this._originalMappings[r];o&&o.originalLine===t.originalLine;)n.push({line:i.getArg(o,"generatedLine",null),column:i.getArg(o,"generatedColumn",null),lastColumn:i.getArg(o,"lastGeneratedColumn",null)}),o=this._originalMappings[--r];return n.reverse()},r.GENERATED_ORDER=1,r.ORIGINAL_ORDER=2,r.prototype.eachMapping=function(e,t,n){var o,s=t||null,u=n||r.GENERATED_ORDER;switch(u){case r.GENERATED_ORDER:o=this._generatedMappings;break;case r.ORIGINAL_ORDER:o=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}var a=this.sourceRoot;o.map(function(e){var t=e.source;return null!=t&&null!=a&&(t=i.join(a,t)),{source:t,generatedLine:e.generatedLine,generatedColumn:e.generatedColumn,originalLine:e.originalLine,originalColumn:e.originalColumn,name:e.name}}).forEach(e,s)},t.SourceMapConsumer=r})},{"./array-set":17,"./base64-vlq":18,"./binary-search":20,"./util":25,amdefine:26}],23:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e){e||(e={}),this._file=o.getArg(e,"file",null),this._sourceRoot=o.getArg(e,"sourceRoot",null),this._skipValidation=o.getArg(e,"skipValidation",!1),this._sources=new s,this._names=new s,this._mappings=new u,this._sourcesContents=null}var i=e("./base64-vlq"),o=e("./util"),s=e("./array-set").ArraySet,u=e("./mapping-list").MappingList;r.prototype._version=3,r.fromSourceMap=function(e){var t=e.sourceRoot,n=new r({file:e.file,sourceRoot:t});return e.eachMapping(function(e){var r={generated:{line:e.generatedLine,column:e.generatedColumn}};null!=e.source&&(r.source=e.source,null!=t&&(r.source=o.relative(t,r.source)),r.original={line:e.originalLine,column:e.originalColumn},null!=e.name&&(r.name=e.name)),n.addMapping(r)}),e.sources.forEach(function(t){var r=e.sourceContentFor(t);null!=r&&n.setSourceContent(t,r)}),n},r.prototype.addMapping=function(e){var t=o.getArg(e,"generated"),n=o.getArg(e,"original",null),r=o.getArg(e,"source",null),i=o.getArg(e,"name",null);this._skipValidation||this._validateMapping(t,n,r,i),null==r||this._sources.has(r)||this._sources.add(r),null==i||this._names.has(i)||this._names.add(i),this._mappings.add({generatedLine:t.line,generatedColumn:t.column,originalLine:null!=n&&n.line,originalColumn:null!=n&&n.column,source:r,name:i})},r.prototype.setSourceContent=function(e,t){var n=e;null!=this._sourceRoot&&(n=o.relative(this._sourceRoot,n)),null!=t?(this._sourcesContents||(this._sourcesContents={}),this._sourcesContents[o.toSetString(n)]=t):this._sourcesContents&&(delete this._sourcesContents[o.toSetString(n)],0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))},r.prototype.applySourceMap=function(e,t,n){var r=t;if(null==t){if(null==e.file)throw new Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');r=e.file}var i=this._sourceRoot;null!=i&&(r=o.relative(i,r));var u=new s,a=new s;this._mappings.unsortedForEach(function(t){if(t.source===r&&null!=t.originalLine){var s=e.originalPositionFor({line:t.originalLine,column:t.originalColumn});null!=s.source&&(t.source=s.source,null!=n&&(t.source=o.join(n,t.source)),null!=i&&(t.source=o.relative(i,t.source)),t.originalLine=s.line,t.originalColumn=s.column,null!=s.name&&(t.name=s.name))}var c=t.source
2
- ;null==c||u.has(c)||u.add(c);var l=t.name;null==l||a.has(l)||a.add(l)},this),this._sources=u,this._names=a,e.sources.forEach(function(t){var r=e.sourceContentFor(t);null!=r&&(null!=n&&(t=o.join(n,t)),null!=i&&(t=o.relative(i,t)),this.setSourceContent(t,r))},this)},r.prototype._validateMapping=function(e,t,n,r){if((!(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0)||t||n||r)&&!(e&&"line"in e&&"column"in e&&t&&"line"in t&&"column"in t&&e.line>0&&e.column>=0&&t.line>0&&t.column>=0&&n))throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:n,original:t,name:r}))},r.prototype._serializeMappings=function(){for(var e,t=0,n=1,r=0,s=0,u=0,a=0,c="",l=this._mappings.toArray(),p=0,f=l.length;p<f;p++){if(e=l[p],e.generatedLine!==n)for(t=0;e.generatedLine!==n;)c+=";",n++;else if(p>0){if(!o.compareByGeneratedPositions(e,l[p-1]))continue;c+=","}c+=i.encode(e.generatedColumn-t),t=e.generatedColumn,null!=e.source&&(c+=i.encode(this._sources.indexOf(e.source)-a),a=this._sources.indexOf(e.source),c+=i.encode(e.originalLine-1-s),s=e.originalLine-1,c+=i.encode(e.originalColumn-r),r=e.originalColumn,null!=e.name&&(c+=i.encode(this._names.indexOf(e.name)-u),u=this._names.indexOf(e.name)))}return c},r.prototype._generateSourcesContent=function(e,t){return e.map(function(e){if(!this._sourcesContents)return null;null!=t&&(e=o.relative(t,e));var n=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,n)?this._sourcesContents[n]:null},this)},r.prototype.toJSON=function(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return null!=this._file&&(e.file=this._file),null!=this._sourceRoot&&(e.sourceRoot=this._sourceRoot),this._sourcesContents&&(e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)),e},r.prototype.toString=function(){return JSON.stringify(this)},t.SourceMapGenerator=r})},{"./array-set":17,"./base64-vlq":18,"./mapping-list":21,"./util":25,amdefine:26}],24:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e,t,n,r,i){this.children=[],this.sourceContents={},this.line=null==e?null:e,this.column=null==t?null:t,this.source=null==n?null:n,this.name=null==i?null:i,this[u]=!0,null!=r&&this.add(r)}var i=e("./source-map-generator").SourceMapGenerator,o=e("./util"),s=/(\r?\n)/,u="$$$isSourceNode$$$";r.fromStringWithSourceMap=function(e,t,n){function i(e,t){if(null===e||void 0===e.source)u.add(t);else{var i=n?o.join(n,e.source):e.source;u.add(new r(e.originalLine,e.originalColumn,i,t,e.name))}}var u=new r,a=e.split(s),c=function(){return a.shift()+(a.shift()||"")},l=1,p=0,f=null;return t.eachMapping(function(e){if(null!==f){if(!(l<e.generatedLine)){var t=a[0],n=t.substr(0,e.generatedColumn-p);return a[0]=t.substr(e.generatedColumn-p),p=e.generatedColumn,i(f,n),void(f=e)}var n="";i(f,c()),l++,p=0}for(;l<e.generatedLine;)u.add(c()),l++;if(p<e.generatedColumn){var t=a[0];u.add(t.substr(0,e.generatedColumn)),a[0]=t.substr(e.generatedColumn),p=e.generatedColumn}f=e},this),a.length>0&&(f&&i(f,c()),u.add(a.join(""))),t.sources.forEach(function(e){var r=t.sourceContentFor(e);null!=r&&(null!=n&&(e=o.join(n,e)),u.setSourceContent(e,r))}),u},r.prototype.add=function(e){if(Array.isArray(e))e.forEach(function(e){this.add(e)},this);else{if(!e[u]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);e&&this.children.push(e)}return this},r.prototype.prepend=function(e){if(Array.isArray(e))for(var t=e.length-1;t>=0;t--)this.prepend(e[t]);else{if(!e[u]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);this.children.unshift(e)}return this},r.prototype.walk=function(e){for(var t,n=0,r=this.children.length;n<r;n++)t=this.children[n],t[u]?t.walk(e):""!==t&&e(t,{source:this.source,line:this.line,column:this.column,name:this.name})},r.prototype.join=function(e){var t,n,r=this.children.length;if(r>0){for(t=[],n=0;n<r-1;n++)t.push(this.children[n]),t.push(e);t.push(this.children[n]),this.children=t}return this},r.prototype.replaceRight=function(e,t){var n=this.children[this.children.length-1];return n[u]?n.replaceRight(e,t):"string"==typeof n?this.children[this.children.length-1]=n.replace(e,t):this.children.push("".replace(e,t)),this},r.prototype.setSourceContent=function(e,t){this.sourceContents[o.toSetString(e)]=t},r.prototype.walkSourceContents=function(e){for(var t=0,n=this.children.length;t<n;t++)this.children[t][u]&&this.children[t].walkSourceContents(e);for(var r=Object.keys(this.sourceContents),t=0,n=r.length;t<n;t++)e(o.fromSetString(r[t]),this.sourceContents[r[t]])},r.prototype.toString=function(){var e="";return this.walk(function(t){e+=t}),e},r.prototype.toStringWithSourceMap=function(e){var t={code:"",line:1,column:0},n=new i(e),r=!1,o=null,s=null,u=null,a=null;return this.walk(function(e,i){t.code+=e,null!==i.source&&null!==i.line&&null!==i.column?(o===i.source&&s===i.line&&u===i.column&&a===i.name||n.addMapping({source:i.source,original:{line:i.line,column:i.column},generated:{line:t.line,column:t.column},name:i.name}),o=i.source,s=i.line,u=i.column,a=i.name,r=!0):r&&(n.addMapping({generated:{line:t.line,column:t.column}}),o=null,r=!1);for(var c=0,l=e.length;c<l;c++)10===e.charCodeAt(c)?(t.line++,t.column=0,c+1===l?(o=null,r=!1):r&&n.addMapping({source:i.source,original:{line:i.line,column:i.column},generated:{line:t.line,column:t.column},name:i.name})):t.column++}),this.walkSourceContents(function(e,t){n.setSourceContent(e,t)}),{code:t.code,map:n}},t.SourceNode=r})},{"./source-map-generator":23,"./util":25,amdefine:26}],25:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e,t,n){if(t in e)return e[t];if(3===arguments.length)return n;throw new Error('"'+t+'" is a required argument.')}function i(e){var t=e.match(m);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}function o(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}function s(e){var t=e,n=i(e);if(n){if(!n.path)return e;t=n.path}for(var r,s="/"===t.charAt(0),u=t.split(/\/+/),a=0,c=u.length-1;c>=0;c--)r=u[c],"."===r?u.splice(c,1):".."===r?a++:a>0&&(""===r?(u.splice(c+1,a),a=0):(u.splice(c,2),a--));return t=u.join("/"),""===t&&(t=s?"/":"."),n?(n.path=t,o(n)):t}function u(e,t){""===e&&(e="."),""===t&&(t=".");var n=i(t),r=i(e);if(r&&(e=r.path||"/"),n&&!n.scheme)return r&&(n.scheme=r.scheme),o(n);if(n||t.match(g))return t;if(r&&!r.host&&!r.path)return r.host=t,o(r);var u="/"===t.charAt(0)?t:s(e.replace(/\/+$/,"")+"/"+t);return r?(r.path=u,o(r)):u}function a(e,t){""===e&&(e="."),e=e.replace(/\/$/,"");var n=i(e);return"/"==t.charAt(0)&&n&&"/"==n.path?t.slice(1):0===t.indexOf(e+"/")?t.substr(e.length+1):t}function c(e){return"$"+e}function l(e){return e.substr(1)}function p(e,t){var n=e||"",r=t||"";return(n>r)-(n<r)}function f(e,t,n){var r;return(r=p(e.source,t.source))?r:(r=e.originalLine-t.originalLine)?r:(r=e.originalColumn-t.originalColumn)||n?r:(r=p(e.name,t.name))?r:(r=e.generatedLine-t.generatedLine)||e.generatedColumn-t.generatedColumn}function h(e,t,n){var r;return(r=e.generatedLine-t.generatedLine)?r:(r=e.generatedColumn-t.generatedColumn)||n?r:(r=p(e.source,t.source))?r:(r=e.originalLine-t.originalLine)?r:(r=e.originalColumn-t.originalColumn)||p(e.name,t.name)}t.getArg=r;var m=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/,g=/^data:.+\,.+$/;t.urlParse=i,t.urlGenerate=o,t.normalize=s,t.join=u,t.relative=a,t.toSetString=c,t.fromSetString=l,t.compareByOriginalPositions=f,t.compareByGeneratedPositions=h})},{amdefine:26}],26:[function(e,t,n){(function(n,r){"use strict";function i(t,i){function o(e){var t,n;for(t=0;e[t];t+=1)if("."===(n=e[t]))e.splice(t,1),t-=1;else if(".."===n){if(1===t&&(".."===e[2]||".."===e[0]))break;t>0&&(e.splice(t-1,2),t-=2)}}function s(e,t){var n;return e&&"."===e.charAt(0)&&t&&(n=t.split("/"),n=n.slice(0,n.length-1),n=n.concat(e.split("/")),o(n),e=n.join("/")),e}function u(e){return function(t){return s(t,e)}}function a(e){function t(t){m[e]=t}return t.fromText=function(e,t){throw new Error("amdefine does not implement load.fromText")},t}function c(e,n,o){var s,u,a,c;if(e)u=m[e]={},a={id:e,uri:r,exports:u},s=p(i,u,a,e);else{if(g)throw new Error("amdefine with no module ID cannot be called more than once per file.");g=!0,u=t.exports,a=t,s=p(i,u,a,t.id)}n&&(n=n.map(function(e){return s(e)})),void 0!==(c="function"==typeof o?o.apply(a.exports,n):o)&&(a.exports=c,e&&(m[e]=a.exports))}function l(e,t,n){Array.isArray(e)?(n=t,t=e,e=void 0):"string"!=typeof e&&(n=e,e=t=void 0),t&&!Array.isArray(t)&&(n=t,t=void 0),t||(t=["require","exports","module"]),e?h[e]=[e,t,n]:c(e,t,n)}var p,f,h={},m={},g=!1,d=e("path");return p=function(e,t,r,i){function o(o,s){if("string"==typeof o)return f(e,t,r,o,i);o=o.map(function(n){return f(e,t,r,n,i)}),s&&n.nextTick(function(){s.apply(null,o)})}return o.toUrl=function(e){return 0===e.indexOf(".")?s(e,d.dirname(r.filename)):e},o},i=i||function(){return t.require.apply(t,arguments)},f=function(e,t,n,r,i){var o,l,g=r.indexOf("!"),d=r;if(-1===g){if("require"===(r=s(r,i)))return p(e,t,n,i);if("exports"===r)return t;if("module"===r)return n;if(m.hasOwnProperty(r))return m[r];if(h[r])return c.apply(null,h[r]),m[r];if(e)return e(d);throw new Error("No module with ID: "+r)}return o=r.substring(0,g),r=r.substring(g+1,r.length),l=f(e,t,n,o,i),r=l.normalize?l.normalize(r,u(i)):s(r,i),m[r]?m[r]:(l.load(r,p(e,t,n,i),a(r),{}),m[r])},l.require=function(e){return m[e]?m[e]:h[e]?(c.apply(null,h[e]),m[e]):void 0},l.amd={},l}t.exports=i}).call(this,e("_process"),"/node_modules/css/node_modules/source-map/node_modules/amdefine/amdefine.js")},{_process:3,path:2}],27:[function(e,t,n){function r(e){return"\\"===i.sep?e.replace(/\\/g,"/").replace(/^[a-z]:\/?/i,"/"):e}var i=e("path");t.exports=r},{path:2}]},{},[4]);
1
+ !function e(t,n,r){function i(s,u){if(!n[s]){if(!t[s]){var a="function"==typeof require&&require;if(!u&&a)return a(s,!0);if(o)return o(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[s]={exports:{}};t[s][0].call(l.exports,function(e){var n=t[s][1][e];return i(n||e)},l,l.exports,e,t,n,r)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;s<r.length;s++)i(r[s]);return i}({1:[function(e,t,n){},{}],2:[function(e,t,n){(function(e){function t(e,t){for(var n=0,r=e.length-1;r>=0;r--){var i=e[r];"."===i?e.splice(r,1):".."===i?(e.splice(r,1),n++):n&&(e.splice(r,1),n--)}if(t)for(;n--;n)e.unshift("..");return e}function r(e,t){if(e.filter)return e.filter(t);for(var n=[],r=0;r<e.length;r++)t(e[r],r,e)&&n.push(e[r]);return n}var i=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,o=function(e){return i.exec(e).slice(1)};n.resolve=function(){for(var n="",i=!1,o=arguments.length-1;o>=-1&&!i;o--){var s=o>=0?arguments[o]:e.cwd();if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(n=s+"/"+n,i="/"===s.charAt(0))}return n=t(r(n.split("/"),function(e){return!!e}),!i).join("/"),(i?"/":"")+n||"."},n.normalize=function(e){var i=n.isAbsolute(e),o="/"===s(e,-1);return e=t(r(e.split("/"),function(e){return!!e}),!i).join("/"),e||i||(e="."),e&&o&&(e+="/"),(i?"/":"")+e},n.isAbsolute=function(e){return"/"===e.charAt(0)},n.join=function(){var e=Array.prototype.slice.call(arguments,0);return n.normalize(r(e,function(e,t){if("string"!=typeof e)throw new TypeError("Arguments to path.join must be strings");return e}).join("/"))},n.relative=function(e,t){function r(e){for(var t=0;t<e.length&&""===e[t];t++);for(var n=e.length-1;n>=0&&""===e[n];n--);return t>n?[]:e.slice(t,n-t+1)}e=n.resolve(e).substr(1),t=n.resolve(t).substr(1);for(var i=r(e.split("/")),o=r(t.split("/")),s=Math.min(i.length,o.length),u=s,a=0;a<s;a++)if(i[a]!==o[a]){u=a;break}for(var c=[],a=u;a<i.length;a++)c.push("..");return c=c.concat(o.slice(u)),c.join("/")},n.sep="/",n.delimiter=":",n.dirname=function(e){var t=o(e),n=t[0],r=t[1];return n||r?(r&&(r=r.substr(0,r.length-1)),n+r):"."},n.basename=function(e,t){var n=o(e)[2];return t&&n.substr(-1*t.length)===t&&(n=n.substr(0,n.length-t.length)),n},n.extname=function(e){return o(e)[3]};var s="b"==="ab".substr(-1)?function(e,t,n){return e.substr(t,n)}:function(e,t,n){return t<0&&(t=e.length+t),e.substr(t,n)}}).call(this,e("_process"))},{_process:3}],3:[function(e,t,n){function r(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function o(e){if(p===setTimeout)return setTimeout(e,0);if((p===r||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function s(e){if(f===clearTimeout)return clearTimeout(e);if((f===i||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(e);try{return f(e)}catch(t){try{return f.call(null,e)}catch(t){return f.call(this,e)}}}function u(){d&&m&&(d=!1,m.length?g=m.concat(g):v=-1,g.length&&a())}function a(){if(!d){var e=o(u);d=!0;for(var t=g.length;t;){for(m=g,g=[];++v<t;)m&&m[v].run();v=-1,t=g.length}m=null,d=!1,s(e)}}function c(e,t){this.fun=e,this.array=t}function l(){}var p,f,h=t.exports={};!function(){try{p="function"==typeof setTimeout?setTimeout:r}catch(e){p=r}try{f="function"==typeof clearTimeout?clearTimeout:i}catch(e){f=i}}();var m,g=[],d=!1,v=-1;h.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];g.push(new c(e,t)),1!==g.length||d||o(a)},c.prototype.run=function(){this.fun.apply(null,this.array)},h.title="browser",h.browser=!0,h.env={},h.argv=[],h.version="",h.versions={},h.on=l,h.addListener=l,h.once=l,h.off=l,h.removeListener=l,h.removeAllListeners=l,h.emit=l,h.prependListener=l,h.prependOnceListener=l,h.listeners=function(e){return[]},h.binding=function(e){throw new Error("process.binding is not supported")},h.cwd=function(){return"/"},h.chdir=function(e){throw new Error("process.chdir is not supported")},h.umask=function(){return 0}},{}],4:[function(e,t,n){window.css=e("css")},{css:6}],5:[function(e,t,n){(function(n,r){"use strict";function i(t,i){function o(e){var t,n;for(t=0;e[t];t+=1)if("."===(n=e[t]))e.splice(t,1),t-=1;else if(".."===n){if(1===t&&(".."===e[2]||".."===e[0]))break;t>0&&(e.splice(t-1,2),t-=2)}}function s(e,t){var n;return e&&"."===e.charAt(0)&&t&&(n=t.split("/"),n=n.slice(0,n.length-1),n=n.concat(e.split("/")),o(n),e=n.join("/")),e}function u(e){return function(t){return s(t,e)}}function a(e){function t(t){m[e]=t}return t.fromText=function(e,t){throw new Error("amdefine does not implement load.fromText")},t}function c(e,n,o){var s,u,a,c;if(e)u=m[e]={},a={id:e,uri:r,exports:u},s=p(i,u,a,e);else{if(g)throw new Error("amdefine with no module ID cannot be called more than once per file.");g=!0,u=t.exports,a=t,s=p(i,u,a,t.id)}n&&(n=n.map(function(e){return s(e)})),void 0!==(c="function"==typeof o?o.apply(a.exports,n):o)&&(a.exports=c,e&&(m[e]=a.exports))}function l(e,t,n){Array.isArray(e)?(n=t,t=e,e=void 0):"string"!=typeof e&&(n=e,e=t=void 0),t&&!Array.isArray(t)&&(n=t,t=void 0),t||(t=["require","exports","module"]),e?h[e]=[e,t,n]:c(e,t,n)}var p,f,h={},m={},g=!1,d=e("path");return p=function(e,t,r,i){function o(o,s){if("string"==typeof o)return f(e,t,r,o,i);o=o.map(function(n){return f(e,t,r,n,i)}),s&&n.nextTick(function(){s.apply(null,o)})}return o.toUrl=function(e){return 0===e.indexOf(".")?s(e,d.dirname(r.filename)):e},o},i=i||function(){return t.require.apply(t,arguments)},f=function(e,t,n,r,i){var o,l,g=r.indexOf("!"),d=r;if(-1===g){if("require"===(r=s(r,i)))return p(e,t,n,i);if("exports"===r)return t;if("module"===r)return n;if(m.hasOwnProperty(r))return m[r];if(h[r])return c.apply(null,h[r]),m[r];if(e)return e(d);throw new Error("No module with ID: "+r)}return o=r.substring(0,g),r=r.substring(g+1,r.length),l=f(e,t,n,o,i),r=l.normalize?l.normalize(r,u(i)):s(r,i),m[r]?m[r]:(l.load(r,p(e,t,n,i),a(r),{}),m[r])},l.require=function(e){return m[e]?m[e]:h[e]?(c.apply(null,h[e]),m[e]):void 0},l.amd={},l}t.exports=i}).call(this,e("_process"),"/node_modules\\amdefine\\amdefine.js")},{_process:3,path:2}],6:[function(e,t,n){n.parse=e("./lib/parse"),n.stringify=e("./lib/stringify")},{"./lib/parse":7,"./lib/stringify":11}],7:[function(e,t,n){function r(e){return e?e.replace(/^\s+|\s+$/g,""):""}function i(e,t){var n=e&&"string"==typeof e.type,r=n?e:t;for(var o in e){var s=e[o];Array.isArray(s)?s.forEach(function(e){i(e,r)}):s&&"object"==typeof s&&i(s,r)}return n&&Object.defineProperty(e,"parent",{configurable:!0,writable:!0,enumerable:!1,value:t||null}),e}var o=/\/\*[^*]*\*+([^\/*][^*]*\*+)*\//g;t.exports=function(e,t){function n(e){var t=e.match(/\n/g);t&&(j+=t.length);var n=e.lastIndexOf("\n");T=~n?e.length-n:T+e.length}function s(){var e={line:j,column:T};return function(t){return t.position=new u(e),h(),t}}function u(e){this.start=e,this.end={line:j,column:T},this.source=t.source}function a(n){var r=new Error(t.source+":"+j+":"+T+": "+n);if(r.reason=n,r.filename=t.source,r.line=j,r.column=T,r.source=e,!t.silent)throw r;k.push(r)}function c(){return f(/^{\s*/)}function l(){return f(/^}/)}function p(){var t,n=[];for(h(),m(n);e.length&&"}"!=e.charAt(0)&&(t=E()||O());)!1!==t&&(n.push(t),m(n));return n}function f(t){var r=t.exec(e);if(r){var i=r[0];return n(i),e=e.slice(i.length),r}}function h(){f(/^\s*/)}function m(e){var t;for(e=e||[];t=g();)!1!==t&&e.push(t);return e}function g(){var t=s();if("/"==e.charAt(0)&&"*"==e.charAt(1)){for(var r=2;""!=e.charAt(r)&&("*"!=e.charAt(r)||"/"!=e.charAt(r+1));)++r;if(r+=2,""===e.charAt(r-1))return a("End of comment missing");var i=e.slice(2,r-2);return T+=2,n(i),e=e.slice(r),T+=2,t({type:"comment",comment:i})}}function d(){var e=f(/^([^{]+)/);if(e)return r(e[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*\/+/g,"").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g,function(e){return e.replace(/,/g,"‌")}).split(/\s*(?![^(]*\)),\s*/).map(function(e){return e.replace(/\u200C/g,",")})}function v(){var e=s(),t=f(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);if(t){if(t=r(t[0]),!f(/^:\s*/))return a("property missing ':'");var n=f(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/),i=e({type:"declaration",property:t.replace(o,""),value:n?r(n[0]).replace(o,""):""});return f(/^[;\s]*/),i}}function y(){var e=[];if(!c())return a("missing '{'");m(e);for(var t;t=v();)!1!==t&&(e.push(t),m(e));return l()?e:a("missing '}'")}function _(){for(var e,t=[],n=s();e=f(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/);)t.push(e[1]),f(/^,\s*/);if(t.length)return n({type:"keyframe",values:t,declarations:y()})}function C(){var e=s(),t=f(/^@([-\w]+)?keyframes\s*/);if(t){var n=t[1],t=f(/^([-\w]+)\s*/);if(!t)return a("@keyframes missing name");var r=t[1];if(!c())return a("@keyframes missing '{'");for(var i,o=m();i=_();)o.push(i),o=o.concat(m());return l()?e({type:"keyframes",name:r,vendor:n,keyframes:o}):a("@keyframes missing '}'")}}function w(){var e=s(),t=f(/^@supports *([^{]+)/);if(t){var n=r(t[1]);if(!c())return a("@supports missing '{'");var i=m().concat(p());return l()?e({type:"supports",supports:n,rules:i}):a("@supports missing '}'")}}function S(){var e=s();if(f(/^@host\s*/)){if(!c())return a("@host missing '{'");var t=m().concat(p());return l()?e({type:"host",rules:t}):a("@host missing '}'")}}function A(){var e=s(),t=f(/^@media *([^{]+)/);if(t){var n=r(t[1]);if(!c())return a("@media missing '{'");var i=m().concat(p());return l()?e({type:"media",media:n,rules:i}):a("@media missing '}'")}}function M(){var e=s(),t=f(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);if(t)return e({type:"custom-media",name:r(t[1]),media:r(t[2])})}function b(){var e=s();if(f(/^@page */)){var t=d()||[];if(!c())return a("@page missing '{'");for(var n,r=m();n=v();)r.push(n),r=r.concat(m());return l()?e({type:"page",selectors:t,declarations:r}):a("@page missing '}'")}}function R(){var e=s(),t=f(/^@([-\w]+)?document *([^{]+)/);if(t){var n=r(t[1]),i=r(t[2]);if(!c())return a("@document missing '{'");var o=m().concat(p());return l()?e({type:"document",document:i,vendor:n,rules:o}):a("@document missing '}'")}}function x(){var e=s();if(f(/^@font-face\s*/)){if(!c())return a("@font-face missing '{'");for(var t,n=m();t=v();)n.push(t),n=n.concat(m());return l()?e({type:"font-face",declarations:n}):a("@font-face missing '}'")}}function L(e){var t=new RegExp("^@"+e+"\\s*([^;]+);");return function(){var n=s(),r=f(t);if(r){var i={type:e};return i[e]=r[1].trim(),n(i)}}}function E(){if("@"==e[0])return C()||A()||M()||w()||P()||G()||N()||R()||b()||S()||x()}function O(){var e=s(),t=d();return t?(m(),e({type:"rule",selectors:t,declarations:y()})):a("selector missing")}t=t||{};var j=1,T=1;u.prototype.content=e;var k=[],P=L("import"),G=L("charset"),N=L("namespace");return i(function(){return{type:"stylesheet",stylesheet:{rules:p(),parsingErrors:k}}}())}},{}],8:[function(e,t,n){function r(e){this.options=e||{}}t.exports=r,r.prototype.emit=function(e){return e},r.prototype.visit=function(e){return this[e.type](e)},r.prototype.mapVisit=function(e,t){var n="";t=t||"";for(var r=0,i=e.length;r<i;r++)n+=this.visit(e[r]),t&&r<i-1&&(n+=this.emit(t));return n}},{}],9:[function(e,t,n){function r(e){i.call(this,e)}var i=e("./compiler"),o=e("inherits");t.exports=r,o(r,i),r.prototype.compile=function(e){return e.stylesheet.rules.map(this.visit,this).join("")},r.prototype.comment=function(e){return this.emit("",e.position)},r.prototype.import=function(e){return this.emit("@import "+e.import+";",e.position)},r.prototype.media=function(e){return this.emit("@media "+e.media,e.position)+this.emit("{")+this.mapVisit(e.rules)+this.emit("}")},r.prototype.document=function(e){var t="@"+(e.vendor||"")+"document "+e.document;return this.emit(t,e.position)+this.emit("{")+this.mapVisit(e.rules)+this.emit("}")},r.prototype.charset=function(e){return this.emit("@charset "+e.charset+";",e.position)},r.prototype.namespace=function(e){return this.emit("@namespace "+e.namespace+";",e.position)},r.prototype.supports=function(e){return this.emit("@supports "+e.supports,e.position)+this.emit("{")+this.mapVisit(e.rules)+this.emit("}")},r.prototype.keyframes=function(e){return this.emit("@"+(e.vendor||"")+"keyframes "+e.name,e.position)+this.emit("{")+this.mapVisit(e.keyframes)+this.emit("}")},r.prototype.keyframe=function(e){var t=e.declarations;return this.emit(e.values.join(","),e.position)+this.emit("{")+this.mapVisit(t)+this.emit("}")},r.prototype.page=function(e){var t=e.selectors.length?e.selectors.join(", "):"";return this.emit("@page "+t,e.position)+this.emit("{")+this.mapVisit(e.declarations)+this.emit("}")},r.prototype["font-face"]=function(e){return this.emit("@font-face",e.position)+this.emit("{")+this.mapVisit(e.declarations)+this.emit("}")},r.prototype.host=function(e){return this.emit("@host",e.position)+this.emit("{")+this.mapVisit(e.rules)+this.emit("}")},r.prototype["custom-media"]=function(e){return this.emit("@custom-media "+e.name+" "+e.media+";",e.position)},r.prototype.rule=function(e){var t=e.declarations;return t.length?this.emit(e.selectors.join(","),e.position)+this.emit("{")+this.mapVisit(t)+this.emit("}"):""},r.prototype.declaration=function(e){return this.emit(e.property+":"+e.value,e.position)+this.emit(";")}},{"./compiler":8,inherits:13}],10:[function(e,t,n){function r(e){e=e||{},i.call(this,e),this.indentation=e.indent}var i=e("./compiler"),o=e("inherits");t.exports=r,o(r,i),r.prototype.compile=function(e){return this.stylesheet(e)},r.prototype.stylesheet=function(e){return this.mapVisit(e.stylesheet.rules,"\n\n")},r.prototype.comment=function(e){return this.emit(this.indent()+"/*"+e.comment+"*/",e.position)},r.prototype.import=function(e){return this.emit("@import "+e.import+";",e.position)},r.prototype.media=function(e){return this.emit("@media "+e.media,e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},r.prototype.document=function(e){var t="@"+(e.vendor||"")+"document "+e.document;return this.emit(t,e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},r.prototype.charset=function(e){return this.emit("@charset "+e.charset+";",e.position)},r.prototype.namespace=function(e){return this.emit("@namespace "+e.namespace+";",e.position)},r.prototype.supports=function(e){return this.emit("@supports "+e.supports,e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},r.prototype.keyframes=function(e){return this.emit("@"+(e.vendor||"")+"keyframes "+e.name,e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.keyframes,"\n")+this.emit(this.indent(-1)+"}")},r.prototype.keyframe=function(e){var t=e.declarations;return this.emit(this.indent())+this.emit(e.values.join(", "),e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(t,"\n")+this.emit(this.indent(-1)+"\n"+this.indent()+"}\n")},r.prototype.page=function(e){var t=e.selectors.length?e.selectors.join(", ")+" ":"";return this.emit("@page "+t,e.position)+this.emit("{\n")+this.emit(this.indent(1))+this.mapVisit(e.declarations,"\n")+this.emit(this.indent(-1))+this.emit("\n}")},r.prototype["font-face"]=function(e){return this.emit("@font-face ",e.position)+this.emit("{\n")+this.emit(this.indent(1))+this.mapVisit(e.declarations,"\n")+this.emit(this.indent(-1))+this.emit("\n}")},r.prototype.host=function(e){return this.emit("@host",e.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},r.prototype["custom-media"]=function(e){return this.emit("@custom-media "+e.name+" "+e.media+";",e.position)},r.prototype.rule=function(e){var t=this.indent(),n=e.declarations;return n.length?this.emit(e.selectors.map(function(e){return t+e}).join(",\n"),e.position)+this.emit(" {\n")+this.emit(this.indent(1))+this.mapVisit(n,"\n")+this.emit(this.indent(-1))+this.emit("\n"+this.indent()+"}"):""},r.prototype.declaration=function(e){return this.emit(this.indent())+this.emit(e.property+": "+e.value,e.position)+this.emit(";")},r.prototype.indent=function(e){return this.level=this.level||1,null!=e?(this.level+=e,""):Array(this.level).join(this.indentation||" ")}},{"./compiler":8,inherits:13}],11:[function(e,t,n){var r=e("./compress"),i=e("./identity");t.exports=function(t,n){n=n||{};var o=n.compress?new r(n):new i(n);if(n.sourcemap){e("./source-map-support")(o);var s=o.compile(t);o.applySourceMaps();return{code:s,map:"generator"===n.sourcemap?o.map:o.map.toJSON()}}var s=o.compile(t);return s}},{"./compress":9,"./identity":10,"./source-map-support":12}],12:[function(e,t,n){function r(e){e._comment=e.comment,e.map=new i,e.position={line:1,column:1},e.files={};for(var t in n)e[t]=n[t]}var i=e("source-map").SourceMapGenerator,o=e("source-map").SourceMapConsumer,s=e("source-map-resolve"),u=e("urix"),a=e("fs"),c=e("path");t.exports=r,n.updatePosition=function(e){var t=e.match(/\n/g);t&&(this.position.line+=t.length);var n=e.lastIndexOf("\n");this.position.column=~n?e.length-n:this.position.column+e.length},n.emit=function(e,t){if(t){var n=u(t.source||"source.css");this.map.addMapping({source:n,generated:{line:this.position.line,column:Math.max(this.position.column-1,0)},original:{line:t.start.line,column:t.start.column-1}}),this.addFile(n,t)}return this.updatePosition(e),e},n.addFile=function(e,t){"string"==typeof t.content&&(Object.prototype.hasOwnProperty.call(this.files,e)||(this.files[e]=t.content))},n.applySourceMaps=function(){Object.keys(this.files).forEach(function(e){var t=this.files[e];if(this.map.setSourceContent(e,t),!1!==this.options.inputSourcemaps){var n=s.resolveSync(t,e,a.readFileSync);if(n){var r=new o(n.map),i=n.sourcesRelativeTo;this.map.applySourceMap(r,e,u(c.dirname(i)))}}},this)},n.comment=function(e){return/^# sourceMappingURL=/.test(e.comment)?this.emit("",e.position):this._comment(e)}},{fs:1,path:2,"source-map":17,"source-map-resolve":15,urix:27}],13:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],14:[function(e,t,n){!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof n?t.exports=r():e.resolveUrl=r()}(this,function(){function e(){var e=arguments.length;if(0===e)throw new Error("resolveUrl requires at least one argument; got none.");var t=document.createElement("base");if(t.href=arguments[0],1===e)return t.href;var n=document.getElementsByTagName("head")[0];n.insertBefore(t,n.firstChild);for(var r,i=document.createElement("a"),o=1;o<e;o++)i.href=arguments[o],r=i.href,t.href=r;return n.removeChild(t),r}return e})},{}],15:[function(e,t,n){!function(r,i){if("function"==typeof define&&define.amd)define(["source-map-url","resolve-url"],i);else if("object"==typeof n){var o=e("source-map-url"),s=e("resolve-url");t.exports=i(o,s)}else r.sourceMapResolve=i(r.sourceMappingURL,r.resolveUrl)}(this,function(e,t){function n(e,t,n){setImmediate(function(){e(t,n)})}function r(e){return JSON.parse(e.replace(/^\)\]\}'/,""))}function i(e,t,i,o){var u;try{u=s(e,t)}catch(e){return n(o,e)}if(!u||u.map)return n(o,null,u);i(u.url,function(e,t){if(e)return o(e);try{u.map=r(String(t))}catch(e){return o(e)}o(null,u)})}function o(e,t,n){var i=s(e,t);return!i||i.map?i:(i.map=r(String(n(i.url))),i)}function s(n,i){var o=e.getFrom(n);if(!o)return null;var s=o.match(f);if(s){var u=s[1],a=s[2],c=s[3];if(!h.test(u))throw new Error("Unuseful data uri mime type: "+(u||"text/plain"));return{sourceMappingURL:o,url:null,sourcesRelativeTo:i,map:r(";base64"===a?atob(c):decodeURIComponent(c))}}var l=t(i,o);return{sourceMappingURL:o,url:l,sourcesRelativeTo:l,map:null}}function u(e,t,r,i,o){"function"==typeof i&&(o=i,i={});var s=e.sources.length,u=!1,a={sourcesResolved:[],sourcesContent:[]},l=function(e){if(!u){if(e)return u=!0,o(e);s--,0===s&&o(null,a)}};c(e,t,i,function(e,t,i){a.sourcesResolved[i]=e,"string"==typeof t?(a.sourcesContent[i]=t,n(l,null)):r(e,function(e,t){a.sourcesContent[i]=String(t),l(e)})})}function a(e,t,n,r){var i={sourcesResolved:[],sourcesContent:[]};return c(e,t,r,function(e,t,r){i.sourcesResolved[r]=e,null!==n&&(i.sourcesContent[r]="string"==typeof t?t:String(n(e)))}),i}function c(e,n,r,i){r=r||{};for(var o,s,u=0,a=e.sources.length;u<a;u++)o=e.sourceRoot&&!r.ignoreSourceRoot?t(n,e.sourceRoot.replace(m,"/"),e.sources[u]):t(n,e.sources[u]),s=(e.sourcesContent||[])[u],i(o,s,u)}function l(e,t,n,r,o){"function"==typeof r&&(o=r,r={}),i(e,t,n,function(e,t){return e?o(e):t?void u(t.map,t.sourcesRelativeTo,n,r,function(e,n){if(e)return o(e);t.sourcesResolved=n.sourcesResolved,t.sourcesContent=n.sourcesContent,o(null,t)}):o(null,null)})}function p(e,t,n,r){var i=o(e,t,n);if(!i)return null;var s=a(i.map,i.sourcesRelativeTo,n,r);return i.sourcesResolved=s.sourcesResolved,i.sourcesContent=s.sourcesContent,i}var f=/^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/,h=/^(?:application|text)\/json$/,m=/\/?$/;return{resolveSourceMap:i,resolveSourceMapSync:o,resolveSources:u,resolveSourcesSync:a,resolve:l,resolveSync:p}})},{"resolve-url":14,"source-map-url":16}],16:[function(e,t,n){!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof n?t.exports=r():e.sourceMappingURL=r()}(this,function(){var e=/[#@] sourceMappingURL=([^\s'"]*)/,t=RegExp("(?:/\\*(?:\\s*\r?\n(?://)?)?(?:"+e.source+")\\s*\\*/|//(?:"+e.source+"))\\s*$");return{regex:t,_innerRegex:e,getFrom:function(e){var n=e.match(t);return n?n[1]||n[2]||"":null},existsIn:function(e){return t.test(e)},removeFrom:function(e){return e.replace(t,"")},insertBefore:function(e,n){var r=e.match(t);return r?e.slice(0,r.index)+n+e.slice(r.index):e+n}}})},{}],17:[function(e,t,n){n.SourceMapGenerator=e("./source-map/source-map-generator").SourceMapGenerator,n.SourceMapConsumer=e("./source-map/source-map-consumer").SourceMapConsumer,n.SourceNode=e("./source-map/source-node").SourceNode},{"./source-map/source-map-consumer":23,"./source-map/source-map-generator":24,"./source-map/source-node":25}],18:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(){this._array=[],this._set={}}var i=e("./util");r.fromArray=function(e,t){for(var n=new r,i=0,o=e.length;i<o;i++)n.add(e[i],t);return n},r.prototype.add=function(e,t){var n=this.has(e),r=this._array.length;n&&!t||this._array.push(e),n||(this._set[i.toSetString(e)]=r)},r.prototype.has=function(e){return Object.prototype.hasOwnProperty.call(this._set,i.toSetString(e))},r.prototype.indexOf=function(e){if(this.has(e))return this._set[i.toSetString(e)];throw new Error('"'+e+'" is not in the set.')},r.prototype.at=function(e){if(e>=0&&e<this._array.length)return this._array[e];throw new Error("No element indexed by "+e)},r.prototype.toArray=function(){return this._array.slice()},t.ArraySet=r})},{"./util":26,amdefine:5}],19:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e){return e<0?1+(-e<<1):0+(e<<1)}function i(e){var t=1==(1&e),n=e>>1;return t?-n:n}var o=e("./base64");t.encode=function(e){var t,n="",i=r(e);do{t=31&i,i>>>=5,i>0&&(t|=32),n+=o.encode(t)}while(i>0);return n},t.decode=function(e,t){var n,r,s=0,u=e.length,a=0,c=0;do{if(s>=u)throw new Error("Expected more digits in base 64 VLQ value.");r=o.decode(e.charAt(s++)),n=!!(32&r),r&=31,a+=r<<c,c+=5}while(n);t.value=i(a),t.rest=e.slice(s)}})},{"./base64":20,amdefine:5}],20:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){var r={},i={};"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("").forEach(function(e,t){r[e]=t,i[t]=e}),t.encode=function(e){if(e in i)return i[e];throw new TypeError("Must be between 0 and 63: "+e)},t.decode=function(e){if(e in r)return r[e];throw new TypeError("Not a valid base 64 digit: "+e)}})},{amdefine:5}],21:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e,t,n,i,o){var s=Math.floor((t-e)/2)+e,u=o(n,i[s],!0);return 0===u?s:u>0?t-s>1?r(s,t,n,i,o):s:s-e>1?r(e,s,n,i,o):e<0?-1:e}t.search=function(e,t,n){return 0===t.length?-1:r(-1,t.length,e,t,n)}})},{amdefine:5}],22:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e,t){var n=e.generatedLine,r=t.generatedLine,i=e.generatedColumn,s=t.generatedColumn;return r>n||r==n&&s>=i||o.compareByGeneratedPositions(e,t)<=0}function i(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}var o=e("./util");i.prototype.unsortedForEach=function(e,t){this._array.forEach(e,t)},i.prototype.add=function(e){r(this._last,e)?(this._last=e,this._array.push(e)):(this._sorted=!1,this._array.push(e))},i.prototype.toArray=function(){return this._sorted||(this._array.sort(o.compareByGeneratedPositions),this._sorted=!0),this._array},t.MappingList=i})},{"./util":26,amdefine:5}],23:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e){var t=e;"string"==typeof e&&(t=JSON.parse(e.replace(/^\)\]\}'/,"")));var n=i.getArg(t,"version"),r=i.getArg(t,"sources"),o=i.getArg(t,"names",[]),u=i.getArg(t,"sourceRoot",null),a=i.getArg(t,"sourcesContent",null),c=i.getArg(t,"mappings"),l=i.getArg(t,"file",null);if(n!=this._version)throw new Error("Unsupported version: "+n);r=r.map(i.normalize),this._names=s.fromArray(o,!0),this._sources=s.fromArray(r,!0),this.sourceRoot=u,this.sourcesContent=a,this._mappings=c,this.file=l}var i=e("./util"),o=e("./binary-search"),s=e("./array-set").ArraySet,u=e("./base64-vlq");r.fromSourceMap=function(e){var t=Object.create(r.prototype);return t._names=s.fromArray(e._names.toArray(),!0),t._sources=s.fromArray(e._sources.toArray(),!0),t.sourceRoot=e._sourceRoot,t.sourcesContent=e._generateSourcesContent(t._sources.toArray(),t.sourceRoot),t.file=e._file,t.__generatedMappings=e._mappings.toArray().slice(),t.__originalMappings=e._mappings.toArray().slice().sort(i.compareByOriginalPositions),t},r.prototype._version=3,Object.defineProperty(r.prototype,"sources",{get:function(){return this._sources.toArray().map(function(e){return null!=this.sourceRoot?i.join(this.sourceRoot,e):e},this)}}),r.prototype.__generatedMappings=null,Object.defineProperty(r.prototype,"_generatedMappings",{get:function(){return this.__generatedMappings||(this.__generatedMappings=[],this.__originalMappings=[],this._parseMappings(this._mappings,this.sourceRoot)),this.__generatedMappings}}),r.prototype.__originalMappings=null,Object.defineProperty(r.prototype,"_originalMappings",{get:function(){return this.__originalMappings||(this.__generatedMappings=[],this.__originalMappings=[],this._parseMappings(this._mappings,this.sourceRoot)),this.__originalMappings}}),r.prototype._nextCharIsMappingSeparator=function(e){var t=e.charAt(0);return";"===t||","===t},r.prototype._parseMappings=function(e,t){for(var n,r=1,o=0,s=0,a=0,c=0,l=0,p=e,f={};p.length>0;)if(";"===p.charAt(0))r++,p=p.slice(1),o=0;else if(","===p.charAt(0))p=p.slice(1);else{if(n={},n.generatedLine=r,u.decode(p,f),n.generatedColumn=o+f.value,o=n.generatedColumn,p=f.rest,p.length>0&&!this._nextCharIsMappingSeparator(p)){if(u.decode(p,f),n.source=this._sources.at(c+f.value),c+=f.value,p=f.rest,0===p.length||this._nextCharIsMappingSeparator(p))throw new Error("Found a source, but no line and column");if(u.decode(p,f),n.originalLine=s+f.value,s=n.originalLine,n.originalLine+=1,p=f.rest,0===p.length||this._nextCharIsMappingSeparator(p))throw new Error("Found a source and line, but no column");u.decode(p,f),n.originalColumn=a+f.value,a=n.originalColumn,p=f.rest,p.length>0&&!this._nextCharIsMappingSeparator(p)&&(u.decode(p,f),n.name=this._names.at(l+f.value),l+=f.value,p=f.rest)}this.__generatedMappings.push(n),"number"==typeof n.originalLine&&this.__originalMappings.push(n)}this.__generatedMappings.sort(i.compareByGeneratedPositions),this.__originalMappings.sort(i.compareByOriginalPositions)},r.prototype._findMapping=function(e,t,n,r,i){if(e[n]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+e[n]);if(e[r]<0)throw new TypeError("Column must be greater than or equal to 0, got "+e[r]);return o.search(e,t,i)},r.prototype.computeColumnSpans=function(){for(var e=0;e<this._generatedMappings.length;++e){var t=this._generatedMappings[e];if(e+1<this._generatedMappings.length){var n=this._generatedMappings[e+1];if(t.generatedLine===n.generatedLine){t.lastGeneratedColumn=n.generatedColumn-1;continue}}t.lastGeneratedColumn=1/0}},r.prototype.originalPositionFor=function(e){var t={generatedLine:i.getArg(e,"line"),generatedColumn:i.getArg(e,"column")},n=this._findMapping(t,this._generatedMappings,"generatedLine","generatedColumn",i.compareByGeneratedPositions);if(n>=0){var r=this._generatedMappings[n];if(r.generatedLine===t.generatedLine){var o=i.getArg(r,"source",null);return null!=o&&null!=this.sourceRoot&&(o=i.join(this.sourceRoot,o)),{source:o,line:i.getArg(r,"originalLine",null),column:i.getArg(r,"originalColumn",null),name:i.getArg(r,"name",null)}}}return{source:null,line:null,column:null,name:null}},r.prototype.sourceContentFor=function(e){if(!this.sourcesContent)return null;if(null!=this.sourceRoot&&(e=i.relative(this.sourceRoot,e)),this._sources.has(e))return this.sourcesContent[this._sources.indexOf(e)];var t;if(null!=this.sourceRoot&&(t=i.urlParse(this.sourceRoot))){var n=e.replace(/^file:\/\//,"");if("file"==t.scheme&&this._sources.has(n))return this.sourcesContent[this._sources.indexOf(n)];if((!t.path||"/"==t.path)&&this._sources.has("/"+e))return this.sourcesContent[this._sources.indexOf("/"+e)]}throw new Error('"'+e+'" is not in the SourceMap.')},r.prototype.generatedPositionFor=function(e){var t={source:i.getArg(e,"source"),originalLine:i.getArg(e,"line"),originalColumn:i.getArg(e,"column")};null!=this.sourceRoot&&(t.source=i.relative(this.sourceRoot,t.source));var n=this._findMapping(t,this._originalMappings,"originalLine","originalColumn",i.compareByOriginalPositions);if(n>=0){var r=this._originalMappings[n];return{line:i.getArg(r,"generatedLine",null),column:i.getArg(r,"generatedColumn",null),lastColumn:i.getArg(r,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}},r.prototype.allGeneratedPositionsFor=function(e){var t={source:i.getArg(e,"source"),originalLine:i.getArg(e,"line"),originalColumn:1/0};null!=this.sourceRoot&&(t.source=i.relative(this.sourceRoot,t.source));var n=[],r=this._findMapping(t,this._originalMappings,"originalLine","originalColumn",i.compareByOriginalPositions);if(r>=0)for(var o=this._originalMappings[r];o&&o.originalLine===t.originalLine;)n.push({line:i.getArg(o,"generatedLine",null),column:i.getArg(o,"generatedColumn",null),lastColumn:i.getArg(o,"lastGeneratedColumn",null)}),o=this._originalMappings[--r];return n.reverse()},r.GENERATED_ORDER=1,r.ORIGINAL_ORDER=2,r.prototype.eachMapping=function(e,t,n){var o,s=t||null,u=n||r.GENERATED_ORDER;switch(u){case r.GENERATED_ORDER:o=this._generatedMappings;break;case r.ORIGINAL_ORDER:o=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}var a=this.sourceRoot;o.map(function(e){var t=e.source;return null!=t&&null!=a&&(t=i.join(a,t)),{source:t,generatedLine:e.generatedLine,generatedColumn:e.generatedColumn,originalLine:e.originalLine,originalColumn:e.originalColumn,name:e.name}}).forEach(e,s)},t.SourceMapConsumer=r})},{"./array-set":18,"./base64-vlq":19,"./binary-search":21,"./util":26,amdefine:5}],24:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e){e||(e={}),this._file=o.getArg(e,"file",null),this._sourceRoot=o.getArg(e,"sourceRoot",null),this._skipValidation=o.getArg(e,"skipValidation",!1),this._sources=new s,this._names=new s,
2
+ this._mappings=new u,this._sourcesContents=null}var i=e("./base64-vlq"),o=e("./util"),s=e("./array-set").ArraySet,u=e("./mapping-list").MappingList;r.prototype._version=3,r.fromSourceMap=function(e){var t=e.sourceRoot,n=new r({file:e.file,sourceRoot:t});return e.eachMapping(function(e){var r={generated:{line:e.generatedLine,column:e.generatedColumn}};null!=e.source&&(r.source=e.source,null!=t&&(r.source=o.relative(t,r.source)),r.original={line:e.originalLine,column:e.originalColumn},null!=e.name&&(r.name=e.name)),n.addMapping(r)}),e.sources.forEach(function(t){var r=e.sourceContentFor(t);null!=r&&n.setSourceContent(t,r)}),n},r.prototype.addMapping=function(e){var t=o.getArg(e,"generated"),n=o.getArg(e,"original",null),r=o.getArg(e,"source",null),i=o.getArg(e,"name",null);this._skipValidation||this._validateMapping(t,n,r,i),null==r||this._sources.has(r)||this._sources.add(r),null==i||this._names.has(i)||this._names.add(i),this._mappings.add({generatedLine:t.line,generatedColumn:t.column,originalLine:null!=n&&n.line,originalColumn:null!=n&&n.column,source:r,name:i})},r.prototype.setSourceContent=function(e,t){var n=e;null!=this._sourceRoot&&(n=o.relative(this._sourceRoot,n)),null!=t?(this._sourcesContents||(this._sourcesContents={}),this._sourcesContents[o.toSetString(n)]=t):this._sourcesContents&&(delete this._sourcesContents[o.toSetString(n)],0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))},r.prototype.applySourceMap=function(e,t,n){var r=t;if(null==t){if(null==e.file)throw new Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');r=e.file}var i=this._sourceRoot;null!=i&&(r=o.relative(i,r));var u=new s,a=new s;this._mappings.unsortedForEach(function(t){if(t.source===r&&null!=t.originalLine){var s=e.originalPositionFor({line:t.originalLine,column:t.originalColumn});null!=s.source&&(t.source=s.source,null!=n&&(t.source=o.join(n,t.source)),null!=i&&(t.source=o.relative(i,t.source)),t.originalLine=s.line,t.originalColumn=s.column,null!=s.name&&(t.name=s.name))}var c=t.source;null==c||u.has(c)||u.add(c);var l=t.name;null==l||a.has(l)||a.add(l)},this),this._sources=u,this._names=a,e.sources.forEach(function(t){var r=e.sourceContentFor(t);null!=r&&(null!=n&&(t=o.join(n,t)),null!=i&&(t=o.relative(i,t)),this.setSourceContent(t,r))},this)},r.prototype._validateMapping=function(e,t,n,r){if((!(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0)||t||n||r)&&!(e&&"line"in e&&"column"in e&&t&&"line"in t&&"column"in t&&e.line>0&&e.column>=0&&t.line>0&&t.column>=0&&n))throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:n,original:t,name:r}))},r.prototype._serializeMappings=function(){for(var e,t=0,n=1,r=0,s=0,u=0,a=0,c="",l=this._mappings.toArray(),p=0,f=l.length;p<f;p++){if(e=l[p],e.generatedLine!==n)for(t=0;e.generatedLine!==n;)c+=";",n++;else if(p>0){if(!o.compareByGeneratedPositions(e,l[p-1]))continue;c+=","}c+=i.encode(e.generatedColumn-t),t=e.generatedColumn,null!=e.source&&(c+=i.encode(this._sources.indexOf(e.source)-a),a=this._sources.indexOf(e.source),c+=i.encode(e.originalLine-1-s),s=e.originalLine-1,c+=i.encode(e.originalColumn-r),r=e.originalColumn,null!=e.name&&(c+=i.encode(this._names.indexOf(e.name)-u),u=this._names.indexOf(e.name)))}return c},r.prototype._generateSourcesContent=function(e,t){return e.map(function(e){if(!this._sourcesContents)return null;null!=t&&(e=o.relative(t,e));var n=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,n)?this._sourcesContents[n]:null},this)},r.prototype.toJSON=function(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return null!=this._file&&(e.file=this._file),null!=this._sourceRoot&&(e.sourceRoot=this._sourceRoot),this._sourcesContents&&(e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)),e},r.prototype.toString=function(){return JSON.stringify(this)},t.SourceMapGenerator=r})},{"./array-set":18,"./base64-vlq":19,"./mapping-list":22,"./util":26,amdefine:5}],25:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e,t,n,r,i){this.children=[],this.sourceContents={},this.line=null==e?null:e,this.column=null==t?null:t,this.source=null==n?null:n,this.name=null==i?null:i,this[u]=!0,null!=r&&this.add(r)}var i=e("./source-map-generator").SourceMapGenerator,o=e("./util"),s=/(\r?\n)/,u="$$$isSourceNode$$$";r.fromStringWithSourceMap=function(e,t,n){function i(e,t){if(null===e||void 0===e.source)u.add(t);else{var i=n?o.join(n,e.source):e.source;u.add(new r(e.originalLine,e.originalColumn,i,t,e.name))}}var u=new r,a=e.split(s),c=function(){return a.shift()+(a.shift()||"")},l=1,p=0,f=null;return t.eachMapping(function(e){if(null!==f){if(!(l<e.generatedLine)){var t=a[0],n=t.substr(0,e.generatedColumn-p);return a[0]=t.substr(e.generatedColumn-p),p=e.generatedColumn,i(f,n),void(f=e)}var n="";i(f,c()),l++,p=0}for(;l<e.generatedLine;)u.add(c()),l++;if(p<e.generatedColumn){var t=a[0];u.add(t.substr(0,e.generatedColumn)),a[0]=t.substr(e.generatedColumn),p=e.generatedColumn}f=e},this),a.length>0&&(f&&i(f,c()),u.add(a.join(""))),t.sources.forEach(function(e){var r=t.sourceContentFor(e);null!=r&&(null!=n&&(e=o.join(n,e)),u.setSourceContent(e,r))}),u},r.prototype.add=function(e){if(Array.isArray(e))e.forEach(function(e){this.add(e)},this);else{if(!e[u]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);e&&this.children.push(e)}return this},r.prototype.prepend=function(e){if(Array.isArray(e))for(var t=e.length-1;t>=0;t--)this.prepend(e[t]);else{if(!e[u]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);this.children.unshift(e)}return this},r.prototype.walk=function(e){for(var t,n=0,r=this.children.length;n<r;n++)t=this.children[n],t[u]?t.walk(e):""!==t&&e(t,{source:this.source,line:this.line,column:this.column,name:this.name})},r.prototype.join=function(e){var t,n,r=this.children.length;if(r>0){for(t=[],n=0;n<r-1;n++)t.push(this.children[n]),t.push(e);t.push(this.children[n]),this.children=t}return this},r.prototype.replaceRight=function(e,t){var n=this.children[this.children.length-1];return n[u]?n.replaceRight(e,t):"string"==typeof n?this.children[this.children.length-1]=n.replace(e,t):this.children.push("".replace(e,t)),this},r.prototype.setSourceContent=function(e,t){this.sourceContents[o.toSetString(e)]=t},r.prototype.walkSourceContents=function(e){for(var t=0,n=this.children.length;t<n;t++)this.children[t][u]&&this.children[t].walkSourceContents(e);for(var r=Object.keys(this.sourceContents),t=0,n=r.length;t<n;t++)e(o.fromSetString(r[t]),this.sourceContents[r[t]])},r.prototype.toString=function(){var e="";return this.walk(function(t){e+=t}),e},r.prototype.toStringWithSourceMap=function(e){var t={code:"",line:1,column:0},n=new i(e),r=!1,o=null,s=null,u=null,a=null;return this.walk(function(e,i){t.code+=e,null!==i.source&&null!==i.line&&null!==i.column?(o===i.source&&s===i.line&&u===i.column&&a===i.name||n.addMapping({source:i.source,original:{line:i.line,column:i.column},generated:{line:t.line,column:t.column},name:i.name}),o=i.source,s=i.line,u=i.column,a=i.name,r=!0):r&&(n.addMapping({generated:{line:t.line,column:t.column}}),o=null,r=!1);for(var c=0,l=e.length;c<l;c++)10===e.charCodeAt(c)?(t.line++,t.column=0,c+1===l?(o=null,r=!1):r&&n.addMapping({source:i.source,original:{line:i.line,column:i.column},generated:{line:t.line,column:t.column},name:i.name})):t.column++}),this.walkSourceContents(function(e,t){n.setSourceContent(e,t)}),{code:t.code,map:n}},t.SourceNode=r})},{"./source-map-generator":24,"./util":26,amdefine:5}],26:[function(e,t,n){if("function"!=typeof r)var r=e("amdefine")(t,e);r(function(e,t,n){function r(e,t,n){if(t in e)return e[t];if(3===arguments.length)return n;throw new Error('"'+t+'" is a required argument.')}function i(e){var t=e.match(m);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}function o(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}function s(e){var t=e,n=i(e);if(n){if(!n.path)return e;t=n.path}for(var r,s="/"===t.charAt(0),u=t.split(/\/+/),a=0,c=u.length-1;c>=0;c--)r=u[c],"."===r?u.splice(c,1):".."===r?a++:a>0&&(""===r?(u.splice(c+1,a),a=0):(u.splice(c,2),a--));return t=u.join("/"),""===t&&(t=s?"/":"."),n?(n.path=t,o(n)):t}function u(e,t){""===e&&(e="."),""===t&&(t=".");var n=i(t),r=i(e);if(r&&(e=r.path||"/"),n&&!n.scheme)return r&&(n.scheme=r.scheme),o(n);if(n||t.match(g))return t;if(r&&!r.host&&!r.path)return r.host=t,o(r);var u="/"===t.charAt(0)?t:s(e.replace(/\/+$/,"")+"/"+t);return r?(r.path=u,o(r)):u}function a(e,t){""===e&&(e="."),e=e.replace(/\/$/,"");var n=i(e);return"/"==t.charAt(0)&&n&&"/"==n.path?t.slice(1):0===t.indexOf(e+"/")?t.substr(e.length+1):t}function c(e){return"$"+e}function l(e){return e.substr(1)}function p(e,t){var n=e||"",r=t||"";return(n>r)-(n<r)}function f(e,t,n){var r;return(r=p(e.source,t.source))?r:(r=e.originalLine-t.originalLine)?r:(r=e.originalColumn-t.originalColumn)||n?r:(r=p(e.name,t.name))?r:(r=e.generatedLine-t.generatedLine)||e.generatedColumn-t.generatedColumn}function h(e,t,n){var r;return(r=e.generatedLine-t.generatedLine)?r:(r=e.generatedColumn-t.generatedColumn)||n?r:(r=p(e.source,t.source))?r:(r=e.originalLine-t.originalLine)?r:(r=e.originalColumn-t.originalColumn)||p(e.name,t.name)}t.getArg=r;var m=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/,g=/^data:.+\,.+$/;t.urlParse=i,t.urlGenerate=o,t.normalize=s,t.join=u,t.relative=a,t.toSetString=c,t.fromSetString=l,t.compareByOriginalPositions=f,t.compareByGeneratedPositions=h})},{amdefine:5}],27:[function(e,t,n){function r(e){return"\\"===i.sep?e.replace(/\\/g,"/").replace(/^[a-z]:\/?/i,"/"):e}var i=e("path");t.exports=r},{path:2}]},{},[4]);
js/editor.js CHANGED
@@ -1,1696 +1,1844 @@
1
- /* globals jQuery, _, socssOptions, Backbone, CodeMirror, console, cssjs, wp */
2
-
3
- (function ($, _, socssOptions) {
4
-
5
- var socss = {
6
- model: {},
7
- collection: {},
8
- view: {},
9
- fn: {}
10
- };
11
-
12
- window.socss = socss;
13
-
14
- /**
15
- * The toolbar view
16
- */
17
- socss.view.toolbar = Backbone.View.extend({
18
-
19
- button: _.template('<li><a href="#" class="toolbar-button socss-button"><%= text %></a></li>'),
20
-
21
- editor: null,
22
-
23
- initialize: function ( attr ) {
24
- this.editor = attr.editor;
25
-
26
- var thisView = this;
27
- this.$('.editor-expand').click(function (e) {
28
- e.preventDefault();
29
- $(this).blur();
30
- thisView.trigger('click_expand');
31
- });
32
-
33
- this.$('.editor-visual').click(function (e) {
34
- e.preventDefault();
35
- $(this).blur();
36
- thisView.trigger('click_visual');
37
- });
38
- },
39
-
40
- addButton: function (text, action) {
41
- var thisView = this;
42
- var button = $(this.button({text: text}))
43
- .appendTo(this.$('.toolbar-function-buttons .toolbar-buttons'))
44
- .click(function (e) {
45
- e.preventDefault();
46
- $(this).blur();
47
- thisView.trigger('click_' + action);
48
- });
49
-
50
- return button;
51
- }
52
- });
53
-
54
- /**
55
- * The editor view, which handles codemirror stuff
56
- */
57
- socss.view.editor = Backbone.View.extend({
58
-
59
- codeMirror: null,
60
- snippets: null,
61
- toolbar: null,
62
- visualProperties: null,
63
-
64
- inspector: null,
65
-
66
- cssSelectors: [],
67
-
68
- initialize: function (args) {
69
- this.setupEditor();
70
- },
71
-
72
- render: function () {
73
- var thisView = this;
74
-
75
- // Setup the toolbar
76
- this.toolbar = new socss.view.toolbar({
77
- editor: this,
78
- el: this.$('.custom-css-toolbar')
79
- });
80
- this.toolbar.editor = this;
81
- this.toolbar.render();
82
-
83
- // Create the visual properties view
84
- this.visualProperties = new socss.view.properties({
85
- editor: this,
86
- el: $('#so-custom-css-properties')
87
- });
88
- this.visualProperties.render();
89
-
90
- this.toolbar.on('click_expand', function () {
91
- thisView.toggleExpand();
92
- });
93
-
94
- this.toolbar.on('click_visual', function () {
95
- thisView.visualProperties.loadCSS( thisView.codeMirror.getValue().trim() );
96
- thisView.visualProperties.show();
97
- });
98
-
99
- this.preview = new socss.view.preview({
100
- editor: this,
101
- el: this.$('.custom-css-preview')
102
- });
103
- this.preview.render();
104
- },
105
-
106
- /**
107
- * Do the initial setup of the CodeMirror editor
108
- */
109
- setupEditor: function () {
110
- var thisView = this;
111
- this.registerCodeMirrorAutocomplete();
112
-
113
- // Setup the Codemirror instance
114
- var $textArea = this.$('textarea.css-editor');
115
- var initValue = $textArea.val();
116
- // Pad with empty lines so the editor takes up all the white space. To try make sure user gets copy/paste
117
- // options in context menu.
118
- var newlineMatches = initValue.match(/\n/gm);
119
- var lineCount = newlineMatches ? newlineMatches.length+1 : 1;
120
- var paddedValue = initValue;
121
- $textArea.val(paddedValue);
122
- this.codeMirror = CodeMirror.fromTextArea($textArea.get(0), {
123
- tabSize: 2,
124
- lineNumbers: true,
125
- mode: 'css',
126
- theme: 'neat',
127
- inputStyle: 'contenteditable', //necessary to allow context menu (right click) copy/paste etc.
128
- gutters: [
129
- "CodeMirror-lint-markers"
130
- ],
131
- lint: true,
132
- });
133
-
134
- // Make sure the user doesn't leave without saving
135
- this.$el.on('submit', function(){
136
- initValue = thisView.codeMirror.getValue().trim();
137
- });
138
- $(window).bind('beforeunload', function(){
139
- var editorValue = thisView.codeMirror.getValue().trim();
140
- if( editorValue !== initValue ) {
141
- return socssOptions.loc.leave;
142
- }
143
- });
144
-
145
-
146
- // Set the container to visible overflow once the editor is setup
147
- this.$el.find('.custom-css-container').css('overflow', 'visible');
148
- this.scaleEditor();
149
-
150
- // Scale the editor whenever the window is resized
151
- $(window).resize(function () {
152
- thisView.scaleEditor();
153
- });
154
-
155
- // Setup the extensions
156
- this.setupCodeMirrorExtensions();
157
- },
158
-
159
- /**
160
- * Register the autocomplete helper. Based on css-hint.js in the codemirror addon folder.
161
- */
162
- registerCodeMirrorAutocomplete: function () {
163
- var thisView = this;
164
-
165
- var pseudoClasses = {
166
- link: 1, visited: 1, active: 1, hover: 1, focus: 1,
167
- "first-letter": 1, "first-line": 1, "first-child": 1,
168
- before: 1, after: 1, lang: 1
169
- };
170
-
171
- CodeMirror.registerHelper("hint", "css", function (cm) {
172
- var cur = cm.getCursor(), token = cm.getTokenAt(cur);
173
- var inner = CodeMirror.innerMode(cm.getMode(), token.state);
174
- if (inner.mode.name !== "css") {
175
- return;
176
- }
177
-
178
- if (token.type === "keyword" && "!important".indexOf(token.string) === 0) {
179
- return {
180
- list: ["!important"], from: CodeMirror.Pos(cur.line, token.start),
181
- to: CodeMirror.Pos(cur.line, token.end)
182
- };
183
- }
184
-
185
- var start = token.start, end = cur.ch, word = token.string.slice(0, end - start);
186
- if (/[^\w$_-]/.test(word)) {
187
- word = "";
188
- start = end = cur.ch;
189
- }
190
-
191
- var spec = CodeMirror.resolveMode("text/css");
192
-
193
- var result = [];
194
-
195
- function add(keywords) {
196
- for (var name in keywords) {
197
- if (!word || name.lastIndexOf(word, 0) === 0) {
198
- result.push(name);
199
- }
200
- }
201
- }
202
-
203
- var st = inner.state.state;
204
-
205
- if (st === 'top') {
206
- // We're going to autocomplete the selector using our own set of rules
207
- var line = cm.getLine(cur.line).trim();
208
-
209
- var selectors = thisView.cssSelectors;
210
- for (var i = 0; i < selectors.length; i++) {
211
- if (selectors[i].selector.indexOf(line) !== -1) {
212
- result.push(selectors[i].selector);
213
- }
214
- }
215
-
216
- if (result.length) {
217
- return {
218
- list: result,
219
- from: CodeMirror.Pos(cur.line, 0),
220
- to: CodeMirror.Pos(cur.line, end)
221
- };
222
- }
223
- }
224
- else {
225
-
226
- if (st === "pseudo" || token.type === "variable-3") {
227
- add(pseudoClasses);
228
- }
229
- else if (st === "block" || st === "maybeprop") {
230
- add(spec.propertyKeywords);
231
- }
232
- else if (st === "prop" || st === "parens" || st === "at" || st === "params") {
233
- add(spec.valueKeywords);
234
- add(spec.colorKeywords);
235
- }
236
- else if (st === "media" || st === "media_parens") {
237
- add(spec.mediaTypes);
238
- add(spec.mediaFeatures);
239
- }
240
-
241
- if (result.length) {
242
- return {
243
- list: result,
244
- from: CodeMirror.Pos(cur.line, start),
245
- to: CodeMirror.Pos(cur.line, end)
246
- };
247
- }
248
-
249
- }
250
-
251
- });
252
- },
253
-
254
- setupCodeMirrorExtensions: function () {
255
- var thisView = this;
256
-
257
- this.codeMirror.on('cursorActivity', function (cm) {
258
- var cur = cm.getCursor(), token = cm.getTokenAt(cur);
259
- var inner = CodeMirror.innerMode(cm.getMode(), token.state);
260
-
261
- // If we have a qualifier selected, then highlight that in the preview
262
- if (token.type === 'qualifier' || token.type === 'tag' || token.type === 'builtin') {
263
- var line = cm.getLine(cur.line);
264
- var selector = line.substring(0, token.end);
265
-
266
- thisView.preview.highlight(selector);
267
- }
268
- else {
269
- thisView.preview.clearHighlight();
270
- }
271
- });
272
-
273
- // This sets up automatic autocompletion at all times
274
- this.codeMirror.on('keyup', function (cm, e) {
275
- if (
276
- ( e.keyCode >= 65 && e.keyCode <= 90 ) ||
277
- ( e.keyCode === 189 && !e.shiftKey ) ||
278
- ( e.keyCode === 190 && !e.shiftKey ) ||
279
- ( e.keyCode === 51 && e.shiftKey ) ||
280
- ( e.keyCode === 189 && e.shiftKey )
281
- ) {
282
- cm.showHint( {
283
- completeSingle: false
284
- } );
285
- }
286
- });
287
- },
288
-
289
- /**
290
- * Scale the size of the editor depending on whether it's expanded or not
291
- */
292
- scaleEditor: function () {
293
- var windowHeight = $( window ).outerHeight();
294
- if (this.$el.hasClass('expanded')) {
295
- // If we're in the expanded view, then resize the editor
296
- this.$el.find( '.CodeMirror-scroll' ).css( 'max-height', '' );
297
- this.codeMirror.setSize('100%', windowHeight - this.$('.custom-css-toolbar').outerHeight());
298
- }
299
- else {
300
- // Attempt to calculate approximate space available for editor when not expanded.
301
- var $form = $( '#so-custom-css-form' );
302
- var otherEltsHeight = $('#wpadminbar').outerHeight( true ) +
303
- $( '#siteorigin-custom-css' ).find( '> h2' ).outerHeight( true ) +
304
- $form.find( '> .custom-css-toolbar' ).outerHeight( true ) +
305
- $form.find( '> p.description' ).outerHeight( true ) +
306
- $form.find( '> p.submit' ).outerHeight( true ) +
307
- parseFloat( $( '#wpbody-content' ).css( 'padding-bottom' ) );
308
- this.$el.find( '.CodeMirror-scroll' ).css( 'max-height', windowHeight - otherEltsHeight );
309
- this.codeMirror.setSize( '100%', 'auto' );
310
- }
311
- },
312
-
313
- /**
314
- * Check if the editor is in expanded mode
315
- * @returns bool
316
- */
317
- isExpanded: function () {
318
- return this.$el.hasClass('expanded');
319
- },
320
-
321
- /**
322
- * Toggle if this is expanded or not
323
- */
324
- toggleExpand: function () {
325
- this.$el.toggleClass('expanded');
326
- this.scaleEditor();
327
- },
328
-
329
- /**
330
- * Set the expanded state of the editor
331
- * @param expanded
332
- */
333
- setExpand: function (expanded) {
334
- if (expanded) {
335
- this.$el.addClass('expanded');
336
- }
337
- else {
338
- this.$el.removeClass('expanded');
339
- }
340
- this.scaleEditor();
341
- },
342
-
343
- /**
344
- * Set the snippets available to this editor
345
- */
346
- setSnippets: function (snippets) {
347
- if (!_.isEmpty(snippets)) {
348
- var thisView = this;
349
-
350
- this.snippets = new socss.view.snippets({
351
- snippets: snippets
352
- });
353
- this.snippets.editor = this;
354
-
355
- this.snippets.render();
356
- this.toolbar.addButton('Snippets', 'snippets');
357
- this.toolbar.on('click_snippets', function () {
358
- thisView.snippets.show();
359
- });
360
- }
361
- },
362
-
363
- /**
364
- * Add some CSS to the editor.
365
- * @param css
366
- */
367
- addCode: function (css) {
368
- var editor = this.codeMirror;
369
-
370
- var before_css = '';
371
- if (editor.doc.lineCount() === 1 && editor.doc.getLine(editor.doc.lastLine()).length === 0) {
372
- before_css = "";
373
- }
374
- else if (editor.doc.getLine(editor.doc.lastLine()).length === 0) {
375
- before_css = "\n";
376
- }
377
- else {
378
- before_css = "\n\n";
379
- }
380
-
381
- // Now insert the code in the editor
382
- editor.doc.setCursor(
383
- editor.doc.lastLine(),
384
- editor.doc.getLine(editor.doc.lastLine()).length
385
- );
386
- editor.doc.replaceSelection(before_css + css);
387
- },
388
-
389
- addEmptySelector: function (selector) {
390
- this.addCode(selector + " {\n \n}");
391
- },
392
-
393
- /**
394
- * Sets the inspector view that's being used by the editor
395
- */
396
- setInspector: function (inspector) {
397
- var thisView = this;
398
- this.inspector = inspector;
399
- this.cssSelectors = inspector.pageSelectors;
400
-
401
- // A selector is clicked in the inspector
402
- inspector.on('click_selector', function (selector) {
403
- if ( thisView.visualProperties.isVisible() ) {
404
- thisView.visualProperties.addSelector(selector);
405
- }
406
- else {
407
- thisView.addEmptySelector(selector);
408
- }
409
- });
410
-
411
- // A property is clicked in the inspector
412
- inspector.on('click_property', function (property) {
413
- if ( ! thisView.visualProperties.isVisible() ) {
414
- thisView.codeMirror.replaceSelection(property + ";\n ");
415
- }
416
- });
417
-
418
- inspector.on('set_active_element', function(el, selectors){
419
- if ( thisView.visualProperties.isVisible() && selectors.length ) {
420
- thisView.visualProperties.addSelector( selectors[0].selector );
421
- }
422
- });
423
- }
424
-
425
- });
426
-
427
- /**
428
- * The preview.
429
- */
430
- socss.view.preview = Backbone.View.extend({
431
-
432
- template: _.template( $('#template-preview-window').html() ),
433
- editor: null,
434
- originalUri: null,
435
- currentUri: null,
436
-
437
- initialize: function (attr) {
438
- this.editor = attr.editor;
439
-
440
- var thisView = this;
441
- this.editor.codeMirror.on('change', function (cm, c) {
442
- thisView.updatePreviewCss();
443
- });
444
- },
445
-
446
- render: function () {
447
- var thisView = this;
448
-
449
- this.$el.html( this.template() );
450
-
451
- this.$( '#preview-iframe' )
452
- .attr( 'src', socssOptions.homeURL )
453
- .on( 'load', function () {
454
- var $$ = $(this);
455
-
456
- // Update the current URI with the iframe URI
457
- thisView.currentUri = new URI( $$.contents().get(0).location.href );
458
- thisView.currentUri.removeQuery( 'so_css_preview' );
459
- thisView.$( '#preview-navigator input' ).val( thisView.currentUri.toString() );
460
- thisView.currentUri.addQuery( 'so_css_preview', 1 );
461
-
462
- $$.contents().find('a').each(function () {
463
- var href = $(this).attr('href');
464
- if (href === undefined) {
465
- return true;
466
- }
467
-
468
- var firstSeperator = (href.indexOf('?') === -1 ? '?' : '&');
469
- $(this).attr('href', href + firstSeperator + 'so_css_preview=1');
470
- });
471
-
472
- thisView.updatePreviewCss();
473
- })
474
- .mouseleave(function () {
475
- thisView.clearHighlight();
476
- });
477
-
478
- this.$( '#preview-navigator input' ).keydown( function( e ){
479
- var $$ = $(this);
480
-
481
- if( e.keyCode == 13 ) {
482
- e.preventDefault();
483
-
484
- var newUri = new URI( $$.val() );
485
-
486
- // Validate the URI
487
- if(
488
- thisView.originalUri.host() !== newUri.host() ||
489
- thisView.originalUri.protocol() !== newUri.protocol()
490
- ) {
491
- $$.blur();
492
- alert( $$.data( 'invalid-uri' ) );
493
- $$.focus();
494
- }
495
- else {
496
- newUri.addQuery( 'so_css_preview', 1 );
497
- thisView.$( '#preview-iframe' ).attr( 'src', newUri.toString() );
498
- }
499
- }
500
- } );
501
-
502
- this.originalUri = new URI( socssOptions.homeURL );
503
- this.currentUri = new URI( socssOptions.homeURL );
504
-
505
- this.currentUri.removeQuery( 'so_css_preview' );
506
- this.$('#preview-navigator input').val( this.currentUri.toString() );
507
- this.currentUri.addQuery( 'so_css_preview', 1 );
508
- },
509
-
510
- /**
511
- * Update the preview CSS from the CodeMirror value in the editor
512
- */
513
- updatePreviewCss: function () {
514
- var preview = this.$('#preview-iframe');
515
- if (preview.length === 0) {
516
- return;
517
- }
518
-
519
- var head = preview.contents().find('head');
520
- if (head.find('style.siteorigin-custom-css').length === 0) {
521
- head.append('<style class="siteorigin-custom-css" type="text/css"></style>');
522
- }
523
- var style = head.find('style.siteorigin-custom-css');
524
-
525
- // Update the CSS after a short delay
526
- var css = this.editor.codeMirror.getValue().trim();
527
- style.html(css);
528
- },
529
-
530
- /**
531
- * Highlight all elements with a given selector
532
- */
533
- highlight: function (selector) {
534
- try {
535
- this.editor.inspector.hl.highlight(selector);
536
- }
537
- catch (err) {
538
- console.log('No inspector to highlight with');
539
- }
540
- },
541
-
542
- /**
543
- * Clear the currently highlighted elements in preview
544
- */
545
- clearHighlight: function () {
546
- try {
547
- this.editor.inspector.hl.clear();
548
- }
549
- catch (err) {
550
- console.log('No inspector to highlight with');
551
- }
552
- }
553
-
554
- });
555
-
556
- /**
557
- * The dialog for the snippets browser
558
- */
559
- socss.view.snippets = Backbone.View.extend({
560
- template: _.template($('#template-snippet-browser').html()),
561
- snippet: _.template('<li class="snippet"><%- name %></li>'),
562
- className: 'css-editor-snippet-browser',
563
- snippets: null,
564
- editor: null,
565
-
566
- events: {
567
- 'click .close': 'hide',
568
- 'click .buttons .insert-snippet': 'insertSnippet'
569
- },
570
-
571
- currentSnippet: null,
572
-
573
- initialize: function (args) {
574
- this.snippets = args.snippets;
575
- },
576
-
577
- render: function () {
578
- var thisView = this;
579
-
580
-
581
- var clickSnippet = function (e) {
582
- e.preventDefault();
583
- var $$ = $(this);
584
-
585
- thisView.$('.snippets li.snippet').removeClass('active');
586
- $(this).addClass('active');
587
- thisView.viewSnippet({
588
- name: $$.html(),
589
- description: $$.data('description'),
590
- css: $$.data('css')
591
- });
592
- };
593
-
594
- this.$el.html(this.template());
595
- for (var i = 0; i < this.snippets.length; i++) {
596
- $(this.snippet({name: this.snippets[i].Name}))
597
- .data({
598
- 'description': this.snippets[i].Description,
599
- 'css': this.snippets[i].css
600
- })
601
- .appendTo(this.$('ul.snippets'))
602
- .click(clickSnippet);
603
- }
604
-
605
- // Click on the first one
606
- thisView.$('.snippets li.snippet').eq(0).click();
607
-
608
- this.attach();
609
- return this;
610
- },
611
-
612
- viewSnippet: function (args) {
613
- var w = this.$('.main .snippet-view');
614
-
615
- w.find('.snippet-title').html(args.name);
616
- w.find('.snippet-description').html(args.description);
617
- w.find('.snippet-code').html(args.css);
618
-
619
- this.currentSnippet = args;
620
- },
621
-
622
- insertSnippet: function () {
623
- var editor = this.editor.codeMirror;
624
- var css = this.currentSnippet.css;
625
-
626
- var before_css = '';
627
- if (editor.doc.lineCount() === 1 && editor.doc.getLine(editor.doc.lastLine()).length === 0) {
628
- before_css = "";
629
- }
630
- else if (editor.doc.getLine(editor.doc.lastLine()).length === 0) {
631
- before_css = "\n";
632
- }
633
- else {
634
- before_css = "\n\n";
635
- }
636
-
637
- // Now insert the code in the editor
638
- editor.doc.setCursor(
639
- editor.doc.lastLine(),
640
- editor.doc.getLine(editor.doc.lastLine()).length
641
- );
642
- editor.doc.replaceSelection(before_css + css);
643
-
644
- this.hide();
645
- },
646
-
647
- attach: function () {
648
- this.$el.appendTo('body');
649
- },
650
-
651
- show: function () {
652
- this.$el.show();
653
- },
654
-
655
- hide: function () {
656
- this.$el.hide();
657
- }
658
- });
659
-
660
-
661
- /**
662
- * The visual properties editor
663
- */
664
- socss.view.properties = Backbone.View.extend({
665
-
666
- model: socss.model.cssRules,
667
-
668
- tabTemplate: _.template('<li data-section="<%- id %>"><span class="fa fa-<%- icon %>"></span> <%- title %></li>'),
669
- sectionTemplate: _.template('<div class="section" data-section="<%- id %>"><table class="fields-table"><tbody></tbody></table></div>'),
670
- controllerTemplate: _.template('<tr><th scope="row"><%- title %></th><td></td></tr>'),
671
-
672
- /**
673
- * The controllers for each of the properties
674
- */
675
- propertyControllers: [],
676
-
677
- /**
678
- * The editor view
679
- */
680
- editor: null,
681
-
682
- /**
683
- * The current, raw CSS
684
- */
685
- css: '',
686
-
687
- /**
688
- * Parsed CSS
689
- */
690
- parsed: {},
691
-
692
- /**
693
- * The current active selector
694
- */
695
- activeSelector: '',
696
-
697
- /**
698
- * Was the editor expanded before we went into the property editor
699
- */
700
- editorExpandedBefore: false,
701
-
702
- events: {
703
- 'click .close': 'hide'
704
- },
705
-
706
- /**
707
- * Initialize the properties editor with a new model
708
- */
709
- initialize: function ( attr ) {
710
- this.parser = window.css;
711
- this.editor = attr.editor;
712
- },
713
-
714
- /**
715
- * Render the property editor
716
- */
717
- render: function () {
718
- var thisView = this;
719
-
720
- // Clean up for potential re-renders
721
- this.$('.section-tabs').empty();
722
- this.$('.sections').empty();
723
- this.$('.toolbar select').off();
724
- thisView.propertyControllers = [];
725
-
726
- var controllers = socssOptions.propertyControllers;
727
-
728
- for (var id in controllers) {
729
- // Create the tabs
730
- var $t = $(this.tabTemplate({
731
- id: id,
732
- icon: controllers[id].icon,
733
- title: controllers[id].title
734
- })).appendTo(this.$('.section-tabs'));
735
-
736
- // Create the section wrapper
737
- var $s = $(this.sectionTemplate({
738
- id: id
739
- })).appendTo(this.$('.sections'));
740
-
741
- // Now lets add the controllers
742
- if (!_.isEmpty(controllers[id].controllers)) {
743
-
744
- for (var i = 0; i < controllers[id].controllers.length; i++) {
745
-
746
- var $c = $(thisView.controllerTemplate({
747
- title: controllers[id].controllers[i].title
748
- })).appendTo($s.find('tbody'));
749
-
750
- var controllerAtts = controllers[id].controllers[i];
751
- var controller;
752
-
753
- if (typeof socss.view.properties.controllers[controllerAtts.type] === 'undefined') {
754
- // Setup a default controller
755
- controller = new socss.view.propertyController({
756
- el: $c.find('td'),
757
- propertiesView: thisView,
758
- args: ( typeof controllerAtts.args === 'undefined' ? {} : controllerAtts.args )
759
- });
760
- }
761
- else {
762
- // Setup a specific controller
763
- controller = new socss.view.properties.controllers[controllerAtts.type]({
764
- el: $c.find('td'),
765
- propertiesView: thisView,
766
- args: ( typeof controllerAtts.args === 'undefined' ? {} : controllerAtts.args )
767
- });
768
- }
769
-
770
- thisView.propertyControllers.push(controller);
771
-
772
- // Setup and render the controller
773
- controller.render();
774
- controller.initChangeEvents();
775
- }
776
- }
777
- }
778
-
779
- // Setup the tab switching for the property sections
780
- this.$('.section-tabs li').click(function () {
781
- var $$ = $(this);
782
- var show = thisView.$('.sections .section[data-section="' + $$.data('section') + '"]');
783
-
784
- thisView.$('.sections .section').not(show).hide().removeClass('active');
785
- show.show().addClass('active');
786
-
787
- thisView.$('.section-tabs li').not($$).removeClass('active');
788
- $$.addClass('active');
789
- }).eq(0).click();
790
-
791
- this.$('.toolbar select').change(function () {
792
- thisView.setActivateSelector($(this).find(':selected').data('selector'));
793
- });
794
- },
795
-
796
- /**
797
- * Sets the rule value for the active selector
798
- * @param rule
799
- * @param value
800
- */
801
- setRuleValue: function (rule, value) {
802
- if (
803
- typeof this.activeSelector === 'undefined' ||
804
- typeof this.activeSelector.declarations === 'undefined'
805
- ) {
806
- return;
807
- }
808
-
809
- var declarations = this.activeSelector.declarations;
810
- var newRule = true;
811
- var valueChanged = false;
812
- for (var i = 0; i < declarations.length; i++) {
813
- if (declarations[i].property === rule) {
814
- newRule = false;
815
- var declaration = declarations[i];
816
- if ( declaration.value !== value ) {
817
- declaration.value = value;
818
- valueChanged = true;
819
- }
820
-
821
- // Remove empty declarations
822
- if ( _.isEmpty( declaration.value ) ) {
823
- declarations.splice( declarations.indexOf( declaration ) );
824
- }
825
- break;
826
- }
827
- }
828
-
829
- if ( newRule && !_.isEmpty( value ) ) {
830
- declarations.push({
831
- property: rule,
832
- value: value,
833
- type: 'declaration',
834
- });
835
- valueChanged = true;
836
- }
837
-
838
- if ( valueChanged ) {
839
- this.updateMainEditor(false);
840
- }
841
- },
842
-
843
- /**
844
- * Adds the @import rule value if it doesn't already exist.
845
- *
846
- * @param newRule
847
- *
848
- */
849
- addImport: function (newRule) {
850
-
851
- // get @import rules
852
- // check if any have the same value
853
- // if not, then add the new @ rule
854
-
855
- var importRules = _.filter( this.parsed.stylesheet.rules, function ( rule) {
856
- return rule.type === 'import';
857
- } );
858
- var exists = _.any( importRules, function ( rule ) {
859
- return rule.import === newRule.import;
860
- } );
861
-
862
- if ( !exists ) {
863
- // Add it to the top!
864
- // @import statements must precede other rule types.
865
- this.parsed.stylesheet.rules.unshift( newRule );
866
- this.updateMainEditor( false );
867
- }
868
-
869
- },
870
-
871
- /**
872
- * Find @import which completely or partially contains the specified value.
873
- *
874
- * @param value
875
- */
876
- findImport: function(value) {
877
- return _.find( this.parsed.stylesheet.rules, function ( rule ) {
878
- return rule.type === 'import' && rule.import.indexOf(value) > -1;
879
- } );
880
- },
881
-
882
- /**
883
- * Find @import which completely or partially contains the identifier value and update it's import property.
884
- *
885
- * @param identifier
886
- * @param value
887
- */
888
- updateImport: function(identifier, value) {
889
- var importRule = this.findImport(identifier);
890
- if ( importRule.import !== value.import ) {
891
- importRule.import = value.import;
892
- this.updateMainEditor(false);
893
- }
894
- },
895
-
896
- /**
897
- * Find @import which completely or partially contains the identifier value and remove it.
898
- *
899
- * @param identifier
900
- */
901
- removeImport: function(identifier) {
902
- var importIndex = _.findIndex( this.parsed.stylesheet.rules, function ( rule ) {
903
- return rule.type === 'import' && rule.import.indexOf(identifier) > -1;
904
- } );
905
- if ( importIndex > -1 ) {
906
- this.parsed.stylesheet.rules.splice(importIndex, 1);
907
- }
908
- },
909
-
910
- /**
911
- * Get the rule value for the active selector
912
- * @param rule
913
- */
914
- getRuleValue: function (rule) {
915
- if (typeof this.activeSelector === 'undefined' || typeof this.activeSelector.declarations === 'undefined') {
916
- return '';
917
- }
918
-
919
- var declarations = this.activeSelector.declarations;
920
- for (var i = 0; i < declarations.length; i++) {
921
- if (declarations[i].property === rule) {
922
- return declarations[i].value;
923
- }
924
- }
925
- return '';
926
- },
927
-
928
- /**
929
- * Update the main editor with the value of the parsed CSS
930
- */
931
- updateMainEditor: function ( compress ) {
932
- //TODO: add back compress option to remove/merge duplicated CSS selectors.
933
- this.editor.codeMirror.setValue( this.parser.stringify( this.parsed ) );
934
- },
935
-
936
- /**
937
- * Show the properties editor
938
- */
939
- show: function () {
940
- this.editorExpandedBefore = this.editor.isExpanded();
941
- this.editor.setExpand(true);
942
-
943
- this.$el.show().animate({'left': 0}, 'fast');
944
- },
945
-
946
- /**
947
- * Hide the properties editor
948
- */
949
- hide: function () {
950
- this.editor.setExpand(this.editorExpandedBefore);
951
- this.$el.animate( {'left': -338}, 'fast', function(){
952
- $(this).hide();
953
- } );
954
-
955
- // Update the main editor with compressed CSS when we close the properties editor
956
- this.updateMainEditor( true );
957
- },
958
-
959
- /**
960
- * @returns boolean
961
- */
962
- isVisible: function () {
963
- return this.$el.is(':visible');
964
- },
965
-
966
- /**
967
- * Loads a single CSS selector and associated properties into the model
968
- * @param css
969
- */
970
- loadCSS: function (css, activeSelector) {
971
- this.css = css;
972
-
973
- // Load the CSS
974
- this.parsed = this.parser.parse(css, {
975
- silent:true
976
- } );
977
- var rules = this.parsed.stylesheet.rules;
978
-
979
- // Add the dropdown menu items
980
- var dropdown = this.$('.toolbar select').empty();
981
- for (var i = 0; i < rules.length; i++) {
982
- var rule = rules[i];
983
-
984
- // Exclude @import statements
985
- if ( ! _.contains( [ 'rule', 'media' ], rule.type) ) {
986
- continue;
987
- }
988
-
989
- if( rule.type === 'media' ) {
990
-
991
- for (var j = 0; j < rule.rules.length; j++) {
992
- var mediaRule = '@media ' + rule.media;
993
- var subRule = rule.rules[j];
994
- if(subRule.type != 'rule') {
995
- continue;
996
- }
997
- dropdown.append(
998
- $('<option>')
999
- .html( mediaRule + ': ' + subRule.selectors.join(',') )
1000
- .attr( 'val', mediaRule + ': ' + subRule.selectors.join(',') )
1001
- .data( 'selector', subRule )
1002
- );
1003
- }
1004
-
1005
- }
1006
- else {
1007
- dropdown.append(
1008
- $('<option>')
1009
- .html( rule.selectors.join(',') )
1010
- .attr( 'val', rule.selectors.join(',') )
1011
- .data( 'selector', rule )
1012
- );
1013
- }
1014
- }
1015
-
1016
- if (typeof activeSelector === 'undefined') {
1017
- activeSelector = dropdown.find('option').eq(0).attr('val');
1018
- }
1019
- if(!_.isEmpty(activeSelector)) {
1020
- dropdown.val(activeSelector).change();
1021
- }
1022
- },
1023
-
1024
- /**
1025
- * Set the selector that we're currently dealing with
1026
- * @param selector
1027
- */
1028
- setActivateSelector: function (selector) {
1029
- this.activeSelector = selector;
1030
- for (var i = 0; i < this.propertyControllers.length; i++) {
1031
- this.propertyControllers[i].refreshFromRule();
1032
- }
1033
- },
1034
-
1035
- /**
1036
- * Add or select a selector.
1037
- *
1038
- * @param selector
1039
- */
1040
- addSelector: function(selector) {
1041
- // Check if this selector already exists
1042
- var dropdown = this.$('.toolbar select');
1043
- dropdown.val( selector );
1044
-
1045
- if( dropdown.val() === selector ) {
1046
- // Trigger a change event to load the existing selector
1047
- dropdown.change();
1048
- }
1049
- else {
1050
- // The selector doesn't exist, so add it to the CSS, then reload
1051
- this.editor.addEmptySelector(selector);
1052
- this.loadCSS( this.editor.codeMirror.getValue().trim(), selector );
1053
- }
1054
-
1055
- dropdown.addClass('highlighted');
1056
- setTimeout(function(){
1057
- dropdown.removeClass('highlighted');
1058
- }, 2000);
1059
- }
1060
-
1061
- });
1062
-
1063
- // The basic property controller
1064
- socss.view.propertyController = Backbone.View.extend({
1065
-
1066
- template: _.template('<input type="text" value="" />'),
1067
- activeRule: null,
1068
- args: null,
1069
- propertiesView: null,
1070
-
1071
- initialize: function (args) {
1072
-
1073
- this.args = args.args;
1074
- this.propertiesView = args.propertiesView;
1075
-
1076
- // By default, update the active rule whenever things change
1077
- this.on('set_value', this.updateRule, this);
1078
- this.on('change', this.updateRule, this);
1079
- },
1080
-
1081
- /**
1082
- * Render the property field controller
1083
- */
1084
- render: function () {
1085
- this.$el.append( $(this.template( {} )) );
1086
- this.field = this.$('input');
1087
- },
1088
-
1089
- /**
1090
- * Initialize the events that constitute a change
1091
- */
1092
- initChangeEvents: function () {
1093
- var thisView = this;
1094
- this.field.on( 'change keyup', function () {
1095
- thisView.trigger('change', $(this).val());
1096
- } );
1097
- },
1098
-
1099
-
1100
- /**
1101
- * Update the value of an active rule
1102
- */
1103
- updateRule: function () {
1104
- this.propertiesView.setRuleValue(
1105
- this.args.property,
1106
- this.getValue()
1107
- );
1108
- },
1109
-
1110
- /**
1111
- * This is called when the selector changes
1112
- */
1113
- refreshFromRule: function () {
1114
- var value = this.propertiesView.getRuleValue(this.args.property);
1115
- this.setValue(value, {silent: true});
1116
- },
1117
-
1118
- /**
1119
- * Get the current value
1120
- * @return string
1121
- */
1122
- getValue: function () {
1123
- return this.field.val();
1124
- },
1125
-
1126
- /**
1127
- * Set the current value
1128
- * @param socss.view.properties val
1129
- */
1130
- setValue: function (val, options) {
1131
- options = _.extend({silent: false}, options);
1132
-
1133
- this.field.val(val);
1134
-
1135
- if (!options.silent) {
1136
- this.trigger('set_value', val);
1137
- }
1138
- },
1139
-
1140
- /**
1141
- * Reset the current value
1142
- */
1143
- reset: function (options) {
1144
- options = _.extend({silent: false}, options);
1145
-
1146
- this.setValue('', options);
1147
- }
1148
-
1149
- });
1150
-
1151
- // All the value controllers
1152
- socss.view.properties.controllers = {};
1153
-
1154
- // The color controller
1155
- socss.view.properties.controllers.color = socss.view.propertyController.extend({
1156
-
1157
- template: _.template('<input type="text" value="" />'),
1158
-
1159
- render: function () {
1160
- var thisView = this;
1161
-
1162
- this.$el.append($(this.template({})));
1163
-
1164
- // Set this up as a color picker
1165
- this.field = this.$el.find('input');
1166
- this.field.minicolors({});
1167
-
1168
- },
1169
-
1170
- initChangeEvents: function () {
1171
- var thisView = this;
1172
- this.field.on('change keyup', function () {
1173
- thisView.trigger('change', thisView.field.minicolors('value'));
1174
- });
1175
- },
1176
-
1177
- getValue: function () {
1178
- return this.field.minicolors('value').trim();
1179
- },
1180
-
1181
- setValue: function (val, options) {
1182
- options = _.extend({silent: false}, options);
1183
-
1184
- this.field.minicolors('value', val);
1185
-
1186
- if (!options.silent) {
1187
- this.trigger('set_value', val);
1188
- }
1189
- }
1190
-
1191
- });
1192
-
1193
- // The dropdown select box controller
1194
- socss.view.properties.controllers.select = socss.view.propertyController.extend( {
1195
- template: _.template('<select></select>'),
1196
-
1197
- render: function(){
1198
- var thisView = this;
1199
-
1200
- this.$el.append($(this.template({})));
1201
- this.field = this.$el.find('select');
1202
-
1203
- // Add the unchanged option
1204
- this.field.append( $('<option value=""></option>').html('') );
1205
-
1206
- // Add all the options to the dropdown
1207
- for( var k in this.args.options ) {
1208
- this.field.append( $('<option></option>').attr('value', k).html( this.args.options[k] ) );
1209
- }
1210
-
1211
- if( typeof this.args.option_icons !== 'undefined' ) {
1212
- this.setupVisualSelect();
1213
- }
1214
- },
1215
-
1216
- setupVisualSelect: function(){
1217
- var thisView = this;
1218
- this.field.hide();
1219
-
1220
- var $tc = $('<div class="select-tabs"></div>').appendTo( this.$el );
1221
-
1222
- // Add the none value
1223
- $('<div class="select-tab" data-value=""><span class="fa fa-circle-o"></span></div>').appendTo($tc);
1224
-
1225
- // Now add one for each of the option icons
1226
- for ( var k in this.args.option_icons ) {
1227
- $('<div class="select-tab"></div>')
1228
- .appendTo($tc)
1229
- .append(
1230
- $('<span class="fa"></span>')
1231
- .addClass('fa-' + this.args.option_icons[k])
1232
- )
1233
- .attr('data-value', k)
1234
- ;
1235
- }
1236
-
1237
- $tc.find('.select-tab')
1238
- .css('width', 100/( $tc.find('>div').length ) + "%" )
1239
- .click( function(){
1240
- var $t = $(this);
1241
- $tc.find('.select-tab').removeClass('active');
1242
- $t.addClass('active');
1243
- thisView.field.val( $t.data('value')).change();
1244
- } );
1245
- },
1246
-
1247
- /**
1248
- * Set the current value
1249
- * @param socss.view.properties val
1250
- */
1251
- setValue: function (val, options) {
1252
- options = _.extend({silent: false}, options);
1253
-
1254
- this.field.val(val);
1255
-
1256
- this.$('.select-tabs .select-tab').removeClass('active').filter('[data-value="' + val + '"]').addClass('active');
1257
-
1258
- if (!options.silent) {
1259
- this.trigger('set_value', val);
1260
- }
1261
- }
1262
-
1263
- } );
1264
-
1265
- // A field that lets a user upload an image
1266
- socss.view.properties.controllers.image = socss.view.propertyController.extend( {
1267
- template: _.template('<input type="text" value="" /> <span class="select socss-button"><span class="fa fa-upload"></span></span>'),
1268
-
1269
- render: function(){
1270
- var thisView = this;
1271
-
1272
- this.media = wp.media({
1273
- // Set the title of the modal.
1274
- title: socssOptions.loc.select_image,
1275
-
1276
- // Tell the modal to show only images.
1277
- library: {
1278
- type: 'image'
1279
- },
1280
-
1281
- // Customize the submit button.
1282
- button: {
1283
- // Set the text of the button.
1284
- text: socssOptions.loc.select,
1285
- // Tell the button not to close the modal, since we're
1286
- // going to refresh the page when the image is selected.
1287
- close: false
1288
- }
1289
- });
1290
-
1291
- this.$el.append( $(this.template({
1292
- select: socssOptions.loc.select
1293
- })) );
1294
-
1295
- this.field = this.$el.find('input');
1296
-
1297
- this.$('.select').click(function(){
1298
- thisView.media.open();
1299
- });
1300
-
1301
- this.media.on('select', function(){
1302
- // Grab the selected attachment.
1303
- var attachment = this.state().get('selection').first().attributes;
1304
- var val = thisView.args.value.replace('{{url}}', attachment.url);
1305
-
1306
- // Change the field value and trigger a change event
1307
- thisView.field.val( val ).change();
1308
-
1309
- // Close the image selector
1310
- thisView.media.close();
1311
-
1312
- }, this.media);
1313
- }
1314
-
1315
- } );
1316
-
1317
- // A simple measurement field
1318
- socss.view.properties.controllers.measurement = socss.view.propertyController.extend( {
1319
-
1320
- wrapperClass: 'socss-field-measurement',
1321
-
1322
- render: function(){
1323
- this.$el.append($(this.template({})));
1324
- this.field = this.$('input');
1325
- this.setupMeasurementField( this.field, {} );
1326
- },
1327
-
1328
- setValue: function (val, options) {
1329
- options = _.extend({silent: false}, options);
1330
- this.field.val(val).trigger('measurement_refresh');
1331
- if (!options.silent) {
1332
- this.trigger('set_value', val);
1333
- }
1334
- },
1335
-
1336
- units : [
1337
- 'px',
1338
- '%',
1339
- 'em',
1340
- 'cm',
1341
- 'mm',
1342
- 'in',
1343
- 'pt',
1344
- 'pc',
1345
- 'ex',
1346
- 'ch',
1347
- 'rem',
1348
- 'vw',
1349
- 'vh',
1350
- 'vmin',
1351
- 'vmax'
1352
- ],
1353
-
1354
- parseUnits: function( value ){
1355
- var escapeRegExp = function(str) {
1356
- return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
1357
- };
1358
-
1359
- var regexUnits = this.units.map(escapeRegExp);
1360
- var regex = new RegExp('([0-9\\.\\-]+)(' + regexUnits.join('|') + ')?', 'i');
1361
- var result = regex.exec( value );
1362
-
1363
- if( result === null ) {
1364
- return {
1365
- value: '',
1366
- unit: ''
1367
- };
1368
- }
1369
- else {
1370
- return {
1371
- value: result[1],
1372
- unit: result[2] === undefined ? '' : result[2]
1373
- };
1374
- }
1375
- },
1376
-
1377
- setupMeasurementField: function( $el, options ){
1378
- var thisView = this;
1379
- var $p = $el.parent();
1380
-
1381
- options = _.extend( {
1382
- defaultUnit: 'px'
1383
- }, options );
1384
-
1385
- $el.hide();
1386
- $p.addClass( this.wrapperClass ).data('unit', options.defaultUnit);
1387
-
1388
- // Create the fake input field
1389
- var $fi = $('<input type="text" class="socss-field-input"/>').appendTo($p);
1390
- var $da = $('<span class="dashicons dashicons-arrow-down"></span>').appendTo($p);
1391
- var $dd = $('<ul class="dropdown"></ul>').appendTo($p);
1392
- var $u = $('<span class="units"></span>').html( options.defaultUnit ).appendTo( $p );
1393
-
1394
- for( var i = 0; i < thisView.units.length; i++ ) {
1395
- var $o = $('<li></li>').html( thisView.units[i] ).data('unit', thisView.units[i]);
1396
- if( thisView.units[i] === options.defaultUnit ) {
1397
- $o.addClass('active');
1398
- }
1399
- $dd.append( $o );
1400
- }
1401
-
1402
- var updateValue = function(){
1403
- var value = thisView.parseUnits( $fi.val() );
1404
-
1405
- if( value.unit !== '' && value.unit !== $p.data( 'unit' ) ) {
1406
- $fi.val( value.value );
1407
- setUnit( value.unit );
1408
- }
1409
-
1410
- if( value.value === '' ) {
1411
- $el.val( '' );
1412
- }
1413
- else {
1414
- $el.val( value.value + $p.data( 'unit' ) );
1415
- }
1416
- };
1417
-
1418
- var setUnit = function( unit ){
1419
- $u.html( unit );
1420
- $p.data( 'unit', unit );
1421
- $fi.trigger('keydown');
1422
- };
1423
-
1424
- $da.click( function(){
1425
- $dd.toggle();
1426
- } );
1427
-
1428
- $dd.find('li').click( function(){
1429
- $dd.toggle();
1430
- setUnit( $(this).data('unit') );
1431
- updateValue();
1432
- $el.trigger('change');
1433
- } );
1434
-
1435
- $fi.on( 'keyup keydown', function(e){
1436
- var $$ = $(this);
1437
-
1438
- var char = '';
1439
- if( e.type === 'keydown' ) {
1440
- if(e.keyCode >= 48 && e.keyCode <= 57 ) {
1441
- char = String.fromCharCode(e.keyCode);
1442
- }
1443
- else if( e.keyCode === 189 ) {
1444
- char = '-';
1445
- }
1446
- else if( e.keyCode === 190 ) {
1447
- char = '.';
1448
- }
1449
- }
1450
-
1451
- var $pl = $('<span class="socss-hidden-placeholder"></span>')
1452
- .css( {
1453
- 'font-size' : '14px'
1454
- } )
1455
- .html( $fi.val() + char )
1456
- .appendTo( 'body' );
1457
- var width = $pl.width();
1458
- width = Math.min(width, 63);
1459
- $pl.remove();
1460
-
1461
- $u.css('left', width + 12);
1462
- } );
1463
-
1464
- $fi.on('keyup', function(e){
1465
- updateValue();
1466
- $el.trigger('change');
1467
- } );
1468
-
1469
- $el.on('measurement_refresh', function(){
1470
- var value = thisView.parseUnits( $el.val() );
1471
- $fi.val( value.value );
1472
-
1473
- var unit = value.unit === '' ? options.defaultUnit : value.unit;
1474
- $p.data( 'unit', unit );
1475
- $u.html( unit );
1476
-
1477
- var $pl = $('<span class="socss-hidden-placeholder"></span>')
1478
- .css({
1479
- 'font-size' : '14px'
1480
- })
1481
- .html( value.value )
1482
- .appendTo( 'body' );
1483
- var width = $pl.width();
1484
- width = Math.min(width, 63);
1485
- $pl.remove();
1486
-
1487
- $u.css('left', width + 12);
1488
- } );
1489
-
1490
- // Now add the increment/decrement buttons
1491
- var $diw = $('<div class="socss-diw"></div>').appendTo($p);
1492
- var $dec = $('<div class="dec-button socss-button"><span class="fa fa-minus"></span></div>').appendTo($diw);
1493
- var $inc = $('<div class="inc-button socss-button"><span class="fa fa-plus"></span></div>').appendTo($diw);
1494
-
1495
- var stepValue = function( direction ) {
1496
- var value = Number.parseInt( thisView.parseUnits( $el.val() ).value );
1497
-
1498
- if( Number.isNaN( value ) ) {
1499
- value = 0;
1500
- }
1501
-
1502
- var newVal = value + direction;
1503
-
1504
- $fi.val( newVal );
1505
- updateValue();
1506
- $el.trigger('change').trigger('measurement_refresh');
1507
- };
1508
-
1509
- var setupStepButton = function ( $button ) {
1510
- var direction = $button.is( '.dec-button' ) ? -1 : 1;
1511
- var intervalId;
1512
- var timeoutId;
1513
- $button.mousedown( function(){
1514
- stepValue( direction );
1515
- timeoutId = setTimeout( function () {
1516
- intervalId = setInterval( function () {
1517
- stepValue( direction );
1518
- }, 50 );
1519
- }, 500 );
1520
- } ).on( 'mouseup mouseout', function(){
1521
- if ( timeoutId ) {
1522
- clearTimeout( timeoutId );
1523
- timeoutId = null;
1524
- }
1525
- if ( intervalId ) {
1526
- clearInterval( intervalId );
1527
- intervalId = null;
1528
- }
1529
- } );
1530
- };
1531
-
1532
- setupStepButton( $dec );
1533
- setupStepButton( $inc );
1534
-
1535
- }
1536
-
1537
- } );
1538
-
1539
- // A simple measurement field
1540
- socss.view.properties.controllers.number = socss.view.propertyController.extend( {
1541
-
1542
- render: function(){
1543
- this.$el.append($(this.template({})));
1544
- this.field = this.$('input');
1545
-
1546
- // Setup the measurement field
1547
- this.setupNumberField(this.field, this.args);
1548
- },
1549
-
1550
- /**
1551
- * Setup the number field
1552
- * @param el
1553
- * @param options
1554
- */
1555
- setupNumberField: function($el, options){
1556
- options = _.extend({
1557
- change: null,
1558
- default: 0,
1559
- increment: 1,
1560
- decrement: -1,
1561
- max: null,
1562
- min: null
1563
- }, options);
1564
-
1565
- var $p = $el.parent();
1566
- $p.addClass('socss-field-number');
1567
-
1568
- // Now add the increment/decrement buttons
1569
- var $diw = $('<div class="socss-diw"></div>').appendTo($p);
1570
- var $dec = $('<div class="dec-button socss-button">-</div>').appendTo($diw);
1571
- var $inc = $('<div class="inc-button socss-button">+</div>').appendTo($diw);
1572
-
1573
- // Increment is clicked
1574
- $diw.find('> div').click( function(e){
1575
- e.preventDefault();
1576
-
1577
- var val = options.default;
1578
- if( $el.val() !== '' ) {
1579
- val = Number($el.val());
1580
- }
1581
- val = val + ( $(this).is( $dec ) ? options.decrement : options.increment );
1582
-
1583
- val = Math.round(val*100)/100;
1584
-
1585
- if( options.max !== null ) {
1586
- val = Math.min( options.max, val);
1587
- }
1588
-
1589
- if( options.min !== null ) {
1590
- val = Math.max( options.min, val);
1591
- }
1592
-
1593
- $el.val( val );
1594
- $el.trigger('change');
1595
- } );
1596
-
1597
- return this;
1598
- }
1599
-
1600
- } );
1601
-
1602
-
1603
- socss.view.properties.controllers.sides = socss.view.propertyController.extend( {
1604
-
1605
- template: _.template( $('#template-sides-field').html().trim() ),
1606
-
1607
- controllers: [],
1608
-
1609
- render: function(){
1610
- var thisView = this;
1611
-
1612
- this.$el.append( $(this.template({})) );
1613
- this.field = this.$el.find('input');
1614
-
1615
- if( !thisView.args.hasAll ) {
1616
- this.$('.select-tab').eq(0).remove();
1617
- this.$('.select-tab').css('width', '25%');
1618
- }
1619
-
1620
- this.$('.select-tab').each( function(){
1621
- var dir = $(this).data('direction');
1622
-
1623
- var container = $('<li class="side">')
1624
- .appendTo( thisView.$('.sides') )
1625
- .hide();
1626
-
1627
- for( var i = 0; i < thisView.args.controllers.length; i++ ) {
1628
-
1629
- var controllerArgs = thisView.args.controllers[i];
1630
-
1631
- if( typeof socss.view.properties.controllers[ controllerArgs.type ] ) {
1632
-
1633
- // Create the measurement view
1634
- var property = '';
1635
- if( dir === 'all' ) {
1636
- property = controllerArgs.args.propertyAll;
1637
- }
1638
- else {
1639
- property = controllerArgs.args.property.replace('{dir}', dir);
1640
- }
1641
-
1642
- var theseControllerArgs = _.extend({}, controllerArgs.args, {property: property});
1643
-
1644
- var controller = new socss.view.properties.controllers[ controllerArgs.type ]( {
1645
- el: $('<div>').appendTo( container ),
1646
- propertiesView: thisView.propertiesView,
1647
- args: theseControllerArgs
1648
- } );
1649
-
1650
- // Setup and render the measurement controller and register it with the properties view
1651
- controller.render();
1652
- controller.initChangeEvents();
1653
- thisView.propertiesView.propertyControllers.push(controller);
1654
-
1655
- }
1656
-
1657
- }
1658
-
1659
- $(this).on( 'click', function(){
1660
- thisView.$('.select-tab').removeClass('active');
1661
- $(this).addClass('active');
1662
-
1663
- thisView.$('.sides .side').hide();
1664
- container.show();
1665
- } );
1666
-
1667
- } );
1668
-
1669
- // Select the first tab by default
1670
- this.$('.select-tab').eq(0).click();
1671
- }
1672
-
1673
- } );
1674
-
1675
- })(jQuery, _, socssOptions);
1676
-
1677
- // Setup the main editor
1678
- jQuery(function ($) {
1679
- var socss = window.socss;
1680
-
1681
- // Setup the editor
1682
- var editor = new socss.view.editor({
1683
- el: $('#so-custom-css-form').get(0)
1684
- });
1685
- editor.render();
1686
- editor.setSnippets(socssOptions.snippets);
1687
-
1688
- window.socss.mainEditor = editor;
1689
-
1690
- // This is for hiding the getting started video
1691
- $('#so-custom-css-getting-started a.hide').click( function(e){
1692
- e.preventDefault();
1693
- $('#so-custom-css-getting-started').slideUp();
1694
- $.get( $(this).attr('href') );
1695
- } );
1696
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* globals jQuery, _, socssOptions, Backbone, CodeMirror, console, cssjs, wp */
2
+
3
+ ( function ( $, _, socssOptions ) {
4
+
5
+ var socss = {
6
+ model: {},
7
+ collection: {},
8
+ view: {},
9
+ fn: {}
10
+ };
11
+
12
+ window.socss = socss;
13
+
14
+ socss.model.CustomCssModel = Backbone.Model.extend( {
15
+ defaults: {
16
+ postId: null,
17
+ postTitle: null,
18
+ css: null,
19
+ },
20
+
21
+ urlRoot: socssOptions.postCssUrlRoot,
22
+
23
+ url: function () {
24
+ return this.urlRoot + '&postId=' + this.get( 'postId' );
25
+ }
26
+ } );
27
+
28
+ socss.model.CustomCssCollection = Backbone.Collection.extend( {
29
+ model: socss.model.CustomCssModel,
30
+
31
+ modelId: function( attrs ) {
32
+ return attrs.postId;
33
+ },
34
+ } );
35
+
36
+ socss.model.CSSEditorModel = Backbone.Model.extend( {
37
+ defaults: {
38
+ customCssPosts: null,
39
+ }
40
+ } );
41
+
42
+ /**
43
+ * The toolbar view
44
+ */
45
+ socss.view.toolbar = Backbone.View.extend( {
46
+
47
+ button: _.template( '<li><a href="#<%= action %>" class="toolbar-button socss-button"><%= text %></a></li>' ),
48
+
49
+ events: {
50
+ 'click .socss-button': 'triggerEvent',
51
+ },
52
+
53
+ triggerEvent: function ( event ) {
54
+ event.preventDefault();
55
+ var $target = $( event.currentTarget );
56
+ $target.blur();
57
+ var value = $target.attr( 'href' ).replace( '#', '' );
58
+ this.$el.trigger( 'click_' + value );
59
+ },
60
+
61
+ addButton: function ( text, action ) {
62
+ var button = $( this.button( { text: text, action: action } ) )
63
+ .appendTo( this.$( '.toolbar-function-buttons .toolbar-buttons' ) );
64
+
65
+ return button;
66
+ },
67
+ } );
68
+
69
+ /**
70
+ * The editor view, which handles codemirror stuff
71
+ *
72
+ * model: socss.model.CSSEditorModel
73
+ *
74
+ */
75
+ socss.view.editor = Backbone.View.extend( {
76
+
77
+ codeMirror: null,
78
+ snippets: null,
79
+ toolbar: null,
80
+ visualProperties: null,
81
+
82
+ inspector: null,
83
+
84
+ cssSelectors: [],
85
+
86
+ initValue: null,
87
+
88
+ events: {
89
+ 'click_expand .custom-css-toolbar': 'toggleExpand',
90
+ 'click_visual .custom-css-toolbar': 'showVisualEditor',
91
+ 'submit': 'onSubmit',
92
+ },
93
+
94
+ initialize: function ( options ) {
95
+
96
+ this.listenTo( this.model, 'change:selectedPost', this.getSelectedPostCss );
97
+
98
+ this.getSelectedPostCss().then( function () {
99
+
100
+ if ( options.openVisualEditor ) {
101
+ this.showVisualEditor();
102
+ }
103
+ }.bind( this ) );
104
+
105
+ },
106
+
107
+ getSelectedPostCss: function () {
108
+ var selectedPost = this.model.get( 'selectedPost' );
109
+ var promise;
110
+ if ( selectedPost && ! selectedPost.has( 'css' ) ) {
111
+ promise = selectedPost.fetch();
112
+ } else {
113
+ promise = new $.Deferred().resolve();
114
+ }
115
+
116
+ return promise.then( this.render.bind( this ) );
117
+ },
118
+
119
+ render: function () {
120
+
121
+ var selectedPost = this.model.get( 'selectedPost' );
122
+
123
+ if ( selectedPost && !selectedPost.has( 'css' ) ) {
124
+ return this;
125
+ }
126
+
127
+ if ( !this.codeMirror ) {
128
+ this.setupEditor();
129
+ }
130
+
131
+ if ( ! this.toolbar ) {
132
+ this.toolbar = new socss.view.toolbar( {
133
+ el: this.$( '.custom-css-toolbar' ),
134
+ model: this.model,
135
+ } );
136
+ this.toolbar.render();
137
+ }
138
+
139
+ if ( !this.visualProperties ) {
140
+ this.visualProperties = new socss.view.properties( {
141
+ editor: this,
142
+ el: $( '#so-custom-css-properties' )
143
+ } );
144
+ this.visualProperties.render();
145
+ }
146
+
147
+ if ( !this.preview ) {
148
+ this.preview = new socss.view.preview( {
149
+ editor: this,
150
+ model: this.model,
151
+ el: this.$( '.custom-css-preview' ),
152
+ initURL: socssOptions.homeURL,
153
+ } );
154
+ this.preview.render();
155
+ }
156
+
157
+ if ( selectedPost ) {
158
+ this.codeMirror.setValue( selectedPost.get( 'css' ) );
159
+ this.codeMirror.clearHistory();
160
+ }
161
+
162
+ return this;
163
+ },
164
+
165
+ /**
166
+ * Do the initial setup of the CodeMirror editor
167
+ */
168
+ setupEditor: function () {
169
+ this.registerCodeMirrorAutocomplete();
170
+
171
+ // Setup the Codemirror instance
172
+ var $textArea = this.$( 'textarea.css-editor' );
173
+ this.initValue = $textArea.val();
174
+ // Pad with empty lines so the editor takes up all the white space. To try make sure user gets copy/paste
175
+ // options in context menu.
176
+ var newlineMatches = this.initValue.match( /\n/gm );
177
+ var lineCount = newlineMatches ? newlineMatches.length + 1 : 1;
178
+ var paddedValue = this.initValue;
179
+ $textArea.val( paddedValue );
180
+ this.codeMirror = CodeMirror.fromTextArea( $textArea.get( 0 ), {
181
+ tabSize: 2,
182
+ lineNumbers: true,
183
+ mode: 'css',
184
+ theme: 'neat',
185
+ inputStyle: 'contenteditable', //necessary to allow context menu (right click) copy/paste etc.
186
+ gutters: [
187
+ "CodeMirror-lint-markers"
188
+ ],
189
+ lint: true,
190
+ search: true,
191
+ dialog: true,
192
+ annotateScrollbar: true,
193
+ extraKeys: {
194
+ 'Ctrl-F': 'findPersistent',
195
+ 'Alt-G': 'jumpToLine',
196
+ }
197
+ } );
198
+
199
+ this.codeMirror.on( 'change', function ( cm, change ) {
200
+ var selectedPost = this.model.get( 'selectedPost' );
201
+ if ( selectedPost && selectedPost.get( 'css' ) !== cm.getValue().trim() ) {
202
+ selectedPost.set( 'css', cm.getValue().trim() );
203
+ }
204
+ }.bind( this ) );
205
+
206
+ // Make sure the user doesn't leave without saving
207
+ $( window ).on( 'beforeunload', function () {
208
+ var editorValue = this.codeMirror.getValue().trim();
209
+ if ( editorValue !== this.initValue ) {
210
+ return socssOptions.loc.leave;
211
+ }
212
+ }.bind( this ) );
213
+
214
+
215
+ // Set the container to visible overflow once the editor is setup
216
+ this.$el.find( '.custom-css-container' ).css( 'overflow', 'visible' );
217
+ this.scaleEditor();
218
+
219
+ // Scale the editor whenever the window is resized
220
+ $( window ).on( 'resize', function () {
221
+ this.scaleEditor();
222
+ }.bind( this ) );
223
+
224
+ // Setup the extensions
225
+ this.setupCodeMirrorExtensions();
226
+ },
227
+
228
+ onSubmit: function () {
229
+ this.initValue = this.codeMirror.getValue().trim();
230
+ },
231
+
232
+ /**
233
+ * Register the autocomplete helper. Based on css-hint.js in the codemirror addon folder.
234
+ */
235
+ registerCodeMirrorAutocomplete: function () {
236
+ var pseudoClasses = {
237
+ link: 1, visited: 1, active: 1, hover: 1, focus: 1,
238
+ "first-letter": 1, "first-line": 1, "first-child": 1,
239
+ before: 1, after: 1, lang: 1
240
+ };
241
+
242
+ CodeMirror.registerHelper( "hint", "css", function ( cm ) {
243
+ var cur = cm.getCursor(), token = cm.getTokenAt( cur );
244
+ var inner = CodeMirror.innerMode( cm.getMode(), token.state );
245
+ if ( inner.mode.name !== "css" ) {
246
+ return;
247
+ }
248
+
249
+ if ( token.type === "keyword" && "!important".indexOf( token.string ) === 0 ) {
250
+ return {
251
+ list: [ "!important" ], from: CodeMirror.Pos( cur.line, token.start ),
252
+ to: CodeMirror.Pos( cur.line, token.end )
253
+ };
254
+ }
255
+
256
+ var start = token.start, end = cur.ch, word = token.string.slice( 0, end - start );
257
+ if ( /[^\w$_-]/.test( word ) ) {
258
+ word = "";
259
+ start = end = cur.ch;
260
+ }
261
+
262
+ var spec = CodeMirror.resolveMode( "text/css" );
263
+
264
+ var result = [];
265
+
266
+ function add( keywords ) {
267
+ for ( var name in keywords ) {
268
+ if ( !word || name.lastIndexOf( word, 0 ) === 0 ) {
269
+ result.push( name );
270
+ }
271
+ }
272
+ }
273
+
274
+ var st = inner.state.state;
275
+
276
+ if ( st === 'top' ) {
277
+ // We're going to autocomplete the selector using our own set of rules
278
+ var line = cm.getLine( cur.line ).trim();
279
+
280
+ var selectors = this.cssSelectors;
281
+ for ( var i = 0; i < selectors.length; i++ ) {
282
+ if ( selectors[ i ].selector.indexOf( line ) !== -1 ) {
283
+ result.push( selectors[ i ].selector );
284
+ }
285
+ }
286
+
287
+ if ( result.length ) {
288
+ return {
289
+ list: result,
290
+ from: CodeMirror.Pos( cur.line, 0 ),
291
+ to: CodeMirror.Pos( cur.line, end )
292
+ };
293
+ }
294
+ }
295
+ else {
296
+
297
+ if ( st === "pseudo" || token.type === "variable-3" ) {
298
+ add( pseudoClasses );
299
+ }
300
+ else if ( st === "block" || st === "maybeprop" ) {
301
+ add( spec.propertyKeywords );
302
+ }
303
+ else if ( st === "prop" || st === "parens" || st === "at" || st === "params" ) {
304
+ add( spec.valueKeywords );
305
+ add( spec.colorKeywords );
306
+ }
307
+ else if ( st === "media" || st === "media_parens" ) {
308
+ add( spec.mediaTypes );
309
+ add( spec.mediaFeatures );
310
+ }
311
+
312
+ if ( result.length ) {
313
+ return {
314
+ list: result,
315
+ from: CodeMirror.Pos( cur.line, start ),
316
+ to: CodeMirror.Pos( cur.line, end )
317
+ };
318
+ }
319
+
320
+ }
321
+
322
+ }.bind( this ) );
323
+ },
324
+
325
+ setupCodeMirrorExtensions: function () {
326
+
327
+ this.codeMirror.on( 'cursorActivity', function ( cm ) {
328
+ var cur = cm.getCursor(), token = cm.getTokenAt( cur );
329
+ var inner = CodeMirror.innerMode( cm.getMode(), token.state );
330
+
331
+ // If we have a qualifier selected, then highlight that in the preview
332
+ if ( token.type === 'qualifier' || token.type === 'tag' || token.type === 'builtin' ) {
333
+ var line = cm.getLine( cur.line );
334
+ var selector = line.substring( 0, token.end );
335
+
336
+ this.preview.highlight( selector );
337
+ }
338
+ else {
339
+ this.preview.clearHighlight();
340
+ }
341
+ }.bind( this ) );
342
+
343
+ // This sets up automatic autocompletion at all times
344
+ this.codeMirror.on( 'keyup', function ( cm, e ) {
345
+ if (
346
+ ( e.keyCode >= 65 && e.keyCode <= 90 ) ||
347
+ ( e.keyCode === 189 && !e.shiftKey ) ||
348
+ ( e.keyCode === 190 && !e.shiftKey ) ||
349
+ ( e.keyCode === 51 && e.shiftKey ) ||
350
+ ( e.keyCode === 189 && e.shiftKey )
351
+ ) {
352
+ cm.showHint( {
353
+ completeSingle: false
354
+ } );
355
+ }
356
+ } );
357
+ },
358
+
359
+ /**
360
+ * Scale the size of the editor depending on whether it's expanded or not
361
+ */
362
+ scaleEditor: function () {
363
+ var windowHeight = $( window ).outerHeight();
364
+ if ( this.$el.hasClass( 'expanded' ) ) {
365
+ // If we're in the expanded view, then resize the editor
366
+ this.$el.find( '.CodeMirror-scroll' ).css( 'max-height', '' );
367
+ this.codeMirror.setSize( '100%', windowHeight - this.$( '.custom-css-toolbar' ).outerHeight() );
368
+ }
369
+ else {
370
+ // Attempt to calculate approximate space available for editor when not expanded.
371
+ var $form = $( '#so-custom-css-form' );
372
+ var otherEltsHeight = $( '#wpadminbar' ).outerHeight( true ) +
373
+ $( '#siteorigin-custom-css' ).find( '> h2' ).outerHeight( true ) +
374
+ $form.find( '> .custom-css-toolbar' ).outerHeight( true ) +
375
+ $form.find( '> p.description' ).outerHeight( true ) +
376
+ $form.find( '> p.submit' ).outerHeight( true ) +
377
+ parseFloat( $( '#wpbody-content' ).css( 'padding-bottom' ) );
378
+ this.$el.find( '.CodeMirror-scroll' ).css( 'max-height', windowHeight - otherEltsHeight );
379
+ this.codeMirror.setSize( '100%', 'auto' );
380
+ }
381
+ },
382
+
383
+ /**
384
+ * Check if the editor is in expanded mode
385
+ * @returns bool
386
+ */
387
+ isExpanded: function () {
388
+ return this.$el.hasClass( 'expanded' );
389
+ },
390
+
391
+ /**
392
+ * Toggle if this is expanded or not
393
+ */
394
+ toggleExpand: function () {
395
+ this.$el.toggleClass( 'expanded' );
396
+ this.scaleEditor();
397
+ },
398
+
399
+ /**
400
+ * Set the expanded state of the editor
401
+ * @param expanded
402
+ */
403
+ setExpand: function ( expanded ) {
404
+ if ( expanded ) {
405
+ this.$el.addClass( 'expanded' );
406
+ }
407
+ else {
408
+ this.$el.removeClass( 'expanded' );
409
+ }
410
+ this.scaleEditor();
411
+ },
412
+
413
+ /**
414
+ * Show the visual editor view.
415
+ */
416
+ showVisualEditor: function () {
417
+ this.visualProperties.loadCSS( this.codeMirror.getValue().trim() );
418
+ this.visualProperties.show();
419
+ },
420
+
421
+ /**
422
+ * Set the snippets available to this editor
423
+ */
424
+ setSnippets: function ( snippets ) {
425
+ if ( !_.isEmpty( snippets ) ) {
426
+
427
+ this.snippets = new socss.view.snippets( {
428
+ snippets: snippets
429
+ } );
430
+ this.snippets.editor = this;
431
+
432
+ this.snippets.render();
433
+ this.toolbar.addButton( 'Snippets', 'snippets' );
434
+ this.toolbar.on( 'click_snippets', function () {
435
+ this.snippets.show();
436
+ }.bind( this ) );
437
+ }
438
+ },
439
+
440
+ /**
441
+ * Add some CSS to the editor.
442
+ * @param css
443
+ */
444
+ addCode: function ( css ) {
445
+ var editor = this.codeMirror;
446
+
447
+ var before_css = '';
448
+ if ( editor.doc.lineCount() === 1 && editor.doc.getLine( editor.doc.lastLine() ).length === 0 ) {
449
+ before_css = "";
450
+ }
451
+ else if ( editor.doc.getLine( editor.doc.lastLine() ).length === 0 ) {
452
+ before_css = "\n";
453
+ }
454
+ else {
455
+ before_css = "\n\n";
456
+ }
457
+
458
+ // Now insert the code in the editor
459
+ editor.doc.setCursor(
460
+ editor.doc.lastLine(),
461
+ editor.doc.getLine( editor.doc.lastLine() ).length
462
+ );
463
+ editor.doc.replaceSelection( before_css + css );
464
+ },
465
+
466
+ addEmptySelector: function ( selector ) {
467
+ this.addCode( selector + " {\n \n}" );
468
+ },
469
+
470
+ /**
471
+ * Sets the inspector view that's being used by the editor
472
+ */
473
+ setInspector: function ( inspector ) {
474
+ this.inspector = inspector;
475
+ this.cssSelectors = inspector.pageSelectors;
476
+
477
+ // A selector is clicked in the inspector
478
+ inspector.on( 'click_selector', function ( selector ) {
479
+ if ( this.visualProperties.isVisible() ) {
480
+ this.visualProperties.addSelector( selector );
481
+ }
482
+ else {
483
+ this.addEmptySelector( selector );
484
+ }
485
+ }.bind( this ) );
486
+
487
+ // A property is clicked in the inspector
488
+ inspector.on( 'click_property', function ( property ) {
489
+ if ( !this.visualProperties.isVisible() ) {
490
+ this.codeMirror.replaceSelection( property + ";\n " );
491
+ }
492
+ }.bind( this ) );
493
+
494
+ inspector.on( 'set_active_element', function ( el, selectors ) {
495
+ if ( this.visualProperties.isVisible() && selectors.length ) {
496
+ this.visualProperties.addSelector( selectors[ 0 ].selector );
497
+ }
498
+ }.bind( this ) );
499
+ }
500
+
501
+ } );
502
+
503
+ /**
504
+ * The preview.
505
+ */
506
+ socss.view.preview = Backbone.View.extend( {
507
+
508
+ template: _.template( $( '#template-preview-window' ).html() ),
509
+ editor: null,
510
+ originalUri: null,
511
+ currentUri: null,
512
+
513
+ events: {
514
+ 'load #preview-iframe': 'initPreview',
515
+ 'mouseleave #preview-iframe': 'clearHighlight',
516
+ 'keydown #preview-navigator input[type="text"]': 'reloadPreview',
517
+ },
518
+
519
+ initialize: function ( attr ) {
520
+ this.editor = attr.editor;
521
+
522
+ this.listenTo( this.model, 'change:selectedPost', this.render.bind( this ) );
523
+
524
+ this.originalUri = new URI( attr.initURL );
525
+ this.currentUri = new URI( attr.initURL );
526
+
527
+ this.editor.codeMirror.on( 'change', function ( cm, c ) {
528
+ this.updatePreviewCss();
529
+ }.bind( this ) );
530
+ },
531
+
532
+ render: function () {
533
+
534
+ var selectedPost = this.model.get( 'selectedPost' );
535
+
536
+ if ( selectedPost && !selectedPost.has( 'postUrl' ) ) {
537
+ selectedPost.fetch().then( this.render.bind( this ) );
538
+ return this;
539
+ }
540
+
541
+ this.$el.html( this.template() );
542
+
543
+ if ( selectedPost ) {
544
+ this.currentUri = new URI( selectedPost.get( 'postUrl' ) );
545
+ }
546
+
547
+ this.currentUri.removeQuery( 'so_css_preview', 1 );
548
+ this.$( '#preview-navigator input' ).val( this.currentUri.toString() );
549
+ this.currentUri.addQuery( 'so_css_preview', 1 );
550
+
551
+ this.$( '#preview-iframe' ).attr( 'src', this.currentUri.toString() );
552
+ },
553
+
554
+ initPreview: function () {
555
+ var $$ = this.$( '#preview-iframe' );
556
+
557
+ // Update the current URI with the iframe URI
558
+ this.currentUri = new URI( $$.contents().get( 0 ).location.href );
559
+ this.currentUri.removeQuery( 'so_css_preview' );
560
+ this.$( '#preview-navigator input' ).val( this.currentUri.toString() );
561
+ this.currentUri.addQuery( 'so_css_preview', 1 );
562
+
563
+ $$.contents().find( 'a' ).each( function () {
564
+ var href = $( this ).attr( 'href' );
565
+ if ( href === undefined ) {
566
+ return true;
567
+ }
568
+
569
+ var firstSeperator = ( href.indexOf( '?' ) === -1 ? '?' : '&' );
570
+ $( this ).attr( 'href', href + firstSeperator + 'so_css_preview=1' );
571
+ } );
572
+
573
+ this.updatePreviewCss();
574
+ },
575
+
576
+ reloadPreview: function ( e ) {
577
+ var $$ = this.$( '#preview-navigator input[type="text"]' );
578
+
579
+ if ( e.keyCode === 13 ) {
580
+ e.preventDefault();
581
+
582
+ var newUri = new URI( $$.val() );
583
+
584
+ // Validate the URI
585
+ if (
586
+ this.originalUri.host() !== newUri.host() ||
587
+ this.originalUri.protocol() !== newUri.protocol()
588
+ ) {
589
+ $$.blur();
590
+ alert( $$.data( 'invalid-uri' ) );
591
+ $$.focus();
592
+ }
593
+ else {
594
+ newUri.addQuery( 'so_css_preview', 1 );
595
+ this.$( '#preview-iframe' ).attr( 'src', newUri.toString() );
596
+ }
597
+ }
598
+ },
599
+
600
+ /**
601
+ * Update the preview CSS from the CodeMirror value in the editor
602
+ */
603
+ updatePreviewCss: function () {
604
+ var preview = this.$( '#preview-iframe' );
605
+ if ( preview.length === 0 ) {
606
+ return;
607
+ }
608
+
609
+ var head = preview.contents().find( 'head' );
610
+ if ( head.find( 'style.siteorigin-custom-css' ).length === 0 ) {
611
+ head.append( '<style class="siteorigin-custom-css" type="text/css"></style>' );
612
+ }
613
+ var style = head.find( 'style.siteorigin-custom-css' );
614
+
615
+ // Update the CSS after a short delay
616
+ var css = this.editor.codeMirror.getValue().trim();
617
+ style.html( css );
618
+ },
619
+
620
+ /**
621
+ * Highlight all elements with a given selector
622
+ */
623
+ highlight: function ( selector ) {
624
+ try {
625
+ this.editor.inspector.hl.highlight( selector );
626
+ }
627
+ catch ( err ) {
628
+ console.log( 'No inspector to highlight with' );
629
+ }
630
+ },
631
+
632
+ /**
633
+ * Clear the currently highlighted elements in preview
634
+ */
635
+ clearHighlight: function () {
636
+ try {
637
+ this.editor.inspector.hl.clear();
638
+ }
639
+ catch ( err ) {
640
+ console.log( 'No inspector to highlight with' );
641
+ }
642
+ }
643
+
644
+ } );
645
+
646
+ /**
647
+ * The dialog for the snippets browser
648
+ */
649
+ socss.view.snippets = Backbone.View.extend( {
650
+ template: _.template( $( '#template-snippet-browser' ).html() ),
651
+ snippet: _.template( '<li class="snippet"><%- name %></li>' ),
652
+ className: 'css-editor-snippet-browser',
653
+ snippets: null,
654
+ editor: null,
655
+
656
+ events: {
657
+ 'click .close': 'hide',
658
+ 'click .buttons .insert-snippet': 'insertSnippet',
659
+ 'click .snippet': 'clickSnippet',
660
+ },
661
+
662
+ currentSnippet: null,
663
+
664
+ initialize: function ( args ) {
665
+ this.snippets = args.snippets;
666
+ },
667
+
668
+ render: function () {
669
+ this.$el.html( this.template() );
670
+ for ( var i = 0; i < this.snippets.length; i++ ) {
671
+ $( this.snippet( { name: this.snippets[ i ].Name } ) )
672
+ .data( {
673
+ 'description': this.snippets[ i ].Description,
674
+ 'css': this.snippets[ i ].css
675
+ } )
676
+ .appendTo( this.$( 'ul.snippets' ) );
677
+ }
678
+
679
+ // Click on the first one
680
+ this.$( '.snippets li.snippet' ).eq( 0 ).click();
681
+
682
+ this.attach();
683
+ return this;
684
+ },
685
+
686
+ clickSnippet: function ( event ) {
687
+ event.preventDefault();
688
+ var $$ = $( event.currentTarget );
689
+
690
+ this.$( '.snippets li.snippet' ).removeClass( 'active' );
691
+ $( this ).addClass( 'active' );
692
+ this.viewSnippet( {
693
+ name: $$.html(),
694
+ description: $$.data( 'description' ),
695
+ css: $$.data( 'css' )
696
+ } );
697
+ },
698
+
699
+ viewSnippet: function ( args ) {
700
+ var w = this.$( '.main .snippet-view' );
701
+
702
+ w.find( '.snippet-title' ).html( args.name );
703
+ w.find( '.snippet-description' ).html( args.description );
704
+ w.find( '.snippet-code' ).html( args.css );
705
+
706
+ this.currentSnippet = args;
707
+ },
708
+
709
+ insertSnippet: function () {
710
+ var editor = this.editor.codeMirror;
711
+ var css = this.currentSnippet.css;
712
+
713
+ var before_css = '';
714
+ if ( editor.doc.lineCount() === 1 && editor.doc.getLine( editor.doc.lastLine() ).length === 0 ) {
715
+ before_css = "";
716
+ }
717
+ else if ( editor.doc.getLine( editor.doc.lastLine() ).length === 0 ) {
718
+ before_css = "\n";
719
+ }
720
+ else {
721
+ before_css = "\n\n";
722
+ }
723
+
724
+ // Now insert the code in the editor
725
+ editor.doc.setCursor(
726
+ editor.doc.lastLine(),
727
+ editor.doc.getLine( editor.doc.lastLine() ).length
728
+ );
729
+ editor.doc.replaceSelection( before_css + css );
730
+
731
+ this.hide();
732
+ },
733
+
734
+ attach: function () {
735
+ this.$el.appendTo( 'body' );
736
+ },
737
+
738
+ show: function () {
739
+ this.$el.show();
740
+ },
741
+
742
+ hide: function () {
743
+ this.$el.hide();
744
+ }
745
+ } );
746
+
747
+
748
+ /**
749
+ * The visual properties editor
750
+ */
751
+ socss.view.properties = Backbone.View.extend( {
752
+
753
+ tabTemplate: _.template( '<li data-section="<%- id %>"><span class="fa fa-<%- icon %>"></span> <%- title %></li>' ),
754
+ sectionTemplate: _.template( '<div class="section" data-section="<%- id %>"><table class="fields-table"><tbody></tbody></table></div>' ),
755
+ controllerTemplate: _.template( '<tr><th scope="row"><%- title %></th><td></td></tr>' ),
756
+
757
+ /**
758
+ * The controllers for each of the properties
759
+ */
760
+ propertyControllers: [],
761
+
762
+ /**
763
+ * The editor view
764
+ */
765
+ editor: null,
766
+
767
+ /**
768
+ * The current, raw CSS
769
+ */
770
+ css: '',
771
+
772
+ /**
773
+ * Parsed CSS
774
+ */
775
+ parsed: {},
776
+
777
+ /**
778
+ * The current active selector
779
+ */
780
+ activeSelector: '',
781
+
782
+ /**
783
+ * Was the editor expanded before we went into the property editor
784
+ */
785
+ editorExpandedBefore: false,
786
+
787
+ events: {
788
+ 'click .close': 'hide',
789
+ 'click .section-tabs li': 'onTabClick',
790
+ 'change .toolbar select': 'onToolbarSelectChange',
791
+ },
792
+
793
+ /**
794
+ * Initialize the properties editor with a new model
795
+ */
796
+ initialize: function ( options ) {
797
+ this.parser = window.css;
798
+ this.editor = options.editor;
799
+ },
800
+
801
+ /**
802
+ * Render the property editor
803
+ */
804
+ render: function () {
805
+ // Clean up for potential re-renders
806
+ this.$( '.section-tabs' ).empty();
807
+ this.$( '.sections' ).empty();
808
+ this.$( '.toolbar select' ).off();
809
+ this.propertyControllers = [];
810
+
811
+ var controllers = socssOptions.propertyControllers;
812
+
813
+ for ( var id in controllers ) {
814
+ // Create the tabs
815
+ var $t = $( this.tabTemplate( {
816
+ id: id,
817
+ icon: controllers[ id ].icon,
818
+ title: controllers[ id ].title
819
+ } ) ).appendTo( this.$( '.section-tabs' ) );
820
+
821
+ // Create the section wrapper
822
+ var $s = $( this.sectionTemplate( {
823
+ id: id
824
+ } ) ).appendTo( this.$( '.sections' ) );
825
+
826
+ // Now lets add the controllers
827
+ if ( !_.isEmpty( controllers[ id ].controllers ) ) {
828
+
829
+ for ( var i = 0; i < controllers[ id ].controllers.length; i++ ) {
830
+
831
+ var $c = $( this.controllerTemplate( {
832
+ title: controllers[ id ].controllers[ i ].title
833
+ } ) ).appendTo( $s.find( 'tbody' ) );
834
+
835
+ var controllerAtts = controllers[ id ].controllers[ i ];
836
+ var controller;
837
+
838
+ if ( typeof socss.view.properties.controllers[ controllerAtts.type ] === 'undefined' ) {
839
+ // Setup a default controller
840
+ controller = new socss.view.propertyController( {
841
+ el: $c.find( 'td' ),
842
+ propertiesView: this,
843
+ args: ( typeof controllerAtts.args === 'undefined' ? {} : controllerAtts.args )
844
+ } );
845
+ }
846
+ else {
847
+ // Setup a specific controller
848
+ controller = new socss.view.properties.controllers[ controllerAtts.type ]( {
849
+ el: $c.find( 'td' ),
850
+ propertiesView: this,
851
+ args: ( typeof controllerAtts.args === 'undefined' ? {} : controllerAtts.args )
852
+ } );
853
+ }
854
+
855
+ this.propertyControllers.push( controller );
856
+
857
+ // Setup and render the controller
858
+ controller.render();
859
+ }
860
+ }
861
+ }
862
+
863
+ // Switch to the first tab.
864
+ this.$( '.section-tabs li' ).eq( 0 ).click();
865
+ },
866
+
867
+ onTabClick: function ( event ) {
868
+ var $$ = $( event.currentTarget );
869
+ var show = this.$( '.sections .section[data-section="' + $$.data( 'section' ) + '"]' );
870
+
871
+ this.$( '.sections .section' ).not( show ).hide().removeClass( 'active' );
872
+ show.show().addClass( 'active' );
873
+
874
+ this.$( '.section-tabs li' ).not( $$ ).removeClass( 'active' );
875
+ $$.addClass( 'active' );
876
+ },
877
+
878
+ onToolbarSelectChange: function ( event ) {
879
+ this.setActiveSelector( $( event.currentTarget ).find( ':selected' ).data( 'selector' ) );
880
+ },
881
+
882
+ /**
883
+ * Sets the rule value for the active selector
884
+ * @param rule
885
+ * @param value
886
+ */
887
+ setRuleValue: function ( rule, value ) {
888
+ if (
889
+ typeof this.activeSelector === 'undefined' ||
890
+ typeof this.activeSelector.declarations === 'undefined'
891
+ ) {
892
+ return;
893
+ }
894
+
895
+ var declarations = this.activeSelector.declarations;
896
+ var newRule = true;
897
+ var valueChanged = false;
898
+ for ( var i = 0; i < declarations.length; i++ ) {
899
+ if ( declarations[ i ].property === rule ) {
900
+ newRule = false;
901
+ var declaration = declarations[ i ];
902
+ if ( declaration.value !== value ) {
903
+ declaration.value = value;
904
+ valueChanged = true;
905
+ }
906
+
907
+ // Remove empty declarations
908
+ if ( _.isEmpty( declaration.value ) ) {
909
+ declarations.splice( declarations.indexOf( declaration ) );
910
+ }
911
+ break;
912
+ }
913
+ }
914
+
915
+ if ( newRule && !_.isEmpty( value ) ) {
916
+ declarations.push( {
917
+ property: rule,
918
+ value: value,
919
+ type: 'declaration',
920
+ } );
921
+ valueChanged = true;
922
+ }
923
+
924
+ if ( valueChanged ) {
925
+ this.updateMainEditor( false );
926
+ }
927
+ },
928
+
929
+ /**
930
+ * Adds the @import rule value if it doesn't already exist.
931
+ *
932
+ * @param newRule
933
+ *
934
+ */
935
+ addImport: function ( newRule ) {
936
+
937
+ // get @import rules
938
+ // check if any have the same value
939
+ // if not, then add the new @ rule
940
+
941
+ var importRules = _.filter( this.parsed.stylesheet.rules, function ( rule ) {
942
+ return rule.type === 'import';
943
+ } );
944
+ var exists = _.any( importRules, function ( rule ) {
945
+ return rule.import === newRule.import;
946
+ } );
947
+
948
+ if ( !exists ) {
949
+ // Add it to the top!
950
+ // @import statements must precede other rule types.
951
+ this.parsed.stylesheet.rules.unshift( newRule );
952
+ this.updateMainEditor( false );
953
+ }
954
+
955
+ },
956
+
957
+ /**
958
+ * Find @import which completely or partially contains the specified value.
959
+ *
960
+ * @param value
961
+ */
962
+ findImport: function ( value ) {
963
+ return _.find( this.parsed.stylesheet.rules, function ( rule ) {
964
+ return rule.type === 'import' && rule.import.indexOf( value ) > -1;
965
+ } );
966
+ },
967
+
968
+ /**
969
+ * Find @import which completely or partially contains the identifier value and update it's import property.
970
+ *
971
+ * @param identifier
972
+ * @param value
973
+ */
974
+ updateImport: function ( identifier, value ) {
975
+ var importRule = this.findImport( identifier );
976
+ if ( importRule.import !== value.import ) {
977
+ importRule.import = value.import;
978
+ this.updateMainEditor( false );
979
+ }
980
+ },
981
+
982
+ /**
983
+ * Find @import which completely or partially contains the identifier value and remove it.
984
+ *
985
+ * @param identifier
986
+ */
987
+ removeImport: function ( identifier ) {
988
+ var importIndex = _.findIndex( this.parsed.stylesheet.rules, function ( rule ) {
989
+ return rule.type === 'import' && rule.import.indexOf( identifier ) > -1;
990
+ } );
991
+ if ( importIndex > -1 ) {
992
+ this.parsed.stylesheet.rules.splice( importIndex, 1 );
993
+ }
994
+ },
995
+
996
+ /**
997
+ * Get the rule value for the active selector
998
+ * @param rule
999
+ */
1000
+ getRuleValue: function ( rule ) {
1001
+ if ( typeof this.activeSelector === 'undefined' || typeof this.activeSelector.declarations === 'undefined' ) {
1002
+ return '';
1003
+ }
1004
+
1005
+ var declarations = this.activeSelector.declarations;
1006
+ for ( var i = 0; i < declarations.length; i++ ) {
1007
+ if ( declarations[ i ].property === rule ) {
1008
+ return declarations[ i ].value;
1009
+ }
1010
+ }
1011
+ return '';
1012
+ },
1013
+
1014
+ /**
1015
+ * Update the main editor with the value of the parsed CSS
1016
+ */
1017
+ updateMainEditor: function ( compress ) {
1018
+ //TODO: add back compress option to remove/merge duplicated CSS selectors.
1019
+ this.editor.codeMirror.setValue( this.parser.stringify( this.parsed ) );
1020
+ },
1021
+
1022
+ /**
1023
+ * Show the properties editor
1024
+ */
1025
+ show: function () {
1026
+ this.editorExpandedBefore = this.editor.isExpanded();
1027
+ this.editor.setExpand( true );
1028
+
1029
+ this.$el.show().animate( { 'left': 0 }, 'fast' );
1030
+ },
1031
+
1032
+ /**
1033
+ * Hide the properties editor
1034
+ */
1035
+ hide: function () {
1036
+ this.editor.setExpand( this.editorExpandedBefore );
1037
+ this.$el.animate( { 'left': -338 }, 'fast', function () {
1038
+ $( this ).hide();
1039
+ } );
1040
+
1041
+ // Update the main editor with compressed CSS when we close the properties editor
1042
+ this.updateMainEditor( true );
1043
+ },
1044
+
1045
+ /**
1046
+ * @returns boolean
1047
+ */
1048
+ isVisible: function () {
1049
+ return this.$el.is( ':visible' );
1050
+ },
1051
+
1052
+ /**
1053
+ * Loads a single CSS selector and associated properties into the model
1054
+ * @param css
1055
+ */
1056
+ loadCSS: function ( css, activeSelector ) {
1057
+ this.css = css;
1058
+
1059
+ // Load the CSS
1060
+ this.parsed = this.parser.parse( css, {
1061
+ silent: true
1062
+ } );
1063
+ var rules = this.parsed.stylesheet.rules;
1064
+
1065
+ // Add the dropdown menu items
1066
+ var dropdown = this.$( '.toolbar select' ).empty();
1067
+ for ( var i = 0; i < rules.length; i++ ) {
1068
+ var rule = rules[ i ];
1069
+
1070
+ // Exclude @import statements
1071
+ if ( !_.contains( [ 'rule', 'media' ], rule.type ) ) {
1072
+ continue;
1073
+ }
1074
+
1075
+ if ( rule.type === 'media' ) {
1076
+
1077
+ for ( var j = 0; j < rule.rules.length; j++ ) {
1078
+ var mediaRule = '@media ' + rule.media;
1079
+ var subRule = rule.rules[ j ];
1080
+ if ( subRule.type != 'rule' ) {
1081
+ continue;
1082
+ }
1083
+ dropdown.append(
1084
+ $( '<option>' )
1085
+ .html( mediaRule + ': ' + subRule.selectors.join( ',' ) )
1086
+ .attr( 'val', mediaRule + ': ' + subRule.selectors.join( ',' ) )
1087
+ .data( 'selector', subRule )
1088
+ );
1089
+ }
1090
+
1091
+ }
1092
+ else {
1093
+ dropdown.append(
1094
+ $( '<option>' )
1095
+ .html( rule.selectors.join( ',' ) )
1096
+ .attr( 'val', rule.selectors.join( ',' ) )
1097
+ .data( 'selector', rule )
1098
+ );
1099
+ }
1100
+ }
1101
+
1102
+ if ( typeof activeSelector === 'undefined' ) {
1103
+ activeSelector = dropdown.find( 'option' ).eq( 0 ).attr( 'val' );
1104
+ }
1105
+ if ( !_.isEmpty( activeSelector ) ) {
1106
+ dropdown.val( activeSelector ).change();
1107
+ }
1108
+ },
1109
+
1110
+ /**
1111
+ * Set the selector that we're currently dealing with
1112
+ * @param selector
1113
+ */
1114
+ setActiveSelector: function ( selector ) {
1115
+ this.activeSelector = selector;
1116
+ for ( var i = 0; i < this.propertyControllers.length; i++ ) {
1117
+ this.propertyControllers[ i ].refreshFromRule();
1118
+ }
1119
+ },
1120
+
1121
+ /**
1122
+ * Add or select a selector.
1123
+ *
1124
+ * @param selector
1125
+ */
1126
+ addSelector: function ( selector ) {
1127
+ // Check if this selector already exists
1128
+ var dropdown = this.$( '.toolbar select' );
1129
+ dropdown.val( selector );
1130
+
1131
+ if ( dropdown.val() === selector ) {
1132
+ // Trigger a change event to load the existing selector
1133
+ dropdown.change();
1134
+ }
1135
+ else {
1136
+ // The selector doesn't exist, so add it to the CSS, then reload
1137
+ this.editor.addEmptySelector( selector );
1138
+ this.loadCSS( this.editor.codeMirror.getValue().trim(), selector );
1139
+ }
1140
+
1141
+ dropdown.addClass( 'highlighted' );
1142
+ setTimeout( function () {
1143
+ dropdown.removeClass( 'highlighted' );
1144
+ }, 2000 );
1145
+ }
1146
+
1147
+ } );
1148
+
1149
+ // The basic property controller
1150
+ socss.view.propertyController = Backbone.View.extend( {
1151
+
1152
+ template: _.template( '<input type="text" value="" class="socss-property-controller-input"/>' ),
1153
+ activeRule: null,
1154
+ args: null,
1155
+ propertiesView: null,
1156
+
1157
+ events: {
1158
+ 'change .socss-property-controller-input': 'onChange',
1159
+ 'keyup input.socss-property-controller-input': 'onChange',
1160
+ },
1161
+
1162
+ initialize: function ( args ) {
1163
+
1164
+ this.args = args.args;
1165
+ this.propertiesView = args.propertiesView;
1166
+
1167
+ // If sub-views items define their own events hash with the same keys as above they will override those on
1168
+ // the above events hash.
1169
+ this.events = _.extend( socss.view.propertyController.prototype.events, this.events );
1170
+ this.delegateEvents( this.events );
1171
+
1172
+ // By default, update the active rule whenever things change
1173
+ this.on( 'set_value', this.updateRule, this );
1174
+ this.on( 'change', this.updateRule, this );
1175
+ },
1176
+
1177
+ /**
1178
+ * Render the property field controller
1179
+ */
1180
+ render: function () {
1181
+ this.$el.append( $( this.template( {} ) ) );
1182
+ this.field = this.$( 'input.socss-property-controller-input' );
1183
+ },
1184
+
1185
+ onChange: function () {
1186
+ this.trigger( 'change', this.field.val() );
1187
+ },
1188
+
1189
+ /**
1190
+ * Update the value of an active rule
1191
+ */
1192
+ updateRule: function () {
1193
+ this.propertiesView.setRuleValue(
1194
+ this.args.property,
1195
+ this.getValue()
1196
+ );
1197
+ },
1198
+
1199
+ /**
1200
+ * This is called when the selector changes
1201
+ */
1202
+ refreshFromRule: function () {
1203
+ var value = this.propertiesView.getRuleValue( this.args.property );
1204
+ this.setValue( value, { silent: true } );
1205
+ },
1206
+
1207
+ /**
1208
+ * Get the current value
1209
+ * @return string
1210
+ */
1211
+ getValue: function () {
1212
+ return this.field.val();
1213
+ },
1214
+
1215
+ /**
1216
+ * Set the current value
1217
+ * @param socss.view.properties val
1218
+ */
1219
+ setValue: function ( val, options ) {
1220
+ options = _.extend( { silent: false }, options );
1221
+
1222
+ this.field.val( val );
1223
+
1224
+ if ( !options.silent ) {
1225
+ this.trigger( 'set_value', val );
1226
+ }
1227
+ },
1228
+
1229
+ /**
1230
+ * Reset the current value
1231
+ */
1232
+ reset: function ( options ) {
1233
+ options = _.extend( { silent: false }, options );
1234
+
1235
+ this.setValue( '', options );
1236
+ }
1237
+
1238
+ } );
1239
+
1240
+ // All the value controllers
1241
+ socss.view.properties.controllers = {};
1242
+
1243
+ // The color controller
1244
+ socss.view.properties.controllers.color = socss.view.propertyController.extend( {
1245
+
1246
+ render: function () {
1247
+ socss.view.propertyController.prototype.render.apply( this, arguments );
1248
+ // Set this up as a color picker
1249
+ this.field.minicolors( {} );
1250
+
1251
+ },
1252
+
1253
+ onChange: function () {
1254
+ this.trigger( 'change', this.field.minicolors( 'value' ) );
1255
+ },
1256
+
1257
+ getValue: function () {
1258
+ return this.field.minicolors( 'value' ).trim();
1259
+ },
1260
+
1261
+ setValue: function ( val, options ) {
1262
+ options = _.extend( { silent: false }, options );
1263
+
1264
+ this.field.minicolors( 'value', val );
1265
+
1266
+ if ( !options.silent ) {
1267
+ this.trigger( 'set_value', val );
1268
+ }
1269
+ }
1270
+
1271
+ } );
1272
+
1273
+ // The dropdown select box controller
1274
+ socss.view.properties.controllers.select = socss.view.propertyController.extend( {
1275
+ template: _.template( '<select class="socss-property-controller-input"></select>' ),
1276
+
1277
+ events: {
1278
+ 'click .select-tab': 'onSelect',
1279
+ },
1280
+
1281
+ render: function () {
1282
+ this.$el.append( $( this.template( {} ) ) );
1283
+ this.field = this.$( 'select' );
1284
+
1285
+ // Add the unchanged option
1286
+ this.field.append( $( '<option value=""></option>' ).html( '' ) );
1287
+
1288
+ // Add all the options to the dropdown
1289
+ for ( var k in this.args.options ) {
1290
+ this.field.append( $( '<option></option>' ).attr( 'value', k ).html( this.args.options[ k ] ) );
1291
+ }
1292
+
1293
+ if ( typeof this.args.option_icons !== 'undefined' ) {
1294
+ this.setupVisualSelect();
1295
+ }
1296
+ },
1297
+
1298
+ setupVisualSelect: function () {
1299
+ this.field.hide();
1300
+
1301
+ var $tc = $( '<div class="select-tabs"></div>' ).appendTo( this.$el );
1302
+
1303
+ // Add the none value
1304
+ $( '<div class="select-tab" data-value=""><span class="fa fa-circle-o"></span></div>' ).appendTo( $tc );
1305
+
1306
+ // Now add one for each of the option icons
1307
+ for ( var k in this.args.option_icons ) {
1308
+ $( '<div class="select-tab"></div>' )
1309
+ .appendTo( $tc )
1310
+ .append(
1311
+ $( '<span class="fa"></span>' )
1312
+ .addClass( 'fa-' + this.args.option_icons[ k ] )
1313
+ )
1314
+ .attr( 'data-value', k )
1315
+ ;
1316
+ }
1317
+
1318
+ $tc.find( '.select-tab' ).css( 'width', 100 / ( $tc.find( '>div' ).length ) + "%" );
1319
+ },
1320
+
1321
+ onSelect: function ( event ) {
1322
+ this.$( '.select-tab' ).removeClass( 'active' );
1323
+ var $t = $( event.currentTarget );
1324
+ $t.addClass( 'active' );
1325
+ this.field.val( $t.data( 'value' ) ).trigger( 'change' );
1326
+ },
1327
+
1328
+ /**
1329
+ * Set the current value
1330
+ * @param socss.view.properties val
1331
+ */
1332
+ setValue: function ( val, options ) {
1333
+ options = _.extend( { silent: false }, options );
1334
+
1335
+ this.field.val( val );
1336
+
1337
+ this.$( '.select-tabs .select-tab' ).removeClass( 'active' ).filter( '[data-value="' + val + '"]' ).addClass( 'active' );
1338
+
1339
+ if ( !options.silent ) {
1340
+ this.trigger( 'set_value', val );
1341
+ }
1342
+ }
1343
+
1344
+ } );
1345
+
1346
+ // A field that lets a user upload an image
1347
+ socss.view.properties.controllers.image = socss.view.propertyController.extend( {
1348
+ template: _.template( '<input type="text" value="" /> <span class="select socss-button"><span class="fa fa-upload"></span></span>' ),
1349
+
1350
+ events: {
1351
+ 'click .select': 'openMedia',
1352
+ },
1353
+
1354
+ render: function () {
1355
+ this.media = wp.media( {
1356
+ // Set the title of the modal.
1357
+ title: socssOptions.loc.select_image,
1358
+
1359
+ // Tell the modal to show only images.
1360
+ library: {
1361
+ type: 'image'
1362
+ },
1363
+
1364
+ // Customize the submit button.
1365
+ button: {
1366
+ // Set the text of the button.
1367
+ text: socssOptions.loc.select,
1368
+ // Tell the button not to close the modal, since we're
1369
+ // going to refresh the page when the image is selected.
1370
+ close: false
1371
+ }
1372
+ } );
1373
+
1374
+ this.$el.append( $( this.template( {
1375
+ select: socssOptions.loc.select
1376
+ } ) ) );
1377
+
1378
+ this.field = this.$el.find( 'input' );
1379
+
1380
+ this.media.on( 'select', function () {
1381
+ // Grab the selected attachment.
1382
+ var attachment = this.media.state().get( 'selection' ).first().attributes;
1383
+ var val = this.args.value.replace( '{{url}}', attachment.url );
1384
+
1385
+ // Change the field value and trigger a change event
1386
+ this.field.val( val ).change();
1387
+
1388
+ // Close the image selector
1389
+ this.media.close();
1390
+
1391
+ }.bind( this ) );
1392
+ },
1393
+
1394
+ openMedia: function () {
1395
+ this.media.open();
1396
+ },
1397
+
1398
+ } );
1399
+
1400
+ // A simple measurement field
1401
+ socss.view.properties.controllers.measurement = socss.view.propertyController.extend( {
1402
+
1403
+ wrapperClass: 'socss-field-measurement',
1404
+
1405
+ events: {
1406
+ 'click .toggle-dropdown': 'toggleUnitDropdown',
1407
+ 'click .dropdown li': 'onSelectUnit',
1408
+ 'keydown .socss-field-input': 'onInputKeyPress',
1409
+ 'keyup .socss-field-input': 'onInputKeyUp',
1410
+ },
1411
+
1412
+ render: function () {
1413
+ socss.view.propertyController.prototype.render.apply( this, arguments );
1414
+
1415
+ this.setupMeasurementField();
1416
+ },
1417
+
1418
+ setValue: function ( val, options ) {
1419
+ options = _.extend( { silent: false }, options );
1420
+ this.field.val( val ).trigger( 'measurement_refresh' );
1421
+ if ( !options.silent ) {
1422
+ this.trigger( 'set_value', val );
1423
+ }
1424
+ },
1425
+
1426
+ units: [
1427
+ 'px',
1428
+ '%',
1429
+ 'em',
1430
+ 'cm',
1431
+ 'mm',
1432
+ 'in',
1433
+ 'pt',
1434
+ 'pc',
1435
+ 'ex',
1436
+ 'ch',
1437
+ 'rem',
1438
+ 'vw',
1439
+ 'vh',
1440
+ 'vmin',
1441
+ 'vmax'
1442
+ ],
1443
+
1444
+ parseUnits: function ( value ) {
1445
+ var escapeRegExp = function ( str ) {
1446
+ return str.replace( /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&" );
1447
+ };
1448
+
1449
+ var regexUnits = this.units.map( escapeRegExp );
1450
+ var regex = new RegExp( '([0-9\\.\\-]+)(' + regexUnits.join( '|' ) + ')?', 'i' );
1451
+ var result = regex.exec( value );
1452
+
1453
+ if ( result === null ) {
1454
+ return {
1455
+ value: '',
1456
+ unit: ''
1457
+ };
1458
+ }
1459
+ else {
1460
+ return {
1461
+ value: result[ 1 ],
1462
+ unit: result[ 2 ] === undefined ? '' : result[ 2 ]
1463
+ };
1464
+ }
1465
+ },
1466
+
1467
+ setupMeasurementField: function () {
1468
+ var defaultUnit = 'px';
1469
+
1470
+ this.field.hide();
1471
+ this.$el.addClass( this.wrapperClass ).data( 'unit', defaultUnit );
1472
+
1473
+ // Create the fake input field
1474
+ var $fi = $( '<input type="text" class="socss-field-input"/>' ).appendTo( this.$el );
1475
+ $( '<span class="toggle-dropdown dashicons dashicons-arrow-down"></span>' ).appendTo( this.$el );
1476
+ var $dd = $( '<ul class="dropdown"></ul>' ).appendTo( this.$el );
1477
+ var $u = $( '<span class="units"></span>' ).html( defaultUnit ).appendTo( this.$el );
1478
+
1479
+ for ( var i = 0; i < this.units.length; i++ ) {
1480
+ var $o = $( '<li></li>' ).html( this.units[ i ] ).data( 'unit', this.units[ i ] );
1481
+ if ( this.units[ i ] === defaultUnit ) {
1482
+ $o.addClass( 'active' );
1483
+ }
1484
+ $dd.append( $o );
1485
+ }
1486
+
1487
+ this.field.on( 'measurement_refresh', function () {
1488
+ var value = this.parseUnits( this.field.val() );
1489
+ $fi.val( value.value );
1490
+
1491
+ var unit = value.unit === '' ? defaultUnit : value.unit;
1492
+ this.$el.data( 'unit', unit );
1493
+ $u.html( unit );
1494
+
1495
+ var $pl = $( '<span class="socss-hidden-placeholder"></span>' )
1496
+ .css( {
1497
+ 'font-size': '14px'
1498
+ } )
1499
+ .html( value.value )
1500
+ .appendTo( 'body' );
1501
+ var width = $pl.width();
1502
+ width = Math.min( width, 63 );
1503
+ $pl.remove();
1504
+
1505
+ $u.css( 'left', width + 12 );
1506
+ }.bind( this ) );
1507
+
1508
+ // Now add the increment/decrement buttons
1509
+ var $diw = $( '<div class="socss-diw"></div>' ).appendTo( this.$el );
1510
+ var $dec = $( '<div class="dec-button socss-button"><span class="fa fa-minus"></span></div>' ).appendTo( $diw );
1511
+ var $inc = $( '<div class="inc-button socss-button"><span class="fa fa-plus"></span></div>' ).appendTo( $diw );
1512
+
1513
+ this.setupStepButton( $dec );
1514
+ this.setupStepButton( $inc );
1515
+
1516
+ },
1517
+
1518
+ updateValue: function () {
1519
+ var $fi = this.$( '.socss-field-input' );
1520
+ var value = this.parseUnits( $fi.val() );
1521
+
1522
+ if ( value.unit !== '' && value.unit !== this.$el.data( 'unit' ) ) {
1523
+ $fi.val( value.value );
1524
+ this.setUnit( value.unit );
1525
+ }
1526
+
1527
+ if ( value.value === '' ) {
1528
+ this.field.val( '' );
1529
+ }
1530
+ else {
1531
+ this.field.val( value.value + this.$el.data( 'unit' ) );
1532
+ }
1533
+ this.field.trigger( 'change' );
1534
+ },
1535
+
1536
+ setUnit: function ( unit ) {
1537
+ this.$( '.units' ).html( unit );
1538
+ this.$el.data( 'unit', unit );
1539
+ this.$( '.socss-field-input' ).trigger( 'keydown' );
1540
+ },
1541
+
1542
+ toggleUnitDropdown: function () {
1543
+ this.$( '.dropdown' ).toggle();
1544
+ },
1545
+
1546
+ onSelectUnit: function ( event ) {
1547
+ this.toggleUnitDropdown();
1548
+ this.setUnit( $( event.currentTarget ).data( 'unit' ) );
1549
+ this.updateValue();
1550
+ },
1551
+
1552
+ onInputKeyUp: function( event ) {
1553
+ this.onInputKeyPress( event );
1554
+ this.updateValue();
1555
+ },
1556
+
1557
+ onInputKeyPress: function ( event ) {
1558
+ var $fi = this.$( '.socss-field-input' );
1559
+
1560
+ var char = '';
1561
+ if ( event.type === 'keydown' ) {
1562
+ if ( event.keyCode >= 48 && event.keyCode <= 57 ) {
1563
+ char = String.fromCharCode( event.keyCode );
1564
+ }
1565
+ else if ( event.keyCode === 189 ) {
1566
+ char = '-';
1567
+ }
1568
+ else if ( event.keyCode === 190 ) {
1569
+ char = '.';
1570
+ }
1571
+ }
1572
+
1573
+ var $pl = $( '<span class="socss-hidden-placeholder"></span>' )
1574
+ .css( {
1575
+ 'font-size': '14px'
1576
+ } )
1577
+ .html( $fi.val() + char )
1578
+ .appendTo( 'body' );
1579
+ var width = $pl.width();
1580
+ width = Math.min( width, 63 );
1581
+ $pl.remove();
1582
+
1583
+ this.$( '.units' ).css( 'left', width + 12 );
1584
+ },
1585
+
1586
+ stepValue: function ( direction ) {
1587
+ var value = Number.parseInt( this.parseUnits( this.field.val() ).value );
1588
+
1589
+ if ( Number.isNaN( value ) ) {
1590
+ value = 0;
1591
+ }
1592
+
1593
+ var newVal = value + direction;
1594
+
1595
+ this.$( '.socss-field-input' ).val( newVal );
1596
+ this.updateValue();
1597
+ this.field.trigger( 'measurement_refresh' );
1598
+ },
1599
+
1600
+ setupStepButton: function ( $button ) {
1601
+ var direction = $button.is( '.dec-button' ) ? -1 : 1;
1602
+ var intervalId;
1603
+ var timeoutId;
1604
+ $button.mousedown( function () {
1605
+ this.stepValue( direction );
1606
+ timeoutId = setTimeout( function () {
1607
+ intervalId = setInterval( function () {
1608
+ this.stepValue( direction );
1609
+ }.bind( this ), 50 );
1610
+ }.bind( this ), 500 );
1611
+ }.bind( this ) ).on( 'mouseup mouseout', function () {
1612
+ if ( timeoutId ) {
1613
+ clearTimeout( timeoutId );
1614
+ timeoutId = null;
1615
+ }
1616
+ if ( intervalId ) {
1617
+ clearInterval( intervalId );
1618
+ intervalId = null;
1619
+ }
1620
+ } );
1621
+ },
1622
+ } );
1623
+
1624
+ // A simple measurement field
1625
+ socss.view.properties.controllers.number = socss.view.propertyController.extend( {
1626
+
1627
+ initialize: function ( args ) {
1628
+ socss.view.propertyController.prototype.initialize.apply( this, arguments );
1629
+
1630
+ this.args = _.extend( {
1631
+ change: null,
1632
+ default: 0,
1633
+ increment: 1,
1634
+ decrement: -1,
1635
+ max: null,
1636
+ min: null
1637
+ }, args.args );
1638
+ },
1639
+
1640
+ render: function () {
1641
+ socss.view.propertyController.prototype.render.apply( this, arguments );
1642
+
1643
+ this.setupNumberField();
1644
+ },
1645
+
1646
+ setupNumberField: function () {
1647
+
1648
+ this.$el.addClass( 'socss-field-number' );
1649
+
1650
+ // Now add the increment/decrement buttons
1651
+ var $diw = $( '<div class="socss-diw"></div>' ).appendTo( this.$el );
1652
+ var $dec = $( '<div class="dec-button socss-button"><span class="fa fa-minus"></span></div>' ).appendTo( $diw );
1653
+ var $inc = $( '<div class="inc-button socss-button"><span class="fa fa-plus"></span></div>' ).appendTo( $diw );
1654
+
1655
+ this.setupStepButton( $dec );
1656
+ this.setupStepButton( $inc );
1657
+
1658
+ return this;
1659
+ },
1660
+
1661
+ stepValue: function ( direction ) {
1662
+ var value = Number.parseFloat( this.field.val() );
1663
+
1664
+ if ( Number.isNaN( value ) ) {
1665
+ value = this.args.default;
1666
+ }
1667
+
1668
+ var newVal = value + direction;
1669
+
1670
+ newVal = Math.round( newVal * 100 ) / 100;
1671
+
1672
+ if ( this.args.max !== null ) {
1673
+ newVal = Math.min( this.args.max, newVal );
1674
+ }
1675
+
1676
+ if ( this.args.min !== null ) {
1677
+ newVal = Math.max( this.args.min, newVal );
1678
+ }
1679
+
1680
+ this.field.val( newVal );
1681
+ this.field.trigger( 'change' );
1682
+ },
1683
+
1684
+ setupStepButton: function ( $button ) {
1685
+ var direction = $button.is( '.dec-button' ) ? this.args.decrement : this.args.increment;
1686
+ var intervalId;
1687
+ var timeoutId;
1688
+ $button.mousedown( function () {
1689
+ this.stepValue( direction );
1690
+ timeoutId = setTimeout( function () {
1691
+ intervalId = setInterval( function () {
1692
+ this.stepValue( direction );
1693
+ }.bind( this ), 50 );
1694
+ }.bind( this ), 500 );
1695
+ }.bind( this ) ).on( 'mouseup mouseout', function () {
1696
+ if ( timeoutId ) {
1697
+ clearTimeout( timeoutId );
1698
+ timeoutId = null;
1699
+ }
1700
+ if ( intervalId ) {
1701
+ clearInterval( intervalId );
1702
+ intervalId = null;
1703
+ }
1704
+ } );
1705
+ },
1706
+
1707
+ } );
1708
+
1709
+
1710
+ socss.view.properties.controllers.sides = socss.view.propertyController.extend( {
1711
+
1712
+ template: _.template( $( '#template-sides-field' ).html().trim() ),
1713
+
1714
+ controllers: [],
1715
+
1716
+ events: {
1717
+ 'click .select-tab': 'onTabClick',
1718
+ },
1719
+
1720
+ render: function () {
1721
+
1722
+ socss.view.propertyController.prototype.render.apply( this, arguments );
1723
+
1724
+ if ( !this.args.hasAll ) {
1725
+ this.$( '.select-tab' ).eq( 0 ).remove();
1726
+ this.$( '.select-tab' ).css( 'width', '25%' );
1727
+ }
1728
+
1729
+ this.$( '.select-tab' ).each( function ( index, element ) {
1730
+ var dir = $( element ).data( 'direction' );
1731
+
1732
+ var container = $( '<li class="side">' )
1733
+ .appendTo( this.$( '.sides' ) )
1734
+ .hide();
1735
+
1736
+ for ( var i = 0; i < this.args.controllers.length; i++ ) {
1737
+
1738
+ var controllerArgs = this.args.controllers[ i ];
1739
+
1740
+ if ( typeof socss.view.properties.controllers[ controllerArgs.type ] ) {
1741
+
1742
+ // Create the measurement view
1743
+ var property = '';
1744
+ if ( dir === 'all' ) {
1745
+ property = controllerArgs.args.propertyAll;
1746
+ }
1747
+ else {
1748
+ property = controllerArgs.args.property.replace( '{dir}', dir );
1749
+ }
1750
+
1751
+ var theseControllerArgs = _.extend( {}, controllerArgs.args, { property: property } );
1752
+
1753
+ var controller = new socss.view.properties.controllers[ controllerArgs.type ]( {
1754
+ el: $( '<div>' ).appendTo( container ),
1755
+ propertiesView: this.propertiesView,
1756
+ args: theseControllerArgs
1757
+ } );
1758
+
1759
+ // Setup and render the measurement controller and register it with the properties view
1760
+ controller.render();
1761
+ this.propertiesView.propertyControllers.push( controller );
1762
+ }
1763
+ }
1764
+
1765
+ }.bind( this ) );
1766
+
1767
+ // Select the first tab by default
1768
+ this.$( '.select-tab' ).eq( 0 ).click();
1769
+ },
1770
+
1771
+ onTabClick: function ( event ) {
1772
+ var $tabs = this.$( '.select-tab' );
1773
+ $tabs.removeClass( 'active' );
1774
+
1775
+ var $tab = $( event.currentTarget );
1776
+ $tab.addClass( 'active' );
1777
+
1778
+ var $sides = this.$( '.sides .side' )
1779
+ $sides.hide();
1780
+
1781
+ $sides.eq( $tabs.index( $tab ) ).show();
1782
+ },
1783
+ } );
1784
+
1785
+ // This is a placeholder for the full font_select in SiteOrigin Premium
1786
+ socss.view.properties.controllers.font_select = socss.view.propertyController.extend( {
1787
+ template: _.template( $('#template-webfont-teaser').html().trim() )
1788
+ });
1789
+
1790
+ socss.view.RevisionsListView = Backbone.View.extend( {
1791
+
1792
+ initialize: function () {
1793
+ this.listenTo( this.model, 'change:selectedPost', this.updateRevisionsList.bind( this ) )
1794
+ },
1795
+
1796
+ updateRevisionsList: function () {
1797
+ $.get(
1798
+ socssOptions.getRevisionsListAjaxUrl,
1799
+ { postId: this.model.get( 'selectedPost' ).get( 'postId' ) },
1800
+ function ( result ) {
1801
+ this.$( '.custom-revisions-list' ).html( result );
1802
+ }.bind( this )
1803
+ );
1804
+ },
1805
+
1806
+ // TODO: This is using the server rendered partial. Update to use models and render
1807
+ } );
1808
+
1809
+ } )( jQuery, _, socssOptions );
1810
+
1811
+ // Setup the main editor
1812
+ jQuery( function ( $ ) {
1813
+ var socss = window.socss;
1814
+
1815
+ var editorModel = new socss.model.CSSEditorModel( {
1816
+ customCssPosts: socssOptions.customCssPosts,
1817
+ } );
1818
+
1819
+ // Setup the editor
1820
+ var editor = new socss.view.editor( {
1821
+ el: $( '#so-custom-css-form' ).get( 0 ),
1822
+ model: editorModel,
1823
+ openVisualEditor: socssOptions.openVisualEditor,
1824
+ } );
1825
+ // editor.render();
1826
+ editor.setSnippets( socssOptions.snippets );
1827
+
1828
+
1829
+ var revisionsList = new socss.view.RevisionsListView( {
1830
+ el: $( '#so-custom-css-revisions' ),
1831
+ model: editorModel,
1832
+ } );
1833
+
1834
+ // This is for hiding the getting started video
1835
+ $( '#so-custom-css-getting-started a.hide' ).click( function ( e ) {
1836
+ e.preventDefault();
1837
+ $( '#so-custom-css-getting-started' ).slideUp();
1838
+ $.get( $( this ).attr( 'href' ) );
1839
+ } );
1840
+
1841
+ window.socss.mainEditor = editor;
1842
+ window.socss.revisionsList = revisionsList;
1843
+ $( socss ).trigger( 'initialized' );
1844
+ } );
js/editor.min.js CHANGED
@@ -1 +1 @@
1
- !function(e,t,i){var s={model:{},collection:{},view:{},fn:{}};window.socss=s,s.view.toolbar=Backbone.View.extend({button:t.template('<li><a href="#" class="toolbar-button socss-button"><%= text %></a></li>'),editor:null,initialize:function(t){this.editor=t.editor;var i=this;this.$(".editor-expand").click(function(t){t.preventDefault(),e(this).blur(),i.trigger("click_expand")}),this.$(".editor-visual").click(function(t){t.preventDefault(),e(this).blur(),i.trigger("click_visual")})},addButton:function(t,i){var s=this;return e(this.button({text:t})).appendTo(this.$(".toolbar-function-buttons .toolbar-buttons")).click(function(t){t.preventDefault(),e(this).blur(),s.trigger("click_"+i)})}}),s.view.editor=Backbone.View.extend({codeMirror:null,snippets:null,toolbar:null,visualProperties:null,inspector:null,cssSelectors:[],initialize:function(e){this.setupEditor()},render:function(){var t=this;this.toolbar=new s.view.toolbar({editor:this,el:this.$(".custom-css-toolbar")}),this.toolbar.editor=this,this.toolbar.render(),this.visualProperties=new s.view.properties({editor:this,el:e("#so-custom-css-properties")}),this.visualProperties.render(),this.toolbar.on("click_expand",function(){t.toggleExpand()}),this.toolbar.on("click_visual",function(){t.visualProperties.loadCSS(t.codeMirror.getValue().trim()),t.visualProperties.show()}),this.preview=new s.view.preview({editor:this,el:this.$(".custom-css-preview")}),this.preview.render()},setupEditor:function(){var t=this;this.registerCodeMirrorAutocomplete();var s=this.$("textarea.css-editor"),r=s.val(),n=r.match(/\n/gm),o=(n&&n.length,r);s.val(o),this.codeMirror=CodeMirror.fromTextArea(s.get(0),{tabSize:2,lineNumbers:!0,mode:"css",theme:"neat",inputStyle:"contenteditable",gutters:["CodeMirror-lint-markers"],lint:!0}),this.$el.on("submit",function(){r=t.codeMirror.getValue().trim()}),e(window).bind("beforeunload",function(){if(t.codeMirror.getValue().trim()!==r)return i.loc.leave}),this.$el.find(".custom-css-container").css("overflow","visible"),this.scaleEditor(),e(window).resize(function(){t.scaleEditor()}),this.setupCodeMirrorExtensions()},registerCodeMirrorAutocomplete:function(){var e=this,t={link:1,visited:1,active:1,hover:1,focus:1,"first-letter":1,"first-line":1,"first-child":1,before:1,after:1,lang:1};CodeMirror.registerHelper("hint","css",function(i){function s(e){for(var t in e)c&&0!==t.lastIndexOf(c,0)||d.push(t)}var r=i.getCursor(),n=i.getTokenAt(r),o=CodeMirror.innerMode(i.getMode(),n.state);if("css"===o.mode.name){if("keyword"===n.type&&0==="!important".indexOf(n.string))return{list:["!important"],from:CodeMirror.Pos(r.line,n.start),to:CodeMirror.Pos(r.line,n.end)};var a=n.start,l=r.ch,c=n.string.slice(0,l-a);/[^\w$_-]/.test(c)&&(c="",a=l=r.ch);var p=CodeMirror.resolveMode("text/css"),d=[],u=o.state.state;if("top"===u){for(var h=i.getLine(r.line).trim(),v=e.cssSelectors,f=0;f<v.length;f++)-1!==v[f].selector.indexOf(h)&&d.push(v[f].selector);if(d.length)return{list:d,from:CodeMirror.Pos(r.line,0),to:CodeMirror.Pos(r.line,l)}}else if("pseudo"===u||"variable-3"===n.type?s(t):"block"===u||"maybeprop"===u?s(p.propertyKeywords):"prop"===u||"parens"===u||"at"===u||"params"===u?(s(p.valueKeywords),s(p.colorKeywords)):"media"!==u&&"media_parens"!==u||(s(p.mediaTypes),s(p.mediaFeatures)),d.length)return{list:d,from:CodeMirror.Pos(r.line,a),to:CodeMirror.Pos(r.line,l)}}})},setupCodeMirrorExtensions:function(){var e=this;this.codeMirror.on("cursorActivity",function(t){var i=t.getCursor(),s=t.getTokenAt(i);CodeMirror.innerMode(t.getMode(),s.state);if("qualifier"===s.type||"tag"===s.type||"builtin"===s.type){var r=t.getLine(i.line),n=r.substring(0,s.end);e.preview.highlight(n)}else e.preview.clearHighlight()}),this.codeMirror.on("keyup",function(e,t){(t.keyCode>=65&&t.keyCode<=90||189===t.keyCode&&!t.shiftKey||190===t.keyCode&&!t.shiftKey||51===t.keyCode&&t.shiftKey||189===t.keyCode&&t.shiftKey)&&e.showHint({completeSingle:!1})})},scaleEditor:function(){var t=e(window).outerHeight();if(this.$el.hasClass("expanded"))this.$el.find(".CodeMirror-scroll").css("max-height",""),this.codeMirror.setSize("100%",t-this.$(".custom-css-toolbar").outerHeight());else{var i=e("#so-custom-css-form"),s=e("#wpadminbar").outerHeight(!0)+e("#siteorigin-custom-css").find("> h2").outerHeight(!0)+i.find("> .custom-css-toolbar").outerHeight(!0)+i.find("> p.description").outerHeight(!0)+i.find("> p.submit").outerHeight(!0)+parseFloat(e("#wpbody-content").css("padding-bottom"));this.$el.find(".CodeMirror-scroll").css("max-height",t-s),this.codeMirror.setSize("100%","auto")}},isExpanded:function(){return this.$el.hasClass("expanded")},toggleExpand:function(){this.$el.toggleClass("expanded"),this.scaleEditor()},setExpand:function(e){e?this.$el.addClass("expanded"):this.$el.removeClass("expanded"),this.scaleEditor()},setSnippets:function(e){if(!t.isEmpty(e)){var i=this;this.snippets=new s.view.snippets({snippets:e}),this.snippets.editor=this,this.snippets.render(),this.toolbar.addButton("Snippets","snippets"),this.toolbar.on("click_snippets",function(){i.snippets.show()})}},addCode:function(e){var t=this.codeMirror,i="";i=1===t.doc.lineCount()&&0===t.doc.getLine(t.doc.lastLine()).length?"":0===t.doc.getLine(t.doc.lastLine()).length?"\n":"\n\n",t.doc.setCursor(t.doc.lastLine(),t.doc.getLine(t.doc.lastLine()).length),t.doc.replaceSelection(i+e)},addEmptySelector:function(e){this.addCode(e+" {\n \n}")},setInspector:function(e){var t=this;this.inspector=e,this.cssSelectors=e.pageSelectors,e.on("click_selector",function(e){t.visualProperties.isVisible()?t.visualProperties.addSelector(e):t.addEmptySelector(e)}),e.on("click_property",function(e){t.visualProperties.isVisible()||t.codeMirror.replaceSelection(e+";\n ")}),e.on("set_active_element",function(e,i){t.visualProperties.isVisible()&&i.length&&t.visualProperties.addSelector(i[0].selector)})}}),s.view.preview=Backbone.View.extend({template:t.template(e("#template-preview-window").html()),editor:null,originalUri:null,currentUri:null,initialize:function(e){this.editor=e.editor;var t=this;this.editor.codeMirror.on("change",function(e,i){t.updatePreviewCss()})},render:function(){var t=this;this.$el.html(this.template()),this.$("#preview-iframe").attr("src",i.homeURL).on("load",function(){var i=e(this);t.currentUri=new URI(i.contents().get(0).location.href),t.currentUri.removeQuery("so_css_preview"),t.$("#preview-navigator input").val(t.currentUri.toString()),t.currentUri.addQuery("so_css_preview",1),i.contents().find("a").each(function(){var t=e(this).attr("href");if(void 0===t)return!0;var i=-1===t.indexOf("?")?"?":"&";e(this).attr("href",t+i+"so_css_preview=1")}),t.updatePreviewCss()}).mouseleave(function(){t.clearHighlight()}),this.$("#preview-navigator input").keydown(function(i){var s=e(this);if(13==i.keyCode){i.preventDefault();var r=new URI(s.val());t.originalUri.host()!==r.host()||t.originalUri.protocol()!==r.protocol()?(s.blur(),alert(s.data("invalid-uri")),s.focus()):(r.addQuery("so_css_preview",1),t.$("#preview-iframe").attr("src",r.toString()))}}),this.originalUri=new URI(i.homeURL),this.currentUri=new URI(i.homeURL),this.currentUri.removeQuery("so_css_preview"),this.$("#preview-navigator input").val(this.currentUri.toString()),this.currentUri.addQuery("so_css_preview",1)},updatePreviewCss:function(){var e=this.$("#preview-iframe");if(0!==e.length){var t=e.contents().find("head");0===t.find("style.siteorigin-custom-css").length&&t.append('<style class="siteorigin-custom-css" type="text/css"></style>');var i=t.find("style.siteorigin-custom-css"),s=this.editor.codeMirror.getValue().trim();i.html(s)}},highlight:function(e){try{this.editor.inspector.hl.highlight(e)}catch(e){console.log("No inspector to highlight with")}},clearHighlight:function(){try{this.editor.inspector.hl.clear()}catch(e){console.log("No inspector to highlight with")}}}),s.view.snippets=Backbone.View.extend({template:t.template(e("#template-snippet-browser").html()),snippet:t.template('<li class="snippet"><%- name %></li>'),className:"css-editor-snippet-browser",snippets:null,editor:null,events:{"click .close":"hide","click .buttons .insert-snippet":"insertSnippet"},currentSnippet:null,initialize:function(e){this.snippets=e.snippets},render:function(){var t=this,i=function(i){i.preventDefault();var s=e(this);t.$(".snippets li.snippet").removeClass("active"),e(this).addClass("active"),t.viewSnippet({name:s.html(),description:s.data("description"),css:s.data("css")})};this.$el.html(this.template());for(var s=0;s<this.snippets.length;s++)e(this.snippet({name:this.snippets[s].Name})).data({description:this.snippets[s].Description,css:this.snippets[s].css}).appendTo(this.$("ul.snippets")).click(i);return t.$(".snippets li.snippet").eq(0).click(),this.attach(),this},viewSnippet:function(e){var t=this.$(".main .snippet-view");t.find(".snippet-title").html(e.name),t.find(".snippet-description").html(e.description),t.find(".snippet-code").html(e.css),this.currentSnippet=e},insertSnippet:function(){var e=this.editor.codeMirror,t=this.currentSnippet.css,i="";i=1===e.doc.lineCount()&&0===e.doc.getLine(e.doc.lastLine()).length?"":0===e.doc.getLine(e.doc.lastLine()).length?"\n":"\n\n",e.doc.setCursor(e.doc.lastLine(),e.doc.getLine(e.doc.lastLine()).length),e.doc.replaceSelection(i+t),this.hide()},attach:function(){this.$el.appendTo("body")},show:function(){this.$el.show()},hide:function(){this.$el.hide()}}),s.view.properties=Backbone.View.extend({model:s.model.cssRules,tabTemplate:t.template('<li data-section="<%- id %>"><span class="fa fa-<%- icon %>"></span> <%- title %></li>'),sectionTemplate:t.template('<div class="section" data-section="<%- id %>"><table class="fields-table"><tbody></tbody></table></div>'),controllerTemplate:t.template('<tr><th scope="row"><%- title %></th><td></td></tr>'),propertyControllers:[],editor:null,css:"",parsed:{},activeSelector:"",editorExpandedBefore:!1,events:{"click .close":"hide"},initialize:function(e){this.parser=window.css,this.editor=e.editor},render:function(){var r=this;this.$(".section-tabs").empty(),this.$(".sections").empty(),this.$(".toolbar select").off(),r.propertyControllers=[];var n=i.propertyControllers;for(var o in n){var a=(e(this.tabTemplate({id:o,icon:n[o].icon,title:n[o].title})).appendTo(this.$(".section-tabs")),e(this.sectionTemplate({id:o})).appendTo(this.$(".sections")));if(!t.isEmpty(n[o].controllers))for(var l=0;l<n[o].controllers.length;l++){var c,p=e(r.controllerTemplate({title:n[o].controllers[l].title})).appendTo(a.find("tbody")),d=n[o].controllers[l];c=void 0===s.view.properties.controllers[d.type]?new s.view.propertyController({el:p.find("td"),propertiesView:r,args:void 0===d.args?{}:d.args}):new s.view.properties.controllers[d.type]({el:p.find("td"),propertiesView:r,args:void 0===d.args?{}:d.args}),r.propertyControllers.push(c),c.render(),c.initChangeEvents()}}this.$(".section-tabs li").click(function(){var t=e(this),i=r.$('.sections .section[data-section="'+t.data("section")+'"]');r.$(".sections .section").not(i).hide().removeClass("active"),i.show().addClass("active"),r.$(".section-tabs li").not(t).removeClass("active"),t.addClass("active")}).eq(0).click(),this.$(".toolbar select").change(function(){r.setActivateSelector(e(this).find(":selected").data("selector"))})},setRuleValue:function(e,i){if(void 0!==this.activeSelector&&void 0!==this.activeSelector.declarations){for(var s=this.activeSelector.declarations,r=!0,n=!1,o=0;o<s.length;o++)if(s[o].property===e){r=!1;var a=s[o];a.value!==i&&(a.value=i,n=!0),t.isEmpty(a.value)&&s.splice(s.indexOf(a));break}r&&!t.isEmpty(i)&&(s.push({property:e,value:i,type:"declaration"}),n=!0),n&&this.updateMainEditor(!1)}},addImport:function(e){var i=t.filter(this.parsed.stylesheet.rules,function(e){return"import"===e.type});t.any(i,function(t){return t.import===e.import})||(this.parsed.stylesheet.rules.unshift(e),this.updateMainEditor(!1))},findImport:function(e){return t.find(this.parsed.stylesheet.rules,function(t){return"import"===t.type&&t.import.indexOf(e)>-1})},updateImport:function(e,t){var i=this.findImport(e);i.import!==t.import&&(i.import=t.import,this.updateMainEditor(!1))},removeImport:function(e){var i=t.findIndex(this.parsed.stylesheet.rules,function(t){return"import"===t.type&&t.import.indexOf(e)>-1});i>-1&&this.parsed.stylesheet.rules.splice(i,1)},getRuleValue:function(e){if(void 0===this.activeSelector||void 0===this.activeSelector.declarations)return"";for(var t=this.activeSelector.declarations,i=0;i<t.length;i++)if(t[i].property===e)return t[i].value;return""},updateMainEditor:function(e){this.editor.codeMirror.setValue(this.parser.stringify(this.parsed))},show:function(){this.editorExpandedBefore=this.editor.isExpanded(),this.editor.setExpand(!0),this.$el.show().animate({left:0},"fast")},hide:function(){this.editor.setExpand(this.editorExpandedBefore),this.$el.animate({left:-338},"fast",function(){e(this).hide()}),this.updateMainEditor(!0)},isVisible:function(){return this.$el.is(":visible")},loadCSS:function(i,s){this.css=i,this.parsed=this.parser.parse(i,{silent:!0});for(var r=this.parsed.stylesheet.rules,n=this.$(".toolbar select").empty(),o=0;o<r.length;o++){var a=r[o];if(t.contains(["rule","media"],a.type))if("media"===a.type)for(var l=0;l<a.rules.length;l++){var c="@media "+a.media,p=a.rules[l];"rule"==p.type&&n.append(e("<option>").html(c+": "+p.selectors.join(",")).attr("val",c+": "+p.selectors.join(",")).data("selector",p))}else n.append(e("<option>").html(a.selectors.join(",")).attr("val",a.selectors.join(",")).data("selector",a))}void 0===s&&(s=n.find("option").eq(0).attr("val")),t.isEmpty(s)||n.val(s).change()},setActivateSelector:function(e){this.activeSelector=e;for(var t=0;t<this.propertyControllers.length;t++)this.propertyControllers[t].refreshFromRule()},addSelector:function(e){var t=this.$(".toolbar select");t.val(e),t.val()===e?t.change():(this.editor.addEmptySelector(e),this.loadCSS(this.editor.codeMirror.getValue().trim(),e)),t.addClass("highlighted"),setTimeout(function(){t.removeClass("highlighted")},2e3)}}),s.view.propertyController=Backbone.View.extend({template:t.template('<input type="text" value="" />'),activeRule:null,args:null,propertiesView:null,initialize:function(e){this.args=e.args,this.propertiesView=e.propertiesView,this.on("set_value",this.updateRule,this),this.on("change",this.updateRule,this)},render:function(){this.$el.append(e(this.template({}))),this.field=this.$("input")},initChangeEvents:function(){var t=this;this.field.on("change keyup",function(){t.trigger("change",e(this).val())})},updateRule:function(){this.propertiesView.setRuleValue(this.args.property,this.getValue())},refreshFromRule:function(){var e=this.propertiesView.getRuleValue(this.args.property);this.setValue(e,{silent:!0})},getValue:function(){return this.field.val()},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.val(e),i.silent||this.trigger("set_value",e)},reset:function(e){e=t.extend({silent:!1},e),this.setValue("",e)}}),s.view.properties.controllers={},s.view.properties.controllers.color=s.view.propertyController.extend({template:t.template('<input type="text" value="" />'),render:function(){this.$el.append(e(this.template({}))),this.field=this.$el.find("input"),this.field.minicolors({})},initChangeEvents:function(){var e=this;this.field.on("change keyup",function(){e.trigger("change",e.field.minicolors("value"))})},getValue:function(){return this.field.minicolors("value").trim()},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.minicolors("value",e),i.silent||this.trigger("set_value",e)}}),s.view.properties.controllers.select=s.view.propertyController.extend({template:t.template("<select></select>"),render:function(){this.$el.append(e(this.template({}))),this.field=this.$el.find("select"),this.field.append(e('<option value=""></option>').html(""));for(var t in this.args.options)this.field.append(e("<option></option>").attr("value",t).html(this.args.options[t]));void 0!==this.args.option_icons&&this.setupVisualSelect()},setupVisualSelect:function(){var t=this;this.field.hide();var i=e('<div class="select-tabs"></div>').appendTo(this.$el);e('<div class="select-tab" data-value=""><span class="fa fa-circle-o"></span></div>').appendTo(i);for(var s in this.args.option_icons)e('<div class="select-tab"></div>').appendTo(i).append(e('<span class="fa"></span>').addClass("fa-"+this.args.option_icons[s])).attr("data-value",s);i.find(".select-tab").css("width",100/i.find(">div").length+"%").click(function(){var s=e(this);i.find(".select-tab").removeClass("active"),s.addClass("active"),t.field.val(s.data("value")).change()})},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.val(e),this.$(".select-tabs .select-tab").removeClass("active").filter('[data-value="'+e+'"]').addClass("active"),i.silent||this.trigger("set_value",e)}}),s.view.properties.controllers.image=s.view.propertyController.extend({template:t.template('<input type="text" value="" /> <span class="select socss-button"><span class="fa fa-upload"></span></span>'),render:function(){var t=this;this.media=wp.media({title:i.loc.select_image,library:{type:"image"},button:{text:i.loc.select,close:!1}}),this.$el.append(e(this.template({select:i.loc.select}))),this.field=this.$el.find("input"),this.$(".select").click(function(){t.media.open()}),this.media.on("select",function(){var e=this.state().get("selection").first().attributes,i=t.args.value.replace("{{url}}",e.url);t.field.val(i).change(),t.media.close()},this.media)}}),s.view.properties.controllers.measurement=s.view.propertyController.extend({wrapperClass:"socss-field-measurement",render:function(){this.$el.append(e(this.template({}))),this.field=this.$("input"),this.setupMeasurementField(this.field,{})},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.val(e).trigger("measurement_refresh"),i.silent||this.trigger("set_value",e)},units:["px","%","em","cm","mm","in","pt","pc","ex","ch","rem","vw","vh","vmin","vmax"],parseUnits:function(e){var t=function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},i=this.units.map(t),s=new RegExp("([0-9\\.\\-]+)("+i.join("|")+")?","i"),r=s.exec(e);return null===r?{value:"",unit:""}:{value:r[1],unit:void 0===r[2]?"":r[2]}},setupMeasurementField:function(i,s){var r=this,n=i.parent();s=t.extend({defaultUnit:"px"},s),i.hide(),n.addClass(this.wrapperClass).data("unit",s.defaultUnit);for(var o=e('<input type="text" class="socss-field-input"/>').appendTo(n),a=e('<span class="dashicons dashicons-arrow-down"></span>').appendTo(n),l=e('<ul class="dropdown"></ul>').appendTo(n),c=e('<span class="units"></span>').html(s.defaultUnit).appendTo(n),p=0;p<r.units.length;p++){var d=e("<li></li>").html(r.units[p]).data("unit",r.units[p]);r.units[p]===s.defaultUnit&&d.addClass("active"),l.append(d)}var u=function(){var e=r.parseUnits(o.val());""!==e.unit&&e.unit!==n.data("unit")&&(o.val(e.value),h(e.unit)),""===e.value?i.val(""):i.val(e.value+n.data("unit"))},h=function(e){c.html(e),n.data("unit",e),o.trigger("keydown")};a.click(function(){l.toggle()}),l.find("li").click(function(){l.toggle(),h(e(this).data("unit")),u(),i.trigger("change")}),o.on("keyup keydown",function(t){var i=(e(this),"");"keydown"===t.type&&(t.keyCode>=48&&t.keyCode<=57?i=String.fromCharCode(t.keyCode):189===t.keyCode?i="-":190===t.keyCode&&(i="."));var s=e('<span class="socss-hidden-placeholder"></span>').css({"font-size":"14px"}).html(o.val()+i).appendTo("body"),r=s.width();r=Math.min(r,63),s.remove(),c.css("left",r+12)}),o.on("keyup",function(e){u(),i.trigger("change")}),i.on("measurement_refresh",function(){var t=r.parseUnits(i.val());o.val(t.value);var a=""===t.unit?s.defaultUnit:t.unit;n.data("unit",a),c.html(a);var l=e('<span class="socss-hidden-placeholder"></span>').css({"font-size":"14px"}).html(t.value).appendTo("body"),p=l.width();p=Math.min(p,63),l.remove(),c.css("left",p+12)});var v=e('<div class="socss-diw"></div>').appendTo(n),f=e('<div class="dec-button socss-button"><span class="fa fa-minus"></span></div>').appendTo(v),m=e('<div class="inc-button socss-button"><span class="fa fa-plus"></span></div>').appendTo(v),g=function(e){var t=Number.parseInt(r.parseUnits(i.val()).value);Number.isNaN(t)&&(t=0);var s=t+e;o.val(s),u(),i.trigger("change").trigger("measurement_refresh")},w=function(e){var t,i,s=e.is(".dec-button")?-1:1;e.mousedown(function(){g(s),i=setTimeout(function(){t=setInterval(function(){g(s)},50)},500)}).on("mouseup mouseout",function(){i&&(clearTimeout(i),i=null),t&&(clearInterval(t),t=null)})};w(f),w(m)}}),s.view.properties.controllers.number=s.view.propertyController.extend({render:function(){this.$el.append(e(this.template({}))),this.field=this.$("input"),this.setupNumberField(this.field,this.args)},setupNumberField:function(i,s){s=t.extend({change:null,default:0,increment:1,decrement:-1,max:null,min:null},s);var r=i.parent();r.addClass("socss-field-number");var n=e('<div class="socss-diw"></div>').appendTo(r),o=e('<div class="dec-button socss-button">-</div>').appendTo(n);e('<div class="inc-button socss-button">+</div>').appendTo(n);return n.find("> div").click(function(t){t.preventDefault();var r=s.default;""!==i.val()&&(r=Number(i.val())),r+=e(this).is(o)?s.decrement:s.increment,r=Math.round(100*r)/100,null!==s.max&&(r=Math.min(s.max,r)),null!==s.min&&(r=Math.max(s.min,r)),i.val(r),i.trigger("change")}),this}}),s.view.properties.controllers.sides=s.view.propertyController.extend({template:t.template(e("#template-sides-field").html().trim()),controllers:[],render:function(){var i=this;this.$el.append(e(this.template({}))),this.field=this.$el.find("input"),i.args.hasAll||(this.$(".select-tab").eq(0).remove(),this.$(".select-tab").css("width","25%")),this.$(".select-tab").each(function(){for(var r=e(this).data("direction"),n=e('<li class="side">').appendTo(i.$(".sides")).hide(),o=0;o<i.args.controllers.length;o++){var a=i.args.controllers[o];if(s.view.properties.controllers[a.type],!0){var l="";l="all"===r?a.args.propertyAll:a.args.property.replace("{dir}",r);var c=t.extend({},a.args,{property:l}),p=new s.view.properties.controllers[a.type]({el:e("<div>").appendTo(n),propertiesView:i.propertiesView,args:c});p.render(),p.initChangeEvents(),i.propertiesView.propertyControllers.push(p)}}e(this).on("click",function(){i.$(".select-tab").removeClass("active"),e(this).addClass("active"),i.$(".sides .side").hide(),n.show()})}),this.$(".select-tab").eq(0).click()}})}(jQuery,_,socssOptions),jQuery(function(e){var t=window.socss,i=new t.view.editor({el:e("#so-custom-css-form").get(0)});i.render(),i.setSnippets(socssOptions.snippets),window.socss.mainEditor=i,e("#so-custom-css-getting-started a.hide").click(function(t){t.preventDefault(),e("#so-custom-css-getting-started").slideUp(),e.get(e(this).attr("href"))})});
1
+ !function(e,t,i){var s={model:{},collection:{},view:{},fn:{}};window.socss=s,s.model.CustomCssModel=Backbone.Model.extend({defaults:{postId:null,postTitle:null,css:null},urlRoot:i.postCssUrlRoot,url:function(){return this.urlRoot+"&postId="+this.get("postId")}}),s.model.CustomCssCollection=Backbone.Collection.extend({model:s.model.CustomCssModel,modelId:function(e){return e.postId}}),s.model.CSSEditorModel=Backbone.Model.extend({defaults:{customCssPosts:null}}),s.view.toolbar=Backbone.View.extend({button:t.template('<li><a href="#<%= action %>" class="toolbar-button socss-button"><%= text %></a></li>'),events:{"click .socss-button":"triggerEvent"},triggerEvent:function(t){t.preventDefault();var i=e(t.currentTarget);i.blur();var s=i.attr("href").replace("#","");this.$el.trigger("click_"+s)},addButton:function(t,i){return e(this.button({text:t,action:i})).appendTo(this.$(".toolbar-function-buttons .toolbar-buttons"))}}),s.view.editor=Backbone.View.extend({codeMirror:null,snippets:null,toolbar:null,visualProperties:null,inspector:null,cssSelectors:[],initValue:null,events:{"click_expand .custom-css-toolbar":"toggleExpand","click_visual .custom-css-toolbar":"showVisualEditor",submit:"onSubmit"},initialize:function(e){this.listenTo(this.model,"change:selectedPost",this.getSelectedPostCss),this.getSelectedPostCss().then(function(){e.openVisualEditor&&this.showVisualEditor()}.bind(this))},getSelectedPostCss:function(){var t,i=this.model.get("selectedPost");return t=i&&!i.has("css")?i.fetch():(new e.Deferred).resolve(),t.then(this.render.bind(this))},render:function(){var t=this.model.get("selectedPost");return t&&!t.has("css")?this:(this.codeMirror||this.setupEditor(),this.toolbar||(this.toolbar=new s.view.toolbar({el:this.$(".custom-css-toolbar"),model:this.model}),this.toolbar.render()),this.visualProperties||(this.visualProperties=new s.view.properties({editor:this,el:e("#so-custom-css-properties")}),this.visualProperties.render()),this.preview||(this.preview=new s.view.preview({editor:this,model:this.model,el:this.$(".custom-css-preview"),initURL:i.homeURL}),this.preview.render()),t&&(this.codeMirror.setValue(t.get("css")),this.codeMirror.clearHistory()),this)},setupEditor:function(){this.registerCodeMirrorAutocomplete();var t=this.$("textarea.css-editor");this.initValue=t.val();var s=this.initValue.match(/\n/gm),r=(s&&s.length,this.initValue);t.val(r),this.codeMirror=CodeMirror.fromTextArea(t.get(0),{tabSize:2,lineNumbers:!0,mode:"css",theme:"neat",inputStyle:"contenteditable",gutters:["CodeMirror-lint-markers"],lint:!0,search:!0,dialog:!0,annotateScrollbar:!0,extraKeys:{"Ctrl-F":"findPersistent","Alt-G":"jumpToLine"}}),this.codeMirror.on("change",function(e,t){var i=this.model.get("selectedPost");i&&i.get("css")!==e.getValue().trim()&&i.set("css",e.getValue().trim())}.bind(this)),e(window).on("beforeunload",function(){if(this.codeMirror.getValue().trim()!==this.initValue)return i.loc.leave}.bind(this)),this.$el.find(".custom-css-container").css("overflow","visible"),this.scaleEditor(),e(window).on("resize",function(){this.scaleEditor()}.bind(this)),this.setupCodeMirrorExtensions()},onSubmit:function(){this.initValue=this.codeMirror.getValue().trim()},registerCodeMirrorAutocomplete:function(){var e={link:1,visited:1,active:1,hover:1,focus:1,"first-letter":1,"first-line":1,"first-child":1,before:1,after:1,lang:1};CodeMirror.registerHelper("hint","css",function(t){function i(e){for(var t in e)a&&0!==t.lastIndexOf(a,0)||p.push(t)}var s=t.getCursor(),r=t.getTokenAt(s),o=CodeMirror.innerMode(t.getMode(),r.state);if("css"===o.mode.name){if("keyword"===r.type&&0==="!important".indexOf(r.string))return{list:["!important"],from:CodeMirror.Pos(s.line,r.start),to:CodeMirror.Pos(s.line,r.end)};var n=r.start,l=s.ch,a=r.string.slice(0,l-n);/[^\w$_-]/.test(a)&&(a="",n=l=s.ch);var c=CodeMirror.resolveMode("text/css"),p=[],d=o.state.state;if("top"===d){for(var h=t.getLine(s.line).trim(),u=this.cssSelectors,v=0;v<u.length;v++)-1!==u[v].selector.indexOf(h)&&p.push(u[v].selector);if(p.length)return{list:p,from:CodeMirror.Pos(s.line,0),to:CodeMirror.Pos(s.line,l)}}else if("pseudo"===d||"variable-3"===r.type?i(e):"block"===d||"maybeprop"===d?i(c.propertyKeywords):"prop"===d||"parens"===d||"at"===d||"params"===d?(i(c.valueKeywords),i(c.colorKeywords)):"media"!==d&&"media_parens"!==d||(i(c.mediaTypes),i(c.mediaFeatures)),p.length)return{list:p,from:CodeMirror.Pos(s.line,n),to:CodeMirror.Pos(s.line,l)}}}.bind(this))},setupCodeMirrorExtensions:function(){this.codeMirror.on("cursorActivity",function(e){var t=e.getCursor(),i=e.getTokenAt(t);CodeMirror.innerMode(e.getMode(),i.state);if("qualifier"===i.type||"tag"===i.type||"builtin"===i.type){var s=e.getLine(t.line),r=s.substring(0,i.end);this.preview.highlight(r)}else this.preview.clearHighlight()}.bind(this)),this.codeMirror.on("keyup",function(e,t){(t.keyCode>=65&&t.keyCode<=90||189===t.keyCode&&!t.shiftKey||190===t.keyCode&&!t.shiftKey||51===t.keyCode&&t.shiftKey||189===t.keyCode&&t.shiftKey)&&e.showHint({completeSingle:!1})})},scaleEditor:function(){var t=e(window).outerHeight();if(this.$el.hasClass("expanded"))this.$el.find(".CodeMirror-scroll").css("max-height",""),this.codeMirror.setSize("100%",t-this.$(".custom-css-toolbar").outerHeight());else{var i=e("#so-custom-css-form"),s=e("#wpadminbar").outerHeight(!0)+e("#siteorigin-custom-css").find("> h2").outerHeight(!0)+i.find("> .custom-css-toolbar").outerHeight(!0)+i.find("> p.description").outerHeight(!0)+i.find("> p.submit").outerHeight(!0)+parseFloat(e("#wpbody-content").css("padding-bottom"));this.$el.find(".CodeMirror-scroll").css("max-height",t-s),this.codeMirror.setSize("100%","auto")}},isExpanded:function(){return this.$el.hasClass("expanded")},toggleExpand:function(){this.$el.toggleClass("expanded"),this.scaleEditor()},setExpand:function(e){e?this.$el.addClass("expanded"):this.$el.removeClass("expanded"),this.scaleEditor()},showVisualEditor:function(){this.visualProperties.loadCSS(this.codeMirror.getValue().trim()),this.visualProperties.show()},setSnippets:function(e){t.isEmpty(e)||(this.snippets=new s.view.snippets({snippets:e}),this.snippets.editor=this,this.snippets.render(),this.toolbar.addButton("Snippets","snippets"),this.toolbar.on("click_snippets",function(){this.snippets.show()}.bind(this)))},addCode:function(e){var t=this.codeMirror,i="";i=1===t.doc.lineCount()&&0===t.doc.getLine(t.doc.lastLine()).length?"":0===t.doc.getLine(t.doc.lastLine()).length?"\n":"\n\n",t.doc.setCursor(t.doc.lastLine(),t.doc.getLine(t.doc.lastLine()).length),t.doc.replaceSelection(i+e)},addEmptySelector:function(e){this.addCode(e+" {\n \n}")},setInspector:function(e){this.inspector=e,this.cssSelectors=e.pageSelectors,e.on("click_selector",function(e){this.visualProperties.isVisible()?this.visualProperties.addSelector(e):this.addEmptySelector(e)}.bind(this)),e.on("click_property",function(e){this.visualProperties.isVisible()||this.codeMirror.replaceSelection(e+";\n ")}.bind(this)),e.on("set_active_element",function(e,t){this.visualProperties.isVisible()&&t.length&&this.visualProperties.addSelector(t[0].selector)}.bind(this))}}),s.view.preview=Backbone.View.extend({template:t.template(e("#template-preview-window").html()),editor:null,originalUri:null,currentUri:null,events:{"load #preview-iframe":"initPreview","mouseleave #preview-iframe":"clearHighlight",'keydown #preview-navigator input[type="text"]':"reloadPreview"},initialize:function(e){this.editor=e.editor,this.listenTo(this.model,"change:selectedPost",this.render.bind(this)),this.originalUri=new URI(e.initURL),this.currentUri=new URI(e.initURL),this.editor.codeMirror.on("change",function(e,t){this.updatePreviewCss()}.bind(this))},render:function(){var e=this.model.get("selectedPost");if(e&&!e.has("postUrl"))return e.fetch().then(this.render.bind(this)),this;this.$el.html(this.template()),e&&(this.currentUri=new URI(e.get("postUrl"))),this.currentUri.removeQuery("so_css_preview",1),this.$("#preview-navigator input").val(this.currentUri.toString()),this.currentUri.addQuery("so_css_preview",1),this.$("#preview-iframe").attr("src",this.currentUri.toString())},initPreview:function(){var t=this.$("#preview-iframe");this.currentUri=new URI(t.contents().get(0).location.href),this.currentUri.removeQuery("so_css_preview"),this.$("#preview-navigator input").val(this.currentUri.toString()),this.currentUri.addQuery("so_css_preview",1),t.contents().find("a").each(function(){var t=e(this).attr("href");if(void 0===t)return!0;var i=-1===t.indexOf("?")?"?":"&";e(this).attr("href",t+i+"so_css_preview=1")}),this.updatePreviewCss()},reloadPreview:function(e){var t=this.$('#preview-navigator input[type="text"]');if(13===e.keyCode){e.preventDefault();var i=new URI(t.val());this.originalUri.host()!==i.host()||this.originalUri.protocol()!==i.protocol()?(t.blur(),alert(t.data("invalid-uri")),t.focus()):(i.addQuery("so_css_preview",1),this.$("#preview-iframe").attr("src",i.toString()))}},updatePreviewCss:function(){var e=this.$("#preview-iframe");if(0!==e.length){var t=e.contents().find("head");0===t.find("style.siteorigin-custom-css").length&&t.append('<style class="siteorigin-custom-css" type="text/css"></style>');var i=t.find("style.siteorigin-custom-css"),s=this.editor.codeMirror.getValue().trim();i.html(s)}},highlight:function(e){try{this.editor.inspector.hl.highlight(e)}catch(e){console.log("No inspector to highlight with")}},clearHighlight:function(){try{this.editor.inspector.hl.clear()}catch(e){console.log("No inspector to highlight with")}}}),s.view.snippets=Backbone.View.extend({template:t.template(e("#template-snippet-browser").html()),snippet:t.template('<li class="snippet"><%- name %></li>'),className:"css-editor-snippet-browser",snippets:null,editor:null,events:{"click .close":"hide","click .buttons .insert-snippet":"insertSnippet","click .snippet":"clickSnippet"},currentSnippet:null,initialize:function(e){this.snippets=e.snippets},render:function(){this.$el.html(this.template());for(var t=0;t<this.snippets.length;t++)e(this.snippet({name:this.snippets[t].Name})).data({description:this.snippets[t].Description,css:this.snippets[t].css}).appendTo(this.$("ul.snippets"));return this.$(".snippets li.snippet").eq(0).click(),this.attach(),this},clickSnippet:function(t){t.preventDefault();var i=e(t.currentTarget);this.$(".snippets li.snippet").removeClass("active"),e(this).addClass("active"),this.viewSnippet({name:i.html(),description:i.data("description"),css:i.data("css")})},viewSnippet:function(e){var t=this.$(".main .snippet-view");t.find(".snippet-title").html(e.name),t.find(".snippet-description").html(e.description),t.find(".snippet-code").html(e.css),this.currentSnippet=e},insertSnippet:function(){var e=this.editor.codeMirror,t=this.currentSnippet.css,i="";i=1===e.doc.lineCount()&&0===e.doc.getLine(e.doc.lastLine()).length?"":0===e.doc.getLine(e.doc.lastLine()).length?"\n":"\n\n",e.doc.setCursor(e.doc.lastLine(),e.doc.getLine(e.doc.lastLine()).length),e.doc.replaceSelection(i+t),this.hide()},attach:function(){this.$el.appendTo("body")},show:function(){this.$el.show()},hide:function(){this.$el.hide()}}),s.view.properties=Backbone.View.extend({tabTemplate:t.template('<li data-section="<%- id %>"><span class="fa fa-<%- icon %>"></span> <%- title %></li>'),sectionTemplate:t.template('<div class="section" data-section="<%- id %>"><table class="fields-table"><tbody></tbody></table></div>'),controllerTemplate:t.template('<tr><th scope="row"><%- title %></th><td></td></tr>'),propertyControllers:[],editor:null,css:"",parsed:{},activeSelector:"",editorExpandedBefore:!1,events:{"click .close":"hide","click .section-tabs li":"onTabClick","change .toolbar select":"onToolbarSelectChange"},initialize:function(e){this.parser=window.css,this.editor=e.editor},render:function(){this.$(".section-tabs").empty(),this.$(".sections").empty(),this.$(".toolbar select").off(),this.propertyControllers=[];var r=i.propertyControllers;for(var o in r){var n=(e(this.tabTemplate({id:o,icon:r[o].icon,title:r[o].title})).appendTo(this.$(".section-tabs")),e(this.sectionTemplate({id:o})).appendTo(this.$(".sections")));if(!t.isEmpty(r[o].controllers))for(var l=0;l<r[o].controllers.length;l++){var a,c=e(this.controllerTemplate({title:r[o].controllers[l].title})).appendTo(n.find("tbody")),p=r[o].controllers[l];a=void 0===s.view.properties.controllers[p.type]?new s.view.propertyController({el:c.find("td"),propertiesView:this,args:void 0===p.args?{}:p.args}):new s.view.properties.controllers[p.type]({el:c.find("td"),propertiesView:this,args:void 0===p.args?{}:p.args}),this.propertyControllers.push(a),a.render()}}this.$(".section-tabs li").eq(0).click()},onTabClick:function(t){var i=e(t.currentTarget),s=this.$('.sections .section[data-section="'+i.data("section")+'"]');this.$(".sections .section").not(s).hide().removeClass("active"),s.show().addClass("active"),this.$(".section-tabs li").not(i).removeClass("active"),i.addClass("active")},onToolbarSelectChange:function(t){this.setActiveSelector(e(t.currentTarget).find(":selected").data("selector"))},setRuleValue:function(e,i){if(void 0!==this.activeSelector&&void 0!==this.activeSelector.declarations){for(var s=this.activeSelector.declarations,r=!0,o=!1,n=0;n<s.length;n++)if(s[n].property===e){r=!1;var l=s[n];l.value!==i&&(l.value=i,o=!0),t.isEmpty(l.value)&&s.splice(s.indexOf(l));break}r&&!t.isEmpty(i)&&(s.push({property:e,value:i,type:"declaration"}),o=!0),o&&this.updateMainEditor(!1)}},addImport:function(e){var i=t.filter(this.parsed.stylesheet.rules,function(e){return"import"===e.type});t.any(i,function(t){return t.import===e.import})||(this.parsed.stylesheet.rules.unshift(e),this.updateMainEditor(!1))},findImport:function(e){return t.find(this.parsed.stylesheet.rules,function(t){return"import"===t.type&&t.import.indexOf(e)>-1})},updateImport:function(e,t){var i=this.findImport(e);i.import!==t.import&&(i.import=t.import,this.updateMainEditor(!1))},removeImport:function(e){var i=t.findIndex(this.parsed.stylesheet.rules,function(t){return"import"===t.type&&t.import.indexOf(e)>-1});i>-1&&this.parsed.stylesheet.rules.splice(i,1)},getRuleValue:function(e){if(void 0===this.activeSelector||void 0===this.activeSelector.declarations)return"";for(var t=this.activeSelector.declarations,i=0;i<t.length;i++)if(t[i].property===e)return t[i].value;return""},updateMainEditor:function(e){this.editor.codeMirror.setValue(this.parser.stringify(this.parsed))},show:function(){this.editorExpandedBefore=this.editor.isExpanded(),this.editor.setExpand(!0),this.$el.show().animate({left:0},"fast")},hide:function(){this.editor.setExpand(this.editorExpandedBefore),this.$el.animate({left:-338},"fast",function(){e(this).hide()}),this.updateMainEditor(!0)},isVisible:function(){return this.$el.is(":visible")},loadCSS:function(i,s){this.css=i,this.parsed=this.parser.parse(i,{silent:!0});for(var r=this.parsed.stylesheet.rules,o=this.$(".toolbar select").empty(),n=0;n<r.length;n++){var l=r[n];if(t.contains(["rule","media"],l.type))if("media"===l.type)for(var a=0;a<l.rules.length;a++){var c="@media "+l.media,p=l.rules[a];"rule"==p.type&&o.append(e("<option>").html(c+": "+p.selectors.join(",")).attr("val",c+": "+p.selectors.join(",")).data("selector",p))}else o.append(e("<option>").html(l.selectors.join(",")).attr("val",l.selectors.join(",")).data("selector",l))}void 0===s&&(s=o.find("option").eq(0).attr("val")),t.isEmpty(s)||o.val(s).change()},setActiveSelector:function(e){this.activeSelector=e;for(var t=0;t<this.propertyControllers.length;t++)this.propertyControllers[t].refreshFromRule()},addSelector:function(e){var t=this.$(".toolbar select");t.val(e),t.val()===e?t.change():(this.editor.addEmptySelector(e),this.loadCSS(this.editor.codeMirror.getValue().trim(),e)),t.addClass("highlighted"),setTimeout(function(){t.removeClass("highlighted")},2e3)}}),s.view.propertyController=Backbone.View.extend({template:t.template('<input type="text" value="" class="socss-property-controller-input"/>'),activeRule:null,args:null,propertiesView:null,events:{"change .socss-property-controller-input":"onChange","keyup input.socss-property-controller-input":"onChange"},initialize:function(e){this.args=e.args,this.propertiesView=e.propertiesView,this.events=t.extend(s.view.propertyController.prototype.events,this.events),this.delegateEvents(this.events),this.on("set_value",this.updateRule,this),this.on("change",this.updateRule,this)},render:function(){this.$el.append(e(this.template({}))),this.field=this.$("input.socss-property-controller-input")},onChange:function(){this.trigger("change",this.field.val())},updateRule:function(){this.propertiesView.setRuleValue(this.args.property,this.getValue())},refreshFromRule:function(){var e=this.propertiesView.getRuleValue(this.args.property);this.setValue(e,{silent:!0})},getValue:function(){return this.field.val()},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.val(e),i.silent||this.trigger("set_value",e)},reset:function(e){e=t.extend({silent:!1},e),this.setValue("",e)}}),s.view.properties.controllers={},s.view.properties.controllers.color=s.view.propertyController.extend({render:function(){s.view.propertyController.prototype.render.apply(this,arguments),this.field.minicolors({})},onChange:function(){this.trigger("change",this.field.minicolors("value"))},getValue:function(){return this.field.minicolors("value").trim()},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.minicolors("value",e),i.silent||this.trigger("set_value",e)}}),s.view.properties.controllers.select=s.view.propertyController.extend({template:t.template('<select class="socss-property-controller-input"></select>'),events:{"click .select-tab":"onSelect"},render:function(){this.$el.append(e(this.template({}))),this.field=this.$("select"),this.field.append(e('<option value=""></option>').html(""));for(var t in this.args.options)this.field.append(e("<option></option>").attr("value",t).html(this.args.options[t]));void 0!==this.args.option_icons&&this.setupVisualSelect()},setupVisualSelect:function(){this.field.hide();var t=e('<div class="select-tabs"></div>').appendTo(this.$el);e('<div class="select-tab" data-value=""><span class="fa fa-circle-o"></span></div>').appendTo(t);for(var i in this.args.option_icons)e('<div class="select-tab"></div>').appendTo(t).append(e('<span class="fa"></span>').addClass("fa-"+this.args.option_icons[i])).attr("data-value",i);t.find(".select-tab").css("width",100/t.find(">div").length+"%")},onSelect:function(t){this.$(".select-tab").removeClass("active");var i=e(t.currentTarget);i.addClass("active"),this.field.val(i.data("value")).trigger("change")},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.val(e),this.$(".select-tabs .select-tab").removeClass("active").filter('[data-value="'+e+'"]').addClass("active"),i.silent||this.trigger("set_value",e)}}),s.view.properties.controllers.image=s.view.propertyController.extend({template:t.template('<input type="text" value="" /> <span class="select socss-button"><span class="fa fa-upload"></span></span>'),events:{"click .select":"openMedia"},render:function(){this.media=wp.media({title:i.loc.select_image,library:{type:"image"},button:{text:i.loc.select,close:!1}}),this.$el.append(e(this.template({select:i.loc.select}))),this.field=this.$el.find("input"),this.media.on("select",function(){var e=this.media.state().get("selection").first().attributes,t=this.args.value.replace("{{url}}",e.url);this.field.val(t).change(),this.media.close()}.bind(this))},openMedia:function(){this.media.open()}}),s.view.properties.controllers.measurement=s.view.propertyController.extend({wrapperClass:"socss-field-measurement",events:{"click .toggle-dropdown":"toggleUnitDropdown","click .dropdown li":"onSelectUnit","keydown .socss-field-input":"onInputKeyPress","keyup .socss-field-input":"onInputKeyUp"},render:function(){s.view.propertyController.prototype.render.apply(this,arguments),this.setupMeasurementField()},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.val(e).trigger("measurement_refresh"),i.silent||this.trigger("set_value",e)},units:["px","%","em","cm","mm","in","pt","pc","ex","ch","rem","vw","vh","vmin","vmax"],parseUnits:function(e){var t=function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},i=this.units.map(t),s=new RegExp("([0-9\\.\\-]+)("+i.join("|")+")?","i"),r=s.exec(e);return null===r?{value:"",unit:""}:{value:r[1],unit:void 0===r[2]?"":r[2]}},setupMeasurementField:function(){this.field.hide(),this.$el.addClass(this.wrapperClass).data("unit","px");var t=e('<input type="text" class="socss-field-input"/>').appendTo(this.$el);e('<span class="toggle-dropdown dashicons dashicons-arrow-down"></span>').appendTo(this.$el);for(var i=e('<ul class="dropdown"></ul>').appendTo(this.$el),s=e('<span class="units"></span>').html("px").appendTo(this.$el),r=0;r<this.units.length;r++){var o=e("<li></li>").html(this.units[r]).data("unit",this.units[r]);"px"===this.units[r]&&o.addClass("active"),i.append(o)}this.field.on("measurement_refresh",function(){var i=this.parseUnits(this.field.val());t.val(i.value);var r=""===i.unit?"px":i.unit;this.$el.data("unit",r),s.html(r);var o=e('<span class="socss-hidden-placeholder"></span>').css({"font-size":"14px"}).html(i.value).appendTo("body"),n=o.width();n=Math.min(n,63),o.remove(),s.css("left",n+12)}.bind(this));var n=e('<div class="socss-diw"></div>').appendTo(this.$el),l=e('<div class="dec-button socss-button"><span class="fa fa-minus"></span></div>').appendTo(n),a=e('<div class="inc-button socss-button"><span class="fa fa-plus"></span></div>').appendTo(n);this.setupStepButton(l),this.setupStepButton(a)},updateValue:function(){var e=this.$(".socss-field-input"),t=this.parseUnits(e.val());""!==t.unit&&t.unit!==this.$el.data("unit")&&(e.val(t.value),this.setUnit(t.unit)),""===t.value?this.field.val(""):this.field.val(t.value+this.$el.data("unit")),this.field.trigger("change")},setUnit:function(e){this.$(".units").html(e),this.$el.data("unit",e),this.$(".socss-field-input").trigger("keydown")},toggleUnitDropdown:function(){this.$(".dropdown").toggle()},onSelectUnit:function(t){this.toggleUnitDropdown(),this.setUnit(e(t.currentTarget).data("unit")),this.updateValue()},onInputKeyUp:function(e){this.onInputKeyPress(e),this.updateValue()},onInputKeyPress:function(t){var i=this.$(".socss-field-input"),s="";"keydown"===t.type&&(t.keyCode>=48&&t.keyCode<=57?s=String.fromCharCode(t.keyCode):189===t.keyCode?s="-":190===t.keyCode&&(s="."));var r=e('<span class="socss-hidden-placeholder"></span>').css({"font-size":"14px"}).html(i.val()+s).appendTo("body"),o=r.width();o=Math.min(o,63),r.remove(),this.$(".units").css("left",o+12)},stepValue:function(e){var t=Number.parseInt(this.parseUnits(this.field.val()).value);Number.isNaN(t)&&(t=0);var i=t+e;this.$(".socss-field-input").val(i),this.updateValue(),this.field.trigger("measurement_refresh")},setupStepButton:function(e){var t,i,s=e.is(".dec-button")?-1:1;e.mousedown(function(){this.stepValue(s),i=setTimeout(function(){t=setInterval(function(){this.stepValue(s)}.bind(this),50)}.bind(this),500)}.bind(this)).on("mouseup mouseout",function(){i&&(clearTimeout(i),i=null),t&&(clearInterval(t),t=null)})}}),s.view.properties.controllers.number=s.view.propertyController.extend({initialize:function(e){s.view.propertyController.prototype.initialize.apply(this,arguments),this.args=t.extend({change:null,default:0,increment:1,decrement:-1,max:null,min:null},e.args)},render:function(){s.view.propertyController.prototype.render.apply(this,arguments),this.setupNumberField()},setupNumberField:function(){this.$el.addClass("socss-field-number");var t=e('<div class="socss-diw"></div>').appendTo(this.$el),i=e('<div class="dec-button socss-button"><span class="fa fa-minus"></span></div>').appendTo(t),s=e('<div class="inc-button socss-button"><span class="fa fa-plus"></span></div>').appendTo(t);return this.setupStepButton(i),this.setupStepButton(s),this},stepValue:function(e){var t=Number.parseFloat(this.field.val());Number.isNaN(t)&&(t=this.args.default);var i=t+e;i=Math.round(100*i)/100,null!==this.args.max&&(i=Math.min(this.args.max,i)),null!==this.args.min&&(i=Math.max(this.args.min,i)),this.field.val(i),this.field.trigger("change")},setupStepButton:function(e){var t,i,s=e.is(".dec-button")?this.args.decrement:this.args.increment;e.mousedown(function(){this.stepValue(s),i=setTimeout(function(){t=setInterval(function(){this.stepValue(s)}.bind(this),50)}.bind(this),500)}.bind(this)).on("mouseup mouseout",function(){i&&(clearTimeout(i),i=null),t&&(clearInterval(t),t=null)})}}),s.view.properties.controllers.sides=s.view.propertyController.extend({template:t.template(e("#template-sides-field").html().trim()),controllers:[],events:{"click .select-tab":"onTabClick"},render:function(){s.view.propertyController.prototype.render.apply(this,arguments),this.args.hasAll||(this.$(".select-tab").eq(0).remove(),this.$(".select-tab").css("width","25%")),this.$(".select-tab").each(function(i,r){for(var o=e(r).data("direction"),n=e('<li class="side">').appendTo(this.$(".sides")).hide(),l=0;l<this.args.controllers.length;l++){var a=this.args.controllers[l];if(s.view.properties.controllers[a.type],!0){var c="";c="all"===o?a.args.propertyAll:a.args.property.replace("{dir}",o);var p=t.extend({},a.args,{property:c}),d=new s.view.properties.controllers[a.type]({el:e("<div>").appendTo(n),propertiesView:this.propertiesView,args:p});d.render(),this.propertiesView.propertyControllers.push(d)}}}.bind(this)),this.$(".select-tab").eq(0).click()},onTabClick:function(t){var i=this.$(".select-tab");i.removeClass("active");var s=e(t.currentTarget);s.addClass("active");var r=this.$(".sides .side");r.hide(),r.eq(i.index(s)).show()}}),s.view.properties.controllers.font_select=s.view.propertyController.extend({template:t.template(e("#template-webfont-teaser").html().trim())}),s.view.RevisionsListView=Backbone.View.extend({initialize:function(){this.listenTo(this.model,"change:selectedPost",this.updateRevisionsList.bind(this))},updateRevisionsList:function(){e.get(i.getRevisionsListAjaxUrl,{postId:this.model.get("selectedPost").get("postId")},function(e){this.$(".custom-revisions-list").html(e)}.bind(this))}})}(jQuery,_,socssOptions),jQuery(function(e){var t=window.socss,i=new t.model.CSSEditorModel({customCssPosts:socssOptions.customCssPosts}),s=new t.view.editor({el:e("#so-custom-css-form").get(0),model:i,openVisualEditor:socssOptions.openVisualEditor});s.setSnippets(socssOptions.snippets);var r=new t.view.RevisionsListView({el:e("#so-custom-css-revisions"),model:i});e("#so-custom-css-getting-started a.hide").click(function(t){t.preventDefault(),e("#so-custom-css-getting-started").slideUp(),e.get(e(this).attr("href"))}),window.socss.mainEditor=s,window.socss.revisionsList=r,e(t).trigger("initialized")});
lang/so-css.pot CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2017 so-css
2
  # This file is distributed under the same license as the so-css package.
3
  msgid ""
4
  msgstr ""
@@ -7,7 +7,7 @@ msgstr ""
7
  "MIME-Version: 1.0\n"
8
  "Content-Type: text/plain; charset=UTF-8\n"
9
  "Content-Transfer-Encoding: 8bit\n"
10
- "PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n"
11
  "Last-Translator: SiteOrigin <support@siteorigin.com>\n"
12
  "Language-Team: SiteOrigin <support@siteorigin.com>\n"
13
  "X-Poedit-Basepath: ..\n"
@@ -409,43 +409,59 @@ msgstr ""
409
  msgid "Z-Index"
410
  msgstr ""
411
 
412
- #: tmp/so-css.php:111, tmp/so-css.php:111, tmp/so-css.php:175
413
  msgid "Custom CSS"
414
  msgstr ""
415
 
416
- #: tmp/so-css.php:177
417
  msgid "SiteOrigin CSS adds any custom CSS you enter here into your site's header. "
418
  msgstr ""
419
 
420
- #: tmp/so-css.php:178
421
  msgid "These changes will persist across updates so it's best to make all your changes here. "
422
  msgstr ""
423
 
424
- #: tmp/so-css.php:234
 
 
 
 
 
 
 
 
425
  msgid "Unchanged"
426
  msgstr ""
427
 
428
- #: tmp/so-css.php:235
429
  msgid "Select"
430
  msgstr ""
431
 
432
- #: tmp/so-css.php:236
433
  msgid "Select Image"
434
  msgstr ""
435
 
436
- #: tmp/so-css.php:237
437
  msgid "Are you sure you want to leave without saving?"
438
  msgstr ""
439
 
440
- #: tmp/so-css.php:273
441
  msgid "CSS Editor"
442
  msgstr ""
443
 
444
- #: tmp/so-css.php:274
445
  msgid "Support"
446
  msgstr ""
447
 
448
- #: tmp/so-css.php:412
 
 
 
 
 
 
 
 
449
  msgid "Changes apply to %s and its child themes"
450
  msgstr ""
451
 
@@ -453,54 +469,70 @@ msgstr ""
453
  msgid "Navigate To: "
454
  msgstr ""
455
 
456
- #: tmp/tpl/js-templates.php:8
457
  msgid "CSS Snippets"
458
  msgstr ""
459
 
460
- #: tmp/tpl/js-templates.php:14
461
  msgid "Search Snippets"
462
  msgstr ""
463
 
464
- #: tmp/tpl/js-templates.php:26
465
  msgid "Insert Snippet"
466
  msgstr ""
467
 
468
- #: tmp/tpl/js-templates.php:51
469
  msgid "Invalid URI. Please make sure you're using a URL from the same site."
470
  msgstr ""
471
 
472
- #: tmp/tpl/page.php:13
 
 
 
 
473
  msgid "SiteOrigin CSS"
474
  msgstr ""
475
 
476
- #: tmp/tpl/page.php:18
477
  msgid "Site design updated."
478
  msgstr ""
479
 
480
- #: tmp/tpl/page.php:23
481
- msgid "Viewing a revision. Save CSS to keep using this revision."
482
  msgstr ""
483
 
484
- #: tmp/tpl/page.php:33
 
 
 
 
 
 
 
 
485
  msgid "Getting Started Video"
486
  msgstr ""
487
 
488
- #: tmp/tpl/page.php:34
489
  msgid "Dismiss"
490
  msgstr ""
491
 
492
- #: tmp/tpl/page.php:43
493
  msgid "CSS Revisions"
494
  msgstr ""
495
 
496
- #: tmp/tpl/page.php:45
497
  msgid "Are you sure you want to load this revision?"
498
  msgstr ""
499
 
500
- #: tmp/tpl/page.php:57
501
- msgid "%d chars"
 
 
 
 
502
  msgstr ""
503
 
504
- #: tmp/tpl/page.php:101
505
  msgid "Save CSS"
506
  msgstr ""
1
+ # Copyright (C) 2018 so-css
2
  # This file is distributed under the same license as the so-css package.
3
  msgid ""
4
  msgstr ""
7
  "MIME-Version: 1.0\n"
8
  "Content-Type: text/plain; charset=UTF-8\n"
9
  "Content-Transfer-Encoding: 8bit\n"
10
+ "PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n"
11
  "Last-Translator: SiteOrigin <support@siteorigin.com>\n"
12
  "Language-Team: SiteOrigin <support@siteorigin.com>\n"
13
  "X-Poedit-Basepath: ..\n"
409
  msgid "Z-Index"
410
  msgstr ""
411
 
412
+ #: tmp/so-css.php:521, tmp/so-css.php:521, tmp/so-css.php:583
413
  msgid "Custom CSS"
414
  msgstr ""
415
 
416
+ #: tmp/so-css.php:587
417
  msgid "SiteOrigin CSS adds any custom CSS you enter here into your site's header. "
418
  msgstr ""
419
 
420
+ #: tmp/so-css.php:589
421
  msgid "These changes will persist across updates so it's best to make all your changes here. "
422
  msgstr ""
423
 
424
+ #: tmp/so-css.php:759
425
+ msgid "Changes apply to <%= themeName %> and its child themes"
426
+ msgstr ""
427
+
428
+ #: tmp/so-css.php:761
429
+ msgid "Changes apply to the post <%= postTitle %> when the current theme is <%= themeName %> or its child themes"
430
+ msgstr ""
431
+
432
+ #: tmp/so-css.php:781
433
  msgid "Unchanged"
434
  msgstr ""
435
 
436
+ #: tmp/so-css.php:783
437
  msgid "Select"
438
  msgstr ""
439
 
440
+ #: tmp/so-css.php:785
441
  msgid "Select Image"
442
  msgstr ""
443
 
444
+ #: tmp/so-css.php:787
445
  msgid "Are you sure you want to leave without saving?"
446
  msgstr ""
447
 
448
+ #: tmp/so-css.php:855
449
  msgid "CSS Editor"
450
  msgstr ""
451
 
452
+ #: tmp/so-css.php:857
453
  msgid "Support"
454
  msgstr ""
455
 
456
+ #: tmp/so-css.php:1109
457
+ msgid "%d chars"
458
+ msgstr ""
459
+
460
+ #: tmp/so-css.php:1109
461
+ msgid "Latest"
462
+ msgstr ""
463
+
464
+ #: tmp/so-css.php:1345
465
  msgid "Changes apply to %s and its child themes"
466
  msgstr ""
467
 
469
  msgid "Navigate To: "
470
  msgstr ""
471
 
472
+ #: tmp/tpl/js-templates.php:15
473
  msgid "CSS Snippets"
474
  msgstr ""
475
 
476
+ #: tmp/tpl/js-templates.php:27
477
  msgid "Search Snippets"
478
  msgstr ""
479
 
480
+ #: tmp/tpl/js-templates.php:51
481
  msgid "Insert Snippet"
482
  msgstr ""
483
 
484
+ #: tmp/tpl/js-templates.php:101
485
  msgid "Invalid URI. Please make sure you're using a URL from the same site."
486
  msgstr ""
487
 
488
+ #: tmp/tpl/js-templates.php:121
489
+ msgid "Get a %sGoogle Font%s selector."
490
+ msgstr ""
491
+
492
+ #: tmp/tpl/page.php:35
493
  msgid "SiteOrigin CSS"
494
  msgstr ""
495
 
496
+ #: tmp/tpl/page.php:45
497
  msgid "Site design updated."
498
  msgstr ""
499
 
500
+ #: tmp/tpl/page.php:55
501
+ msgid "Editing revision dated %s. Click %sRevert to this revision%s to keep using it."
502
  msgstr ""
503
 
504
+ #: tmp/tpl/page.php:73
505
+ msgid "Get The Full Experience"
506
+ msgstr ""
507
+
508
+ #: tmp/tpl/page.php:77
509
+ msgid "%sSiteOrigin Premium%s adds a <strong>Google Web Font</strong> selector to SiteOrigin CSS so you can easily change any font."
510
+ msgstr ""
511
+
512
+ #: tmp/tpl/page.php:93
513
  msgid "Getting Started Video"
514
  msgstr ""
515
 
516
+ #: tmp/tpl/page.php:95
517
  msgid "Dismiss"
518
  msgstr ""
519
 
520
+ #: tmp/tpl/page.php:113
521
  msgid "CSS Revisions"
522
  msgstr ""
523
 
524
+ #: tmp/tpl/page.php:117
525
  msgid "Are you sure you want to load this revision?"
526
  msgstr ""
527
 
528
+ #: tmp/tpl/page.php:201
529
+ msgid "!empty$current_revision?__Revert to this revision"
530
+ msgstr ""
531
+
532
+ #: tmp/tpl/page.php:201
533
+ msgid "Revert to this revision"
534
  msgstr ""
535
 
536
+ #: tmp/tpl/page.php:201
537
  msgid "Save CSS"
538
  msgstr ""
lib/codemirror/addon/dialog/dialog.css ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .CodeMirror-dialog {
2
+ position: absolute;
3
+ left: 0; right: 0;
4
+ background: inherit;
5
+ z-index: 15;
6
+ padding: .1em .8em;
7
+ overflow: hidden;
8
+ color: inherit;
9
+ }
10
+
11
+ .CodeMirror-dialog-top {
12
+ border-bottom: 1px solid #eee;
13
+ top: 0;
14
+ }
15
+
16
+ .CodeMirror-dialog-bottom {
17
+ border-top: 1px solid #eee;
18
+ bottom: 0;
19
+ }
20
+
21
+ .CodeMirror-dialog input {
22
+ border: none;
23
+ outline: none;
24
+ background: transparent;
25
+ width: 20em;
26
+ color: inherit;
27
+ font-family: monospace;
28
+ }
29
+
30
+ .CodeMirror-dialog button {
31
+ font-size: 70%;
32
+ }
lib/codemirror/addon/dialog/dialog.js ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ // Open simple dialogs on top of an editor. Relies on dialog.css.
5
+
6
+ (function(mod) {
7
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
8
+ mod(require("../../lib/codemirror"));
9
+ else if (typeof define == "function" && define.amd) // AMD
10
+ define(["../../lib/codemirror"], mod);
11
+ else // Plain browser env
12
+ mod(CodeMirror);
13
+ })(function(CodeMirror) {
14
+ function dialogDiv(cm, template, bottom) {
15
+ var wrap = cm.getWrapperElement();
16
+ var dialog;
17
+ dialog = wrap.appendChild(document.createElement("div"));
18
+ if (bottom)
19
+ dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom";
20
+ else
21
+ dialog.className = "CodeMirror-dialog CodeMirror-dialog-top";
22
+
23
+ if (typeof template == "string") {
24
+ dialog.innerHTML = template;
25
+ } else { // Assuming it's a detached DOM element.
26
+ dialog.appendChild(template);
27
+ }
28
+ return dialog;
29
+ }
30
+
31
+ function closeNotification(cm, newVal) {
32
+ if (cm.state.currentNotificationClose)
33
+ cm.state.currentNotificationClose();
34
+ cm.state.currentNotificationClose = newVal;
35
+ }
36
+
37
+ CodeMirror.defineExtension("openDialog", function(template, callback, options) {
38
+ if (!options) options = {};
39
+
40
+ closeNotification(this, null);
41
+
42
+ var dialog = dialogDiv(this, template, options.bottom);
43
+ var closed = false, me = this;
44
+ function close(newVal) {
45
+ if (typeof newVal == 'string') {
46
+ inp.value = newVal;
47
+ } else {
48
+ if (closed) return;
49
+ closed = true;
50
+ dialog.parentNode.removeChild(dialog);
51
+ me.focus();
52
+
53
+ if (options.onClose) options.onClose(dialog);
54
+ }
55
+ }
56
+
57
+ var inp = dialog.getElementsByTagName("input")[0], button;
58
+ if (inp) {
59
+ inp.focus();
60
+
61
+ if (options.value) {
62
+ inp.value = options.value;
63
+ if (options.selectValueOnOpen !== false) {
64
+ inp.select();
65
+ }
66
+ }
67
+
68
+ if (options.onInput)
69
+ CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);});
70
+ if (options.onKeyUp)
71
+ CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);});
72
+
73
+ CodeMirror.on(inp, "keydown", function(e) {
74
+ if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; }
75
+ if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
76
+ inp.blur();
77
+ CodeMirror.e_stop(e);
78
+ close();
79
+ }
80
+ if (e.keyCode == 13) callback(inp.value, e);
81
+ });
82
+
83
+ if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close);
84
+ } else if (button = dialog.getElementsByTagName("button")[0]) {
85
+ CodeMirror.on(button, "click", function() {
86
+ close();
87
+ me.focus();
88
+ });
89
+
90
+ if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close);
91
+
92
+ button.focus();
93
+ }
94
+ return close;
95
+ });
96
+
97
+ CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) {
98
+ closeNotification(this, null);
99
+ var dialog = dialogDiv(this, template, options && options.bottom);
100
+ var buttons = dialog.getElementsByTagName("button");
101
+ var closed = false, me = this, blurring = 1;
102
+ function close() {
103
+ if (closed) return;
104
+ closed = true;
105
+ dialog.parentNode.removeChild(dialog);
106
+ me.focus();
107
+ }
108
+ buttons[0].focus();
109
+ for (var i = 0; i < buttons.length; ++i) {
110
+ var b = buttons[i];
111
+ (function(callback) {
112
+ CodeMirror.on(b, "click", function(e) {
113
+ CodeMirror.e_preventDefault(e);
114
+ close();
115
+ if (callback) callback(me);
116
+ });
117
+ })(callbacks[i]);
118
+ CodeMirror.on(b, "blur", function() {
119
+ --blurring;
120
+ setTimeout(function() { if (blurring <= 0) close(); }, 200);
121
+ });
122
+ CodeMirror.on(b, "focus", function() { ++blurring; });
123
+ }
124
+ });
125
+
126
+ /*
127
+ * openNotification
128
+ * Opens a notification, that can be closed with an optional timer
129
+ * (default 5000ms timer) and always closes on click.
130
+ *
131
+ * If a notification is opened while another is opened, it will close the
132
+ * currently opened one and open the new one immediately.
133
+ */
134
+ CodeMirror.defineExtension("openNotification", function(template, options) {
135
+ closeNotification(this, close);
136
+ var dialog = dialogDiv(this, template, options && options.bottom);
137
+ var closed = false, doneTimer;
138
+ var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000;
139
+
140
+ function close() {
141
+ if (closed) return;
142
+ closed = true;
143
+ clearTimeout(doneTimer);
144
+ dialog.parentNode.removeChild(dialog);
145
+ }
146
+
147
+ CodeMirror.on(dialog, 'click', function(e) {
148
+ CodeMirror.e_preventDefault(e);
149
+ close();
150
+ });
151
+
152
+ if (duration)
153
+ doneTimer = setTimeout(close, duration);
154
+
155
+ return close;
156
+ });
157
+ });
lib/codemirror/addon/dialog/dialog.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){function o(e,o,n){var t,i=e.getWrapperElement();return t=i.appendChild(document.createElement("div")),t.className=n?"CodeMirror-dialog CodeMirror-dialog-bottom":"CodeMirror-dialog CodeMirror-dialog-top","string"==typeof o?t.innerHTML=o:t.appendChild(o),t}function n(e,o){e.state.currentNotificationClose&&e.state.currentNotificationClose(),e.state.currentNotificationClose=o}e.defineExtension("openDialog",function(t,i,r){function u(e){if("string"==typeof e)s.value=e;else{if(f)return;f=!0,c.parentNode.removeChild(c),a.focus(),r.onClose&&r.onClose(c)}}r||(r={}),n(this,null);var l,c=o(this,t,r.bottom),f=!1,a=this,s=c.getElementsByTagName("input")[0];return s?(s.focus(),r.value&&(s.value=r.value,!1!==r.selectValueOnOpen&&s.select()),r.onInput&&e.on(s,"input",function(e){r.onInput(e,s.value,u)}),r.onKeyUp&&e.on(s,"keyup",function(e){r.onKeyUp(e,s.value,u)}),e.on(s,"keydown",function(o){r&&r.onKeyDown&&r.onKeyDown(o,s.value,u)||((27==o.keyCode||!1!==r.closeOnEnter&&13==o.keyCode)&&(s.blur(),e.e_stop(o),u()),13==o.keyCode&&i(s.value,o))}),!1!==r.closeOnBlur&&e.on(s,"blur",u)):(l=c.getElementsByTagName("button")[0])&&(e.on(l,"click",function(){u(),a.focus()}),!1!==r.closeOnBlur&&e.on(l,"blur",u),l.focus()),u}),e.defineExtension("openConfirm",function(t,i,r){function u(){f||(f=!0,l.parentNode.removeChild(l),a.focus())}n(this,null);var l=o(this,t,r&&r.bottom),c=l.getElementsByTagName("button"),f=!1,a=this,s=1;c[0].focus();for(var d=0;d<c.length;++d){var p=c[d];!function(o){e.on(p,"click",function(n){e.e_preventDefault(n),u(),o&&o(a)})}(i[d]),e.on(p,"blur",function(){--s,setTimeout(function(){s<=0&&u()},200)}),e.on(p,"focus",function(){++s})}}),e.defineExtension("openNotification",function(t,i){function r(){c||(c=!0,clearTimeout(u),l.parentNode.removeChild(l))}n(this,r);var u,l=o(this,t,i&&i.bottom),c=!1,f=i&&void 0!==i.duration?i.duration:5e3;return e.on(l,"click",function(o){e.e_preventDefault(o),r()}),f&&(u=setTimeout(r,f)),r})});
lib/codemirror/addon/scroll/annotatescrollbar.js ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineExtension("annotateScrollbar", function(options) {
15
+ if (typeof options == "string") options = {className: options};
16
+ return new Annotation(this, options);
17
+ });
18
+
19
+ CodeMirror.defineOption("scrollButtonHeight", 0);
20
+
21
+ function Annotation(cm, options) {
22
+ this.cm = cm;
23
+ this.options = options;
24
+ this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight");
25
+ this.annotations = [];
26
+ this.doRedraw = this.doUpdate = null;
27
+ this.div = cm.getWrapperElement().appendChild(document.createElement("div"));
28
+ this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none";
29
+ this.computeScale();
30
+
31
+ function scheduleRedraw(delay) {
32
+ clearTimeout(self.doRedraw);
33
+ self.doRedraw = setTimeout(function() { self.redraw(); }, delay);
34
+ }
35
+
36
+ var self = this;
37
+ cm.on("refresh", this.resizeHandler = function() {
38
+ clearTimeout(self.doUpdate);
39
+ self.doUpdate = setTimeout(function() {
40
+ if (self.computeScale()) scheduleRedraw(20);
41
+ }, 100);
42
+ });
43
+ cm.on("markerAdded", this.resizeHandler);
44
+ cm.on("markerCleared", this.resizeHandler);
45
+ if (options.listenForChanges !== false)
46
+ cm.on("change", this.changeHandler = function() {
47
+ scheduleRedraw(250);
48
+ });
49
+ }
50
+
51
+ Annotation.prototype.computeScale = function() {
52
+ var cm = this.cm;
53
+ var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) /
54
+ cm.getScrollerElement().scrollHeight
55
+ if (hScale != this.hScale) {
56
+ this.hScale = hScale;
57
+ return true;
58
+ }
59
+ };
60
+
61
+ Annotation.prototype.update = function(annotations) {
62
+ this.annotations = annotations;
63
+ this.redraw();
64
+ };
65
+
66
+ Annotation.prototype.redraw = function(compute) {
67
+ if (compute !== false) this.computeScale();
68
+ var cm = this.cm, hScale = this.hScale;
69
+
70
+ var frag = document.createDocumentFragment(), anns = this.annotations;
71
+
72
+ var wrapping = cm.getOption("lineWrapping");
73
+ var singleLineH = wrapping && cm.defaultTextHeight() * 1.5;
74
+ var curLine = null, curLineObj = null;
75
+ function getY(pos, top) {
76
+ if (curLine != pos.line) {
77
+ curLine = pos.line;
78
+ curLineObj = cm.getLineHandle(curLine);
79
+ }
80
+ if ((curLineObj.widgets && curLineObj.widgets.length) ||
81
+ (wrapping && curLineObj.height > singleLineH))
82
+ return cm.charCoords(pos, "local")[top ? "top" : "bottom"];
83
+ var topY = cm.heightAtLine(curLineObj, "local");
84
+ return topY + (top ? 0 : curLineObj.height);
85
+ }
86
+
87
+ var lastLine = cm.lastLine()
88
+ if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
89
+ var ann = anns[i];
90
+ if (ann.to.line > lastLine) continue;
91
+ var top = nextTop || getY(ann.from, true) * hScale;
92
+ var bottom = getY(ann.to, false) * hScale;
93
+ while (i < anns.length - 1) {
94
+ if (anns[i + 1].to.line > lastLine) break;
95
+ nextTop = getY(anns[i + 1].from, true) * hScale;
96
+ if (nextTop > bottom + .9) break;
97
+ ann = anns[++i];
98
+ bottom = getY(ann.to, false) * hScale;
99
+ }
100
+ if (bottom == top) continue;
101
+ var height = Math.max(bottom - top, 3);
102
+
103
+ var elt = frag.appendChild(document.createElement("div"));
104
+ elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: "
105
+ + (top + this.buttonHeight) + "px; height: " + height + "px";
106
+ elt.className = this.options.className;
107
+ if (ann.id) {
108
+ elt.setAttribute("annotation-id", ann.id);
109
+ }
110
+ }
111
+ this.div.textContent = "";
112
+ this.div.appendChild(frag);
113
+ };
114
+
115
+ Annotation.prototype.clear = function() {
116
+ this.cm.off("refresh", this.resizeHandler);
117
+ this.cm.off("markerAdded", this.resizeHandler);
118
+ this.cm.off("markerCleared", this.resizeHandler);
119
+ if (this.changeHandler) this.cm.off("change", this.changeHandler);
120
+ this.div.parentNode.removeChild(this.div);
121
+ };
122
+ });
lib/codemirror/addon/scroll/annotatescrollbar.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],t):t(CodeMirror)}(function(t){"use strict";function e(t,e){function i(t){clearTimeout(n.doRedraw),n.doRedraw=setTimeout(function(){n.redraw()},t)}this.cm=t,this.options=e,this.buttonHeight=e.scrollButtonHeight||t.getOption("scrollButtonHeight"),this.annotations=[],this.doRedraw=this.doUpdate=null,this.div=t.getWrapperElement().appendChild(document.createElement("div")),this.div.style.cssText="position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none",this.computeScale();var n=this;t.on("refresh",this.resizeHandler=function(){clearTimeout(n.doUpdate),n.doUpdate=setTimeout(function(){n.computeScale()&&i(20)},100)}),t.on("markerAdded",this.resizeHandler),t.on("markerCleared",this.resizeHandler),!1!==e.listenForChanges&&t.on("change",this.changeHandler=function(){i(250)})}t.defineExtension("annotateScrollbar",function(t){return"string"==typeof t&&(t={className:t}),new e(this,t)}),t.defineOption("scrollButtonHeight",0),e.prototype.computeScale=function(){var t=this.cm,e=(t.getWrapperElement().clientHeight-t.display.barHeight-2*this.buttonHeight)/t.getScrollerElement().scrollHeight;if(e!=this.hScale)return this.hScale=e,!0},e.prototype.update=function(t){this.annotations=t,this.redraw()},e.prototype.redraw=function(t){function e(t,e){return h!=t.line&&(h=t.line,l=i.getLineHandle(h)),l.widgets&&l.widgets.length||a&&l.height>s?i.charCoords(t,"local")[e?"top":"bottom"]:i.heightAtLine(l,"local")+(e?0:l.height)}!1!==t&&this.computeScale();var i=this.cm,n=this.hScale,o=document.createDocumentFragment(),r=this.annotations,a=i.getOption("lineWrapping"),s=a&&1.5*i.defaultTextHeight(),h=null,l=null,d=i.lastLine();if(i.display.barWidth)for(var c,p=0;p<r.length;p++){var u=r[p];if(!(u.to.line>d)){for(var f=c||e(u.from,!0)*n,m=e(u.to,!1)*n;p<r.length-1&&!(r[p+1].to.line>d)&&!((c=e(r[p+1].from,!0)*n)>m+.9);)u=r[++p],m=e(u.to,!1)*n;if(m!=f){var g=Math.max(m-f,3),H=o.appendChild(document.createElement("div"));H.style.cssText="position: absolute; right: 0px; width: "+Math.max(i.display.barWidth-1,2)+"px; top: "+(f+this.buttonHeight)+"px; height: "+g+"px",H.className=this.options.className,u.id&&H.setAttribute("annotation-id",u.id)}}}this.div.textContent="",this.div.appendChild(o)},e.prototype.clear=function(){this.cm.off("refresh",this.resizeHandler),this.cm.off("markerAdded",this.resizeHandler),this.cm.off("markerCleared",this.resizeHandler),this.changeHandler&&this.cm.off("change",this.changeHandler),this.div.parentNode.removeChild(this.div)}});
lib/codemirror/addon/search/jump-to-line.js ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ // Defines jumpToLine command. Uses dialog.js if present.
5
+
6
+ (function(mod) {
7
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
8
+ mod(require("../../lib/codemirror"), require("../dialog/dialog"));
9
+ else if (typeof define == "function" && define.amd) // AMD
10
+ define(["../../lib/codemirror", "../dialog/dialog"], mod);
11
+ else // Plain browser env
12
+ mod(CodeMirror);
13
+ })(function(CodeMirror) {
14
+ "use strict";
15
+
16
+ function dialog(cm, text, shortText, deflt, f) {
17
+ if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
18
+ else f(prompt(shortText, deflt));
19
+ }
20
+
21
+ var jumpDialog =
22
+ 'Jump to line: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use line:column or scroll% syntax)</span>';
23
+
24
+ function interpretLine(cm, string) {
25
+ var num = Number(string)
26
+ if (/^[-+]/.test(string)) return cm.getCursor().line + num
27
+ else return num - 1
28
+ }
29
+
30
+ CodeMirror.commands.jumpToLine = function(cm) {
31
+ var cur = cm.getCursor();
32
+ dialog(cm, jumpDialog, "Jump to line:", (cur.line + 1) + ":" + cur.ch, function(posStr) {
33
+ if (!posStr) return;
34
+
35
+ var match;
36
+ if (match = /^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(posStr)) {
37
+ cm.setCursor(interpretLine(cm, match[1]), Number(match[2]))
38
+ } else if (match = /^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(posStr)) {
39
+ var line = Math.round(cm.lineCount() * Number(match[1]) / 100);
40
+ if (/^[-+]/.test(match[1])) line = cur.line + line + 1;
41
+ cm.setCursor(line - 1, cur.ch);
42
+ } else if (match = /^\s*\:?\s*([\+\-]?\d+)\s*/.exec(posStr)) {
43
+ cm.setCursor(interpretLine(cm, match[1]), cur.ch);
44
+ }
45
+ });
46
+ };
47
+
48
+ CodeMirror.keyMap["default"]["Alt-G"] = "jumpToLine";
49
+ });
lib/codemirror/addon/search/jump-to-line.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror"),require("../dialog/dialog")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","../dialog/dialog"],e):e(CodeMirror)}(function(e){"use strict";function o(e,o,r,i,t){e.openDialog?e.openDialog(o,t,{value:i,selectValueOnOpen:!0}):t(prompt(r,i))}function r(e,o){var r=Number(o);return/^[-+]/.test(o)?e.getCursor().line+r:r-1}e.commands.jumpToLine=function(e){var i=e.getCursor();o(e,'Jump to line: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use line:column or scroll% syntax)</span>',"Jump to line:",i.line+1+":"+i.ch,function(o){if(o){var t;if(t=/^\s*([\+\-]?\d+)\s*\:\s*(\d+)\s*$/.exec(o))e.setCursor(r(e,t[1]),Number(t[2]));else if(t=/^\s*([\+\-]?\d+(\.\d+)?)\%\s*/.exec(o)){var n=Math.round(e.lineCount()*Number(t[1])/100);/^[-+]/.test(t[1])&&(n=i.line+n+1),e.setCursor(n-1,i.ch)}else(t=/^\s*\:?\s*([\+\-]?\d+)\s*/.exec(o))&&e.setCursor(r(e,t[1]),i.ch)}})},e.keyMap.default["Alt-G"]="jumpToLine"});
lib/codemirror/addon/search/match-highlighter.js ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ // Highlighting text that matches the selection
5
+ //
6
+ // Defines an option highlightSelectionMatches, which, when enabled,
7
+ // will style strings that match the selection throughout the
8
+ // document.
9
+ //
10
+ // The option can be set to true to simply enable it, or to a
11
+ // {minChars, style, wordsOnly, showToken, delay} object to explicitly
12
+ // configure it. minChars is the minimum amount of characters that should be
13
+ // selected for the behavior to occur, and style is the token style to
14
+ // apply to the matches. This will be prefixed by "cm-" to create an
15
+ // actual CSS class name. If wordsOnly is enabled, the matches will be
16
+ // highlighted only if the selected text is a word. showToken, when enabled,
17
+ // will cause the current token to be highlighted when nothing is selected.
18
+ // delay is used to specify how much time to wait, in milliseconds, before
19
+ // highlighting the matches. If annotateScrollbar is enabled, the occurences
20
+ // will be highlighted on the scrollbar via the matchesonscrollbar addon.
21
+
22
+ (function(mod) {
23
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
24
+ mod(require("../../lib/codemirror"), require("./matchesonscrollbar"));
25
+ else if (typeof define == "function" && define.amd) // AMD
26
+ define(["../../lib/codemirror", "./matchesonscrollbar"], mod);
27
+ else // Plain browser env
28
+ mod(CodeMirror);
29
+ })(function(CodeMirror) {
30
+ "use strict";
31
+
32
+ var defaults = {
33
+ style: "matchhighlight",
34
+ minChars: 2,
35
+ delay: 100,
36
+ wordsOnly: false,
37
+ annotateScrollbar: false,
38
+ showToken: false,
39
+ trim: true
40
+ }
41
+
42
+ function State(options) {
43
+ this.options = {}
44
+ for (var name in defaults)
45
+ this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name]
46
+ this.overlay = this.timeout = null;
47
+ this.matchesonscroll = null;
48
+ this.active = false;
49
+ }
50
+
51
+ CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
52
+ if (old && old != CodeMirror.Init) {
53
+ removeOverlay(cm);
54
+ clearTimeout(cm.state.matchHighlighter.timeout);
55
+ cm.state.matchHighlighter = null;
56
+ cm.off("cursorActivity", cursorActivity);
57
+ cm.off("focus", onFocus)
58
+ }
59
+ if (val) {
60
+ var state = cm.state.matchHighlighter = new State(val);
61
+ if (cm.hasFocus()) {
62
+ state.active = true
63
+ highlightMatches(cm)
64
+ } else {
65
+ cm.on("focus", onFocus)
66
+ }
67
+ cm.on("cursorActivity", cursorActivity);
68
+ }
69
+ });
70
+
71
+ function cursorActivity(cm) {
72
+ var state = cm.state.matchHighlighter;
73
+ if (state.active || cm.hasFocus()) scheduleHighlight(cm, state)
74
+ }
75
+
76
+ function onFocus(cm) {
77
+ var state = cm.state.matchHighlighter
78
+ if (!state.active) {
79
+ state.active = true
80
+ scheduleHighlight(cm, state)
81
+ }
82
+ }
83
+
84
+ function scheduleHighlight(cm, state) {
85
+ clearTimeout(state.timeout);
86
+ state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay);
87
+ }
88
+
89
+ function addOverlay(cm, query, hasBoundary, style) {
90
+ var state = cm.state.matchHighlighter;
91
+ cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
92
+ if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
93
+ var searchFor = hasBoundary ? new RegExp("\\b" + query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") + "\\b") : query;
94
+ state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
95
+ {className: "CodeMirror-selection-highlight-scrollbar"});
96
+ }
97
+ }
98
+
99
+ function removeOverlay(cm) {
100
+ var state = cm.state.matchHighlighter;
101
+ if (state.overlay) {
102
+ cm.removeOverlay(state.overlay);
103
+ state.overlay = null;
104
+ if (state.matchesonscroll) {
105
+ state.matchesonscroll.clear();
106
+ state.matchesonscroll = null;
107
+ }
108
+ }
109
+ }
110
+
111
+ function highlightMatches(cm) {
112
+ cm.operation(function() {
113
+ var state = cm.state.matchHighlighter;
114
+ removeOverlay(cm);
115
+ if (!cm.somethingSelected() && state.options.showToken) {
116
+ var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken;
117
+ var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
118
+ while (start && re.test(line.charAt(start - 1))) --start;
119
+ while (end < line.length && re.test(line.charAt(end))) ++end;
120
+ if (start < end)
121
+ addOverlay(cm, line.slice(start, end), re, state.options.style);
122
+ return;
123
+ }
124
+ var from = cm.getCursor("from"), to = cm.getCursor("to");
125
+ if (from.line != to.line) return;
126
+ if (state.options.wordsOnly && !isWord(cm, from, to)) return;
127
+ var selection = cm.getRange(from, to)
128
+ if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "")
129
+ if (selection.length >= state.options.minChars)
130
+ addOverlay(cm, selection, false, state.options.style);
131
+ });
132
+ }
133
+
134
+ function isWord(cm, from, to) {
135
+ var str = cm.getRange(from, to);
136
+ if (str.match(/^\w+$/) !== null) {
137
+ if (from.ch > 0) {
138
+ var pos = {line: from.line, ch: from.ch - 1};
139
+ var chr = cm.getRange(pos, from);
140
+ if (chr.match(/\W/) === null) return false;
141
+ }
142
+ if (to.ch < cm.getLine(from.line).length) {
143
+ var pos = {line: to.line, ch: to.ch + 1};
144
+ var chr = cm.getRange(to, pos);
145
+ if (chr.match(/\W/) === null) return false;
146
+ }
147
+ return true;
148
+ } else return false;
149
+ }
150
+
151
+ function boundariesAround(stream, re) {
152
+ return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) &&
153
+ (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
154
+ }
155
+
156
+ function makeOverlay(query, hasBoundary, style) {
157
+ return {token: function(stream) {
158
+ if (stream.match(query) &&
159
+ (!hasBoundary || boundariesAround(stream, hasBoundary)))
160
+ return style;
161
+ stream.next();
162
+ stream.skipTo(query.charAt(0)) || stream.skipToEnd();
163
+ }};
164
+ }
165
+ });
lib/codemirror/addon/search/match-highlighter.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror"),require("./matchesonscrollbar")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./matchesonscrollbar"],t):t(CodeMirror)}(function(t){"use strict";function e(t){this.options={};for(var e in u)this.options[e]=(t&&t.hasOwnProperty(e)?t:u)[e];this.overlay=this.timeout=null,this.matchesonscroll=null,this.active=!1}function o(t){var e=t.state.matchHighlighter;(e.active||t.hasFocus())&&n(t,e)}function i(t){var e=t.state.matchHighlighter;e.active||(e.active=!0,n(t,e))}function n(t,e){clearTimeout(e.timeout),e.timeout=setTimeout(function(){s(t)},e.options.delay)}function r(t,e,o,i){var n=t.state.matchHighlighter;if(t.addOverlay(n.overlay=h(e,o,i)),n.options.annotateScrollbar&&t.showMatchesOnScrollbar){var r=o?new RegExp("\\b"+e.replace(/[\\\[.+*?(){|^$]/g,"\\$&")+"\\b"):e;n.matchesonscroll=t.showMatchesOnScrollbar(r,!1,{className:"CodeMirror-selection-highlight-scrollbar"})}}function a(t){var e=t.state.matchHighlighter;e.overlay&&(t.removeOverlay(e.overlay),e.overlay=null,e.matchesonscroll&&(e.matchesonscroll.clear(),e.matchesonscroll=null))}function s(t){t.operation(function(){var e=t.state.matchHighlighter;if(a(t),!t.somethingSelected()&&e.options.showToken){for(var o=!0===e.options.showToken?/[\w$]/:e.options.showToken,i=t.getCursor(),n=t.getLine(i.line),s=i.ch,l=s;s&&o.test(n.charAt(s-1));)--s;for(;l<n.length&&o.test(n.charAt(l));)++l;return void(s<l&&r(t,n.slice(s,l),o,e.options.style))}var h=t.getCursor("from"),u=t.getCursor("to");if(h.line==u.line&&(!e.options.wordsOnly||c(t,h,u))){var g=t.getRange(h,u);e.options.trim&&(g=g.replace(/^\s+|\s+$/g,"")),g.length>=e.options.minChars&&r(t,g,!1,e.options.style)}})}function c(t,e,o){if(null!==t.getRange(e,o).match(/^\w+$/)){if(e.ch>0){var i={line:e.line,ch:e.ch-1},n=t.getRange(i,e);if(null===n.match(/\W/))return!1}if(o.ch<t.getLine(e.line).length){var i={line:o.line,ch:o.ch+1},n=t.getRange(o,i);if(null===n.match(/\W/))return!1}return!0}return!1}function l(t,e){return!(t.start&&e.test(t.string.charAt(t.start-1))||t.pos!=t.string.length&&e.test(t.string.charAt(t.pos)))}function h(t,e,o){return{token:function(i){if(i.match(t)&&(!e||l(i,e)))return o;i.next(),i.skipTo(t.charAt(0))||i.skipToEnd()}}}var u={style:"matchhighlight",minChars:2,delay:100,wordsOnly:!1,annotateScrollbar:!1,showToken:!1,trim:!0};t.defineOption("highlightSelectionMatches",!1,function(n,r,c){if(c&&c!=t.Init&&(a(n),clearTimeout(n.state.matchHighlighter.timeout),n.state.matchHighlighter=null,n.off("cursorActivity",o),n.off("focus",i)),r){var l=n.state.matchHighlighter=new e(r);n.hasFocus()?(l.active=!0,s(n)):n.on("focus",i),n.on("cursorActivity",o)}})});
lib/codemirror/addon/search/matchesonscrollbar.css ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ .CodeMirror-search-match {
2
+ background: gold;
3
+ border-top: 1px solid orange;
4
+ border-bottom: 1px solid orange;
5
+ -moz-box-sizing: border-box;
6
+ box-sizing: border-box;
7
+ opacity: .5;
8
+ }
lib/codemirror/addon/search/matchesonscrollbar.js ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"), require("./searchcursor"), require("../scroll/annotatescrollbar"));
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror", "./searchcursor", "../scroll/annotatescrollbar"], mod);
9
+ else // Plain browser env
10
+ mod(CodeMirror);
11
+ })(function(CodeMirror) {
12
+ "use strict";
13
+
14
+ CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) {
15
+ if (typeof options == "string") options = {className: options};
16
+ if (!options) options = {};
17
+ return new SearchAnnotation(this, query, caseFold, options);
18
+ });
19
+
20
+ function SearchAnnotation(cm, query, caseFold, options) {
21
+ this.cm = cm;
22
+ this.options = options;
23
+ var annotateOptions = {listenForChanges: false};
24
+ for (var prop in options) annotateOptions[prop] = options[prop];
25
+ if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match";
26
+ this.annotation = cm.annotateScrollbar(annotateOptions);
27
+ this.query = query;
28
+ this.caseFold = caseFold;
29
+ this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1};
30
+ this.matches = [];
31
+ this.update = null;
32
+
33
+ this.findMatches();
34
+ this.annotation.update(this.matches);
35
+
36
+ var self = this;
37
+ cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); });
38
+ }
39
+
40
+ var MAX_MATCHES = 1000;
41
+
42
+ SearchAnnotation.prototype.findMatches = function() {
43
+ if (!this.gap) return;
44
+ for (var i = 0; i < this.matches.length; i++) {
45
+ var match = this.matches[i];
46
+ if (match.from.line >= this.gap.to) break;
47
+ if (match.to.line >= this.gap.from) this.matches.splice(i--, 1);
48
+ }
49
+ var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), this.caseFold);
50
+ var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES;
51
+ while (cursor.findNext()) {
52
+ var match = {from: cursor.from(), to: cursor.to()};
53
+ if (match.from.line >= this.gap.to) break;
54
+ this.matches.splice(i++, 0, match);
55
+ if (this.matches.length > maxMatches) break;
56
+ }
57
+ this.gap = null;
58
+ };
59
+
60
+ function offsetLine(line, changeStart, sizeChange) {
61
+ if (line <= changeStart) return line;
62
+ return Math.max(changeStart, line + sizeChange);
63
+ }
64
+
65
+ SearchAnnotation.prototype.onChange = function(change) {
66
+ var startLine = change.from.line;
67
+ var endLine = CodeMirror.changeEnd(change).line;
68
+ var sizeChange = endLine - change.to.line;
69
+ if (this.gap) {
70
+ this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line);
71
+ this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line);
72
+ } else {
73
+ this.gap = {from: change.from.line, to: endLine + 1};
74
+ }
75
+
76
+ if (sizeChange) for (var i = 0; i < this.matches.length; i++) {
77
+ var match = this.matches[i];
78
+ var newFrom = offsetLine(match.from.line, startLine, sizeChange);
79
+ if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch);
80
+ var newTo = offsetLine(match.to.line, startLine, sizeChange);
81
+ if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch);
82
+ }
83
+ clearTimeout(this.update);
84
+ var self = this;
85
+ this.update = setTimeout(function() { self.updateAfterChange(); }, 250);
86
+ };
87
+
88
+ SearchAnnotation.prototype.updateAfterChange = function() {
89
+ this.findMatches();
90
+ this.annotation.update(this.matches);
91
+ };
92
+
93
+ SearchAnnotation.prototype.clear = function() {
94
+ this.cm.off("change", this.changeHandler);
95
+ this.annotation.clear();
96
+ };
97
+ });
lib/codemirror/addon/search/matchesonscrollbar.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror"),require("./searchcursor"),require("../scroll/annotatescrollbar")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./searchcursor","../scroll/annotatescrollbar"],t):t(CodeMirror)}(function(t){"use strict";function e(t,e,i,o){this.cm=t,this.options=o;var a={listenForChanges:!1};for(var n in o)a[n]=o[n];a.className||(a.className="CodeMirror-search-match"),this.annotation=t.annotateScrollbar(a),this.query=e,this.caseFold=i,this.gap={from:t.firstLine(),to:t.lastLine()+1},this.matches=[],this.update=null,this.findMatches(),this.annotation.update(this.matches);var s=this;t.on("change",this.changeHandler=function(t,e){s.onChange(e)})}function i(t,e,i){return t<=e?t:Math.max(e,t+i)}t.defineExtension("showMatchesOnScrollbar",function(t,i,o){return"string"==typeof o&&(o={className:o}),o||(o={}),new e(this,t,i,o)});e.prototype.findMatches=function(){if(this.gap){for(var e=0;e<this.matches.length;e++){var i=this.matches[e];if(i.from.line>=this.gap.to)break;i.to.line>=this.gap.from&&this.matches.splice(e--,1)}for(var o=this.cm.getSearchCursor(this.query,t.Pos(this.gap.from,0),this.caseFold),a=this.options&&this.options.maxMatches||1e3;o.findNext();){var i={from:o.from(),to:o.to()};if(i.from.line>=this.gap.to)break;if(this.matches.splice(e++,0,i),this.matches.length>a)break}this.gap=null}},e.prototype.onChange=function(e){var o=e.from.line,a=t.changeEnd(e).line,n=a-e.to.line;if(this.gap?(this.gap.from=Math.min(i(this.gap.from,o,n),e.from.line),this.gap.to=Math.max(i(this.gap.to,o,n),e.from.line)):this.gap={from:e.from.line,to:a+1},n)for(var s=0;s<this.matches.length;s++){var r=this.matches[s],h=i(r.from.line,o,n);h!=r.from.line&&(r.from=t.Pos(h,r.from.ch));var c=i(r.to.line,o,n);c!=r.to.line&&(r.to=t.Pos(c,r.to.ch))}clearTimeout(this.update);var f=this;this.update=setTimeout(function(){f.updateAfterChange()},250)},e.prototype.updateAfterChange=function(){this.findMatches(),this.annotation.update(this.matches)},e.prototype.clear=function(){this.cm.off("change",this.changeHandler),this.annotation.clear()}});
lib/codemirror/addon/search/search.js ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ // Define search commands. Depends on dialog.js or another
5
+ // implementation of the openDialog method.
6
+
7
+ // Replace works a little oddly -- it will do the replace on the next
8
+ // Ctrl-G (or whatever is bound to findNext) press. You prevent a
9
+ // replace by making sure the match is no longer selected when hitting
10
+ // Ctrl-G.
11
+
12
+ (function(mod) {
13
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
14
+ mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog"));
15
+ else if (typeof define == "function" && define.amd) // AMD
16
+ define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod);
17
+ else // Plain browser env
18
+ mod(CodeMirror);
19
+ })(function(CodeMirror) {
20
+ "use strict";
21
+
22
+ function searchOverlay(query, caseInsensitive) {
23
+ if (typeof query == "string")
24
+ query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
25
+ else if (!query.global)
26
+ query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
27
+
28
+ return {token: function(stream) {
29
+ query.lastIndex = stream.pos;
30
+ var match = query.exec(stream.string);
31
+ if (match && match.index == stream.pos) {
32
+ stream.pos += match[0].length || 1;
33
+ return "searching";
34
+ } else if (match) {
35
+ stream.pos = match.index;
36
+ } else {
37
+ stream.skipToEnd();
38
+ }
39
+ }};
40
+ }
41
+
42
+ function SearchState() {
43
+ this.posFrom = this.posTo = this.lastQuery = this.query = null;
44
+ this.overlay = null;
45
+ }
46
+
47
+ function getSearchState(cm) {
48
+ return cm.state.search || (cm.state.search = new SearchState());
49
+ }
50
+
51
+ function queryCaseInsensitive(query) {
52
+ return typeof query == "string" && query == query.toLowerCase();
53
+ }
54
+
55
+ function getSearchCursor(cm, query, pos) {
56
+ // Heuristic: if the query string is all lowercase, do a case insensitive search.
57
+ return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true});
58
+ }
59
+
60
+ function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
61
+ cm.openDialog(text, onEnter, {
62
+ value: deflt,
63
+ selectValueOnOpen: true,
64
+ closeOnEnter: false,
65
+ onClose: function() { clearSearch(cm); },
66
+ onKeyDown: onKeyDown
67
+ });
68
+ }
69
+
70
+ function dialog(cm, text, shortText, deflt, f) {
71
+ if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true});
72
+ else f(prompt(shortText, deflt));
73
+ }
74
+
75
+ function confirmDialog(cm, text, shortText, fs) {
76
+ if (cm.openConfirm) cm.openConfirm(text, fs);
77
+ else if (confirm(shortText)) fs[0]();
78
+ }
79
+
80
+ function parseString(string) {
81
+ return string.replace(/\\(.)/g, function(_, ch) {
82
+ if (ch == "n") return "\n"
83
+ if (ch == "r") return "\r"
84
+ return ch
85
+ })
86
+ }
87
+
88
+ function parseQuery(query) {
89
+ var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
90
+ if (isRE) {
91
+ try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
92
+ catch(e) {} // Not a regular expression after all, do a string search
93
+ } else {
94
+ query = parseString(query)
95
+ }
96
+ if (typeof query == "string" ? query == "" : query.test(""))
97
+ query = /x^/;
98
+ return query;
99
+ }
100
+
101
+ var queryDialog =
102
+ '<span class="CodeMirror-search-label">Search:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
103
+
104
+ function startSearch(cm, state, query) {
105
+ state.queryText = query;
106
+ state.query = parseQuery(query);
107
+ cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
108
+ state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
109
+ cm.addOverlay(state.overlay);
110
+ if (cm.showMatchesOnScrollbar) {
111
+ if (state.annotate) { state.annotate.clear(); state.annotate = null; }
112
+ state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
113
+ }
114
+ }
115
+
116
+ function doSearch(cm, rev, persistent, immediate) {
117
+ var state = getSearchState(cm);
118
+ if (state.query) return findNext(cm, rev);
119
+ var q = cm.getSelection() || state.lastQuery;
120
+ if (q instanceof RegExp && q.source == "x^") q = null
121
+ if (persistent && cm.openDialog) {
122
+ var hiding = null
123
+ var searchNext = function(query, event) {
124
+ CodeMirror.e_stop(event);
125
+ if (!query) return;
126
+ if (query != state.queryText) {
127
+ startSearch(cm, state, query);
128
+ state.posFrom = state.posTo = cm.getCursor();
129
+ }
130
+ if (hiding) hiding.style.opacity = 1
131
+ findNext(cm, event.shiftKey, function(_, to) {
132
+ var dialog
133
+ if (to.line < 3 && document.querySelector &&
134
+ (dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) &&
135
+ dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
136
+ (hiding = dialog).style.opacity = .4
137
+ })
138
+ };
139
+ persistentDialog(cm, queryDialog, q, searchNext, function(event, query) {
140
+ var keyName = CodeMirror.keyName(event)
141
+ var extra = cm.getOption('extraKeys'), cmd = (extra && extra[keyName]) || CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
142
+ if (cmd == "findNext" || cmd == "findPrev" ||
143
+ cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
144
+ CodeMirror.e_stop(event);
145
+ startSearch(cm, getSearchState(cm), query);
146
+ cm.execCommand(cmd);
147
+ } else if (cmd == "find" || cmd == "findPersistent") {
148
+ CodeMirror.e_stop(event);
149
+ searchNext(query, event);
150
+ }
151
+ });
152
+ if (immediate && q) {
153
+ startSearch(cm, state, q);
154
+ findNext(cm, rev);
155
+ }
156
+ } else {
157
+ dialog(cm, queryDialog, "Search for:", q, function(query) {
158
+ if (query && !state.query) cm.operation(function() {
159
+ startSearch(cm, state, query);
160
+ state.posFrom = state.posTo = cm.getCursor();
161
+ findNext(cm, rev);
162
+ });
163
+ });
164
+ }
165
+ }
166
+
167
+ function findNext(cm, rev, callback) {cm.operation(function() {
168
+ var state = getSearchState(cm);
169
+ var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
170
+ if (!cursor.find(rev)) {
171
+ cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
172
+ if (!cursor.find(rev)) return;
173
+ }
174
+ cm.setSelection(cursor.from(), cursor.to());
175
+ cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
176
+ state.posFrom = cursor.from(); state.posTo = cursor.to();
177
+ if (callback) callback(cursor.from(), cursor.to())
178
+ });}
179
+
180
+ function clearSearch(cm) {cm.operation(function() {
181
+ var state = getSearchState(cm);
182
+ state.lastQuery = state.query;
183
+ if (!state.query) return;
184
+ state.query = state.queryText = null;
185
+ cm.removeOverlay(state.overlay);
186
+ if (state.annotate) { state.annotate.clear(); state.annotate = null; }
187
+ });}
188
+
189
+ var replaceQueryDialog =
190
+ ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>';
191
+ var replacementQueryDialog = '<span class="CodeMirror-search-label">With:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/>';
192
+ var doReplaceConfirm = '<span class="CodeMirror-search-label">Replace?</span> <button>Yes</button> <button>No</button> <button>All</button> <button>Stop</button>';
193
+
194
+ function replaceAll(cm, query, text) {
195
+ cm.operation(function() {
196
+ for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
197
+ if (typeof query != "string") {
198
+ var match = cm.getRange(cursor.from(), cursor.to()).match(query);
199
+ cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
200
+ } else cursor.replace(text);
201
+ }
202
+ });
203
+ }
204
+
205
+ function replace(cm, all) {
206
+ if (cm.getOption("readOnly")) return;
207
+ var query = cm.getSelection() || getSearchState(cm).lastQuery;
208
+ var dialogText = '<span class="CodeMirror-search-label">' + (all ? 'Replace all:' : 'Replace:') + '</span>';
209
+ dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) {
210
+ if (!query) return;
211
+ query = parseQuery(query);
212
+ dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) {
213
+ text = parseString(text)
214
+ if (all) {
215
+ replaceAll(cm, query, text)
216
+ } else {
217
+ clearSearch(cm);
218
+ var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
219
+ var advance = function() {
220
+ var start = cursor.from(), match;
221
+ if (!(match = cursor.findNext())) {
222
+ cursor = getSearchCursor(cm, query);
223
+ if (!(match = cursor.findNext()) ||
224
+ (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
225
+ }
226
+ cm.setSelection(cursor.from(), cursor.to());
227
+ cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
228
+ confirmDialog(cm, doReplaceConfirm, "Replace?",
229
+ [function() {doReplace(match);}, advance,
230
+ function() {replaceAll(cm, query, text)}]);
231
+ };
232
+ var doReplace = function(match) {
233
+ cursor.replace(typeof query == "string" ? text :
234
+ text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
235
+ advance();
236
+ };
237
+ advance();
238
+ }
239
+ });
240
+ });
241
+ }
242
+
243
+ CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
244
+ CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
245
+ CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);};
246
+ CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);};
247
+ CodeMirror.commands.findNext = doSearch;
248
+ CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
249
+ CodeMirror.commands.clearSearch = clearSearch;
250
+ CodeMirror.commands.replace = replace;
251
+ CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
252
+ });
lib/codemirror/addon/search/search.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror"),require("./searchcursor"),require("../dialog/dialog")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./searchcursor","../dialog/dialog"],e):e(CodeMirror)}(function(e){"use strict";function n(e,n){return"string"==typeof e?e=new RegExp(e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),n?"gi":"g"):e.global||(e=new RegExp(e.source,e.ignoreCase?"gi":"g")),{token:function(n){e.lastIndex=n.pos;var o=e.exec(n.string);if(o&&o.index==n.pos)return n.pos+=o[0].length||1,"searching";o?n.pos=o.index:n.skipToEnd()}}}function o(){this.posFrom=this.posTo=this.lastQuery=this.query=null,this.overlay=null}function t(e){return e.state.search||(e.state.search=new o)}function r(e){return"string"==typeof e&&e==e.toLowerCase()}function i(e,n,o){return e.getSearchCursor(n,o,{caseFold:r(n),multiline:!0})}function a(e,n,o,t,r){e.openDialog(n,t,{value:o,selectValueOnOpen:!0,closeOnEnter:!1,onClose:function(){y(e)},onKeyDown:r})}function s(e,n,o,t,r){e.openDialog?e.openDialog(n,r,{value:t,selectValueOnOpen:!0}):r(prompt(o,t))}function c(e,n,o,t){e.openConfirm?e.openConfirm(n,t):confirm(o)&&t[0]()}function l(e){return e.replace(/\\(.)/g,function(e,n){return"n"==n?"\n":"r"==n?"\r":n})}function u(e){var n=e.match(/^\/(.*)\/([a-z]*)$/);if(n)try{e=new RegExp(n[1],-1==n[2].indexOf("i")?"":"i")}catch(e){}else e=l(e);return("string"==typeof e?""==e:e.test(""))&&(e=/x^/),e}function f(e,o,t){o.queryText=t,o.query=u(t),e.removeOverlay(o.overlay,r(o.query)),o.overlay=n(o.query,r(o.query)),e.addOverlay(o.overlay),e.showMatchesOnScrollbar&&(o.annotate&&(o.annotate.clear(),o.annotate=null),o.annotate=e.showMatchesOnScrollbar(o.query,r(o.query)))}function p(n,o,r,i){var c=t(n);if(c.query)return d(n,o);var l=n.getSelection()||c.lastQuery;if(l instanceof RegExp&&"x^"==l.source&&(l=null),r&&n.openDialog){var u=null,p=function(o,t){e.e_stop(t),o&&(o!=c.queryText&&(f(n,c,o),c.posFrom=c.posTo=n.getCursor()),u&&(u.style.opacity=1),d(n,t.shiftKey,function(e,o){var t;o.line<3&&document.querySelector&&(t=n.display.wrapper.querySelector(".CodeMirror-dialog"))&&t.getBoundingClientRect().bottom-4>n.cursorCoords(o,"window").top&&((u=t).style.opacity=.4)}))};a(n,h,l,p,function(o,r){var i=e.keyName(o),a=n.getOption("extraKeys"),s=a&&a[i]||e.keyMap[n.getOption("keyMap")][i];"findNext"==s||"findPrev"==s||"findPersistentNext"==s||"findPersistentPrev"==s?(e.e_stop(o),f(n,t(n),r),n.execCommand(s)):"find"!=s&&"findPersistent"!=s||(e.e_stop(o),p(r,o))}),i&&l&&(f(n,c,l),d(n,o))}else s(n,h,"Search for:",l,function(e){e&&!c.query&&n.operation(function(){f(n,c,e),c.posFrom=c.posTo=n.getCursor(),d(n,o)})})}function d(n,o,r){n.operation(function(){var a=t(n),s=i(n,a.query,o?a.posFrom:a.posTo);(s.find(o)||(s=i(n,a.query,o?e.Pos(n.lastLine()):e.Pos(n.firstLine(),0)),s.find(o)))&&(n.setSelection(s.from(),s.to()),n.scrollIntoView({from:s.from(),to:s.to()},20),a.posFrom=s.from(),a.posTo=s.to(),r&&r(s.from(),s.to()))})}function y(e){e.operation(function(){var n=t(e);n.lastQuery=n.query,n.query&&(n.query=n.queryText=null,e.removeOverlay(n.overlay),n.annotate&&(n.annotate.clear(),n.annotate=null))})}function m(e,n,o){e.operation(function(){for(var t=i(e,n);t.findNext();)if("string"!=typeof n){var r=e.getRange(t.from(),t.to()).match(n);t.replace(o.replace(/\$(\d)/g,function(e,n){return r[n]}))}else t.replace(o)})}function g(e,n){if(!e.getOption("readOnly")){var o=e.getSelection()||t(e).lastQuery,r='<span class="CodeMirror-search-label">'+(n?"Replace all:":"Replace:")+"</span>";s(e,r+v,r,o,function(o){o&&(o=u(o),s(e,x,"Replace with:","",function(t){if(t=l(t),n)m(e,o,t);else{y(e);var r=i(e,o,e.getCursor("from")),a=function(){var n,l=r.from();!(n=r.findNext())&&(r=i(e,o),!(n=r.findNext())||l&&r.from().line==l.line&&r.from().ch==l.ch)||(e.setSelection(r.from(),r.to()),e.scrollIntoView({from:r.from(),to:r.to()}),c(e,C,"Replace?",[function(){s(n)},a,function(){m(e,o,t)}]))},s=function(e){r.replace("string"==typeof o?t:t.replace(/\$(\d)/g,function(n,o){return e[o]})),a()};a()}}))})}}var h='<span class="CodeMirror-search-label">Search:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>',v=' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>',x='<span class="CodeMirror-search-label">With:</span> <input type="text" style="width: 10em" class="CodeMirror-search-field"/>',C='<span class="CodeMirror-search-label">Replace?</span> <button>Yes</button> <button>No</button> <button>All</button> <button>Stop</button>';e.commands.find=function(e){y(e),p(e)},e.commands.findPersistent=function(e){y(e),p(e,!1,!0)},e.commands.findPersistentNext=function(e){p(e,!1,!0,!0)},e.commands.findPersistentPrev=function(e){p(e,!0,!0,!0)},e.commands.findNext=p,e.commands.findPrev=function(e){p(e,!0)},e.commands.clearSearch=y,e.commands.replace=g,e.commands.replaceAll=function(e){g(e,!0)}});
lib/codemirror/addon/search/searchcursor.js ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror, copyright (c) by Marijn Haverbeke and others
2
+ // Distributed under an MIT license: http://codemirror.net/LICENSE
3
+
4
+ (function(mod) {
5
+ if (typeof exports == "object" && typeof module == "object") // CommonJS
6
+ mod(require("../../lib/codemirror"))
7
+ else if (typeof define == "function" && define.amd) // AMD
8
+ define(["../../lib/codemirror"], mod)
9
+ else // Plain browser env
10
+ mod(CodeMirror)
11
+ })(function(CodeMirror) {
12
+ "use strict"
13
+ var Pos = CodeMirror.Pos
14
+
15
+ function regexpFlags(regexp) {
16
+ var flags = regexp.flags
17
+ return flags != null ? flags : (regexp.ignoreCase ? "i" : "")
18
+ + (regexp.global ? "g" : "")
19
+ + (regexp.multiline ? "m" : "")
20
+ }
21
+
22
+ function ensureFlags(regexp, flags) {
23
+ var current = regexpFlags(regexp), target = current
24
+ for (var i = 0; i < flags.length; i++) if (target.indexOf(flags.charAt(i)) == -1)
25
+ target += flags.charAt(i)
26
+ return current == target ? regexp : new RegExp(regexp.source, target)
27
+ }
28
+
29
+ function maybeMultiline(regexp) {
30
+ return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source)
31
+ }
32
+
33
+ function searchRegexpForward(doc, regexp, start) {
34
+ regexp = ensureFlags(regexp, "g")
35
+ for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) {
36
+ regexp.lastIndex = ch
37
+ var string = doc.getLine(line), match = regexp.exec(string)
38
+ if (match)
39
+ return {from: Pos(line, match.index),
40
+ to: Pos(line, match.index + match[0].length),
41
+ match: match}
42
+ }
43
+ }
44
+
45
+ function searchRegexpForwardMultiline(doc, regexp, start) {
46
+ if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start)
47
+
48
+ regexp = ensureFlags(regexp, "gm")
49
+ var string, chunk = 1
50
+ for (var line = start.line, last = doc.lastLine(); line <= last;) {
51
+ // This grows the search buffer in exponentially-sized chunks
52
+ // between matches, so that nearby matches are fast and don't
53
+ // require concatenating the whole document (in case we're
54
+ // searching for something that has tons of matches), but at the
55
+ // same time, the amount of retries is limited.
56
+ for (var i = 0; i < chunk; i++) {
57
+ if (line > last) break
58
+ var curLine = doc.getLine(line++)
59
+ string = string == null ? curLine : string + "\n" + curLine
60
+ }
61
+ chunk = chunk * 2
62
+ regexp.lastIndex = start.ch
63
+ var match = regexp.exec(string)
64
+ if (match) {
65
+ var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
66
+ var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length
67
+ return {from: Pos(startLine, startCh),
68
+ to: Pos(startLine + inside.length - 1,
69
+ inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
70
+ match: match}
71
+ }
72
+ }
73
+ }
74
+
75
+ function lastMatchIn(string, regexp) {
76
+ var cutOff = 0, match
77
+ for (;;) {
78
+ regexp.lastIndex = cutOff
79
+ var newMatch = regexp.exec(string)
80
+ if (!newMatch) return match
81
+ match = newMatch
82
+ cutOff = match.index + (match[0].length || 1)
83
+ if (cutOff == string.length) return match
84
+ }
85
+ }
86
+
87
+ function searchRegexpBackward(doc, regexp, start) {
88
+ regexp = ensureFlags(regexp, "g")
89
+ for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
90
+ var string = doc.getLine(line)
91
+ if (ch > -1) string = string.slice(0, ch)
92
+ var match = lastMatchIn(string, regexp)
93
+ if (match)
94
+ return {from: Pos(line, match.index),
95
+ to: Pos(line, match.index + match[0].length),
96
+ match: match}
97
+ }
98
+ }
99
+
100
+ function searchRegexpBackwardMultiline(doc, regexp, start) {
101
+ regexp = ensureFlags(regexp, "gm")
102
+ var string, chunk = 1
103
+ for (var line = start.line, first = doc.firstLine(); line >= first;) {
104
+ for (var i = 0; i < chunk; i++) {
105
+ var curLine = doc.getLine(line--)
106
+ string = string == null ? curLine.slice(0, start.ch) : curLine + "\n" + string
107
+ }
108
+ chunk *= 2
109
+
110
+ var match = lastMatchIn(string, regexp)
111
+ if (match) {
112
+ var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
113
+ var startLine = line + before.length, startCh = before[before.length - 1].length
114
+ return {from: Pos(startLine, startCh),
115
+ to: Pos(startLine + inside.length - 1,
116
+ inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
117
+ match: match}
118
+ }
119
+ }
120
+ }
121
+
122
+ var doFold, noFold
123
+ if (String.prototype.normalize) {
124
+ doFold = function(str) { return str.normalize("NFD").toLowerCase() }
125
+ noFold = function(str) { return str.normalize("NFD") }
126
+ } else {
127
+ doFold = function(str) { return str.toLowerCase() }
128
+ noFold = function(str) { return str }
129
+ }
130
+
131
+ // Maps a position in a case-folded line back to a position in the original line
132
+ // (compensating for codepoints increasing in number during folding)
133
+ function adjustPos(orig, folded, pos, foldFunc) {
134
+ if (orig.length == folded.length) return pos
135
+ for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) {
136
+ if (min == max) return min
137
+ var mid = (min + max) >> 1
138
+ var len = foldFunc(orig.slice(0, mid)).length
139
+ if (len == pos) return mid
140
+ else if (len > pos) max = mid
141
+ else min = mid + 1
142
+ }
143
+ }
144
+
145
+ function searchStringForward(doc, query, start, caseFold) {
146
+ // Empty string would match anything and never progress, so we
147
+ // define it to match nothing instead.
148
+ if (!query.length) return null
149
+ var fold = caseFold ? doFold : noFold
150
+ var lines = fold(query).split(/\r|\n\r?/)
151
+
152
+ search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) {
153
+ var orig = doc.getLine(line).slice(ch), string = fold(orig)
154
+ if (lines.length == 1) {
155
+ var found = string.indexOf(lines[0])
156
+ if (found == -1) continue search
157
+ var start = adjustPos(orig, string, found, fold) + ch
158
+ return {from: Pos(line, adjustPos(orig, string, found, fold) + ch),
159
+ to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)}
160
+ } else {
161
+ var cutFrom = string.length - lines[0].length
162
+ if (string.slice(cutFrom) != lines[0]) continue search
163
+ for (var i = 1; i < lines.length - 1; i++)
164
+ if (fold(doc.getLine(line + i)) != lines[i]) continue search
165
+ var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1]
166
+ if (endString.slice(0, lastLine.length) != lastLine) continue search
167
+ return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch),
168
+ to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))}
169
+ }
170
+ }
171
+ }
172
+
173
+ function searchStringBackward(doc, query, start, caseFold) {
174
+ if (!query.length) return null
175
+ var fold = caseFold ? doFold : noFold
176
+ var lines = fold(query).split(/\r|\n\r?/)
177
+
178
+ search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) {
179
+ var orig = doc.getLine(line)
180
+ if (ch > -1) orig = orig.slice(0, ch)
181
+ var string = fold(orig)
182
+ if (lines.length == 1) {
183
+ var found = string.lastIndexOf(lines[0])
184
+ if (found == -1) continue search
185
+ return {from: Pos(line, adjustPos(orig, string, found, fold)),
186
+ to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))}
187
+ } else {
188
+ var lastLine = lines[lines.length - 1]
189
+ if (string.slice(0, lastLine.length) != lastLine) continue search
190
+ for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++)
191
+ if (fold(doc.getLine(start + i)) != lines[i]) continue search
192
+ var top = doc.getLine(line + 1 - lines.length), topString = fold(top)
193
+ if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search
194
+ return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)),
195
+ to: Pos(line, adjustPos(orig, string, lastLine.length, fold))}
196
+ }
197
+ }
198
+ }
199
+
200
+ function SearchCursor(doc, query, pos, options) {
201
+ this.atOccurrence = false
202
+ this.doc = doc
203
+ pos = pos ? doc.clipPos(pos) : Pos(0, 0)
204
+ this.pos = {from: pos, to: pos}
205
+
206
+ var caseFold
207
+ if (typeof options == "object") {
208
+ caseFold = options.caseFold
209
+ } else { // Backwards compat for when caseFold was the 4th argument
210
+ caseFold = options
211
+ options = null
212
+ }
213
+
214
+ if (typeof query == "string") {
215
+ if (caseFold == null) caseFold = false
216
+ this.matches = function(reverse, pos) {
217
+ return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold)
218
+ }
219
+ } else {
220
+ query = ensureFlags(query, "gm")
221
+ if (!options || options.multiline !== false)
222
+ this.matches = function(reverse, pos) {
223
+ return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos)
224
+ }
225
+ else
226
+ this.matches = function(reverse, pos) {
227
+ return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos)
228
+ }
229
+ }
230
+ }
231
+
232
+ SearchCursor.prototype = {
233
+ findNext: function() {return this.find(false)},
234
+ findPrevious: function() {return this.find(true)},
235
+
236
+ find: function(reverse) {
237
+ var result = this.matches(reverse, this.doc.clipPos(reverse ? this.pos.from : this.pos.to))
238
+
239
+ // Implements weird auto-growing behavior on null-matches for
240
+ // backwards-compatiblity with the vim code (unfortunately)
241
+ while (result && CodeMirror.cmpPos(result.from, result.to) == 0) {
242
+ if (reverse) {
243
+ if (result.from.ch) result.from = Pos(result.from.line, result.from.ch - 1)
244
+ else if (result.from.line == this.doc.firstLine()) result = null
245
+ else result = this.matches(reverse, this.doc.clipPos(Pos(result.from.line - 1)))
246
+ } else {
247
+ if (result.to.ch < this.doc.getLine(result.to.line).length) result.to = Pos(result.to.line, result.to.ch + 1)
248
+ else if (result.to.line == this.doc.lastLine()) result = null
249
+ else result = this.matches(reverse, Pos(result.to.line + 1, 0))
250
+ }
251
+ }
252
+
253
+ if (result) {
254
+ this.pos = result
255
+ this.atOccurrence = true
256
+ return this.pos.match || true
257
+ } else {
258
+ var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0)
259
+ this.pos = {from: end, to: end}
260
+ return this.atOccurrence = false
261
+ }
262
+ },
263
+
264
+ from: function() {if (this.atOccurrence) return this.pos.from},
265
+ to: function() {if (this.atOccurrence) return this.pos.to},
266
+
267
+ replace: function(newText, origin) {
268
+ if (!this.atOccurrence) return
269
+ var lines = CodeMirror.splitLines(newText)
270
+ this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin)
271
+ this.pos.to = Pos(this.pos.from.line + lines.length - 1,
272
+ lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0))
273
+ }
274
+ }
275
+
276
+ CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
277
+ return new SearchCursor(this.doc, query, pos, caseFold)
278
+ })
279
+ CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
280
+ return new SearchCursor(this, query, pos, caseFold)
281
+ })
282
+
283
+ CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
284
+ var ranges = []
285
+ var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold)
286
+ while (cur.findNext()) {
287
+ if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break
288
+ ranges.push({anchor: cur.from(), head: cur.to()})
289
+ }
290
+ if (ranges.length)
291
+ this.setSelections(ranges, 0)
292
+ })
293
+ });
lib/codemirror/addon/search/searchcursor.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],t):t(CodeMirror)}(function(t){"use strict";function n(t){var n=t.flags;return null!=n?n:(t.ignoreCase?"i":"")+(t.global?"g":"")+(t.multiline?"m":"")}function e(t,e){for(var r=n(t),i=r,o=0;o<e.length;o++)-1==i.indexOf(e.charAt(o))&&(i+=e.charAt(o));return r==i?t:new RegExp(t.source,i)}function r(t){return/\\s|\\n|\n|\\W|\\D|\[\^/.test(t.source)}function i(t,n,r){n=e(n,"g");for(var i=r.line,o=r.ch,l=t.lastLine();i<=l;i++,o=0){n.lastIndex=o;var h=t.getLine(i),s=n.exec(h);if(s)return{from:v(i,s.index),to:v(i,s.index+s[0].length),match:s}}}function o(t,n,o){if(!r(n))return i(t,n,o);n=e(n,"gm");for(var l,h=1,s=o.line,c=t.lastLine();s<=c;){for(var f=0;f<h&&!(s>c);f++){var u=t.getLine(s++);l=null==l?u:l+"\n"+u}h*=2,n.lastIndex=o.ch;var a=n.exec(l);if(a){var g=l.slice(0,a.index).split("\n"),m=a[0].split("\n"),d=o.line+g.length-1,p=g[g.length-1].length;return{from:v(d,p),to:v(d+m.length-1,1==m.length?p+m[0].length:m[m.length-1].length),match:a}}}}function l(t,n){for(var e,r=0;;){n.lastIndex=r;var i=n.exec(t);if(!i)return e;if(e=i,(r=e.index+(e[0].length||1))==t.length)return e}}function h(t,n,r){n=e(n,"g");for(var i=r.line,o=r.ch,h=t.firstLine();i>=h;i--,o=-1){var s=t.getLine(i);o>-1&&(s=s.slice(0,o));var c=l(s,n);if(c)return{from:v(i,c.index),to:v(i,c.index+c[0].length),match:c}}}function s(t,n,r){n=e(n,"gm");for(var i,o=1,h=r.line,s=t.firstLine();h>=s;){for(var c=0;c<o;c++){var f=t.getLine(h--);i=null==i?f.slice(0,r.ch):f+"\n"+i}o*=2;var u=l(i,n);if(u){var a=i.slice(0,u.index).split("\n"),g=u[0].split("\n"),m=h+a.length,d=a[a.length-1].length;return{from:v(m,d),to:v(m+g.length-1,1==g.length?d+g[0].length:g[g.length-1].length),match:u}}}}function c(t,n,e,r){if(t.length==n.length)return e;for(var i=0,o=e+Math.max(0,t.length-n.length);;){if(i==o)return i;var l=i+o>>1,h=r(t.slice(0,l)).length;if(h==e)return l;h>e?o=l:i=l+1}}function f(t,n,e,r){if(!n.length)return null;var i=r?g:m,o=i(n).split(/\r|\n\r?/);t:for(var l=e.line,h=e.ch,s=t.lastLine()+1-o.length;l<=s;l++,h=0){var f=t.getLine(l).slice(h),u=i(f);if(1==o.length){var a=u.indexOf(o[0]);if(-1==a)continue t;var e=c(f,u,a,i)+h;return{from:v(l,c(f,u,a,i)+h),to:v(l,c(f,u,a+o[0].length,i)+h)}}var d=u.length-o[0].length;if(u.slice(d)==o[0]){for(var p=1;p<o.length-1;p++)if(i(t.getLine(l+p))!=o[p])continue t;var x=t.getLine(l+o.length-1),L=i(x),C=o[o.length-1];if(L.slice(0,C.length)==C)return{from:v(l,c(f,u,d,i)+h),to:v(l+o.length-1,c(x,L,C.length,i))}}}}function u(t,n,e,r){if(!n.length)return null;var i=r?g:m,o=i(n).split(/\r|\n\r?/);t:for(var l=e.line,h=e.ch,s=t.firstLine()-1+o.length;l>=s;l--,h=-1){var f=t.getLine(l);h>-1&&(f=f.slice(0,h));var u=i(f);if(1==o.length){var a=u.lastIndexOf(o[0]);if(-1==a)continue t;return{from:v(l,c(f,u,a,i)),to:v(l,c(f,u,a+o[0].length,i))}}var d=o[o.length-1];if(u.slice(0,d.length)==d){for(var p=1,e=l-o.length+1;p<o.length-1;p++)if(i(t.getLine(e+p))!=o[p])continue t;var x=t.getLine(l+1-o.length),L=i(x);if(L.slice(L.length-o[0].length)==o[0])return{from:v(l+1-o.length,c(x,L,x.length-o[0].length,i)),to:v(l,c(f,u,d.length,i))}}}}function a(t,n,r,l){this.atOccurrence=!1,this.doc=t,r=r?t.clipPos(r):v(0,0),this.pos={from:r,to:r};var c;"object"==typeof l?c=l.caseFold:(c=l,l=null),"string"==typeof n?(null==c&&(c=!1),this.matches=function(e,r){return(e?u:f)(t,n,r,c)}):(n=e(n,"gm"),l&&!1===l.multiline?this.matches=function(e,r){return(e?h:i)(t,n,r)}:this.matches=function(e,r){return(e?s:o)(t,n,r)})}var g,m,v=t.Pos;String.prototype.normalize?(g=function(t){return t.normalize("NFD").toLowerCase()},m=function(t){return t.normalize("NFD")}):(g=function(t){return t.toLowerCase()},m=function(t){return t}),a.prototype={findNext:function(){return this.find(!1)},findPrevious:function(){return this.find(!0)},find:function(n){for(var e=this.matches(n,this.doc.clipPos(n?this.pos.from:this.pos.to));e&&0==t.cmpPos(e.from,e.to);)n?e.from.ch?e.from=v(e.from.line,e.from.ch-1):e=e.from.line==this.doc.firstLine()?null:this.matches(n,this.doc.clipPos(v(e.from.line-1))):e.to.ch<this.doc.getLine(e.to.line).length?e.to=v(e.to.line,e.to.ch+1):e=e.to.line==this.doc.lastLine()?null:this.matches(n,v(e.to.line+1,0));if(e)return this.pos=e,this.atOccurrence=!0,this.pos.match||!0;var r=v(n?this.doc.firstLine():this.doc.lastLine()+1,0);return this.pos={from:r,to:r},this.atOccurrence=!1},from:function(){if(this.atOccurrence)return this.pos.from},to:function(){if(this.atOccurrence)return this.pos.to},replace:function(n,e){if(this.atOccurrence){var r=t.splitLines(n);this.doc.replaceRange(r,this.pos.from,this.pos.to,e),this.pos.to=v(this.pos.from.line+r.length-1,r[r.length-1].length+(1==r.length?this.pos.from.ch:0))}}},t.defineExtension("getSearchCursor",function(t,n,e){return new a(this.doc,t,n,e)}),t.defineDocExtension("getSearchCursor",function(t,n,e){return new a(this,t,n,e)}),t.defineExtension("selectMatches",function(n,e){for(var r=[],i=this.getSearchCursor(n,this.getCursor("from"),e);i.findNext()&&!(t.cmpPos(i.to(),this.getCursor("to"))>0);)r.push({anchor:i.from(),head:i.to()});r.length&&this.setSelections(r,0)})});
readme.txt CHANGED
@@ -1,138 +1,146 @@
1
- === SiteOrigin CSS ===
2
- Tags: css, design, edit, customize
3
- Requires at least: 3.9
4
- Tested up to: 4.9
5
- Stable tag: 1.1.5
6
- Build time: 2017-09-19T17:05:02+02:00
7
- License: GPLv2 or later
8
- Contributors: gpriday
9
- Donate link: https://siteorigin.com/downloads/contribution/
10
-
11
- SiteOrigin CSS is the simple, yet powerful CSS editor for WordPress. It gives you visual controls that let you edit the look and feel of your site in real-time.
12
-
13
- == Description ==
14
-
15
- SiteOrigin CSS is the simple, yet powerful CSS editor for WordPress. It gives you visual controls that let you edit the look and feel of your site in real-time.
16
-
17
- We've created a site editing experience that will suit both beginners and advanced users alike. Beginners will love the simple visual controls and real-time preview. Advanced users will love the code autocompletion that makes writing CSS faster than ever.
18
-
19
- [vimeo https://vimeo.com/129660380]
20
-
21
- = Inspector =
22
-
23
- The hardest part of editing your site's design using CSS is usually finding the correct selector to use. The powerful inspector that comes with SiteOrigin CSS makes this easy. While viewing a full preview of your site, just click on an element and it'll help you identify the best selector to use to target that element.
24
-
25
- The Inspector will help you even if you have no idea what a CSS selector is.
26
-
27
- = Visual Editor =
28
-
29
- Don't like playing around with code? No problem. SiteOrigin CSS has a set of simple controls that make it easy to choose colors, styles and measurements. Combined with the Inspector, you'll be able to make changes in just a few clicks.
30
-
31
- = CSS Editor =
32
-
33
- SiteOrigin CSS has a powerful CSS editor, the likes of which you'd usually only expect from high-end IDEs. It has autocompletion for both CSS selectors and attributes. It also features very useful CSS linting that'll help you identify issues in your code before you publish your changes.
34
-
35
- = It's Free =
36
-
37
- We're committed to keeping SiteOrigin CSS, free. You can install it on as many sites as you like without ever worrying about licensing. All future updates and upgrades will be free, and we even offer free support over on our friendly support forums.
38
-
39
- = Works With Any Theme =
40
-
41
- There's an ever-growing collection of awesome WordPress themes, and now with SiteOrigin CSS you can edit every single one of them to your heart's content. No matter what theme you're using, SiteOrigin CSS will work perfectly.
42
-
43
- = Actively Developed =
44
-
45
- We're actively developing SiteOrigin CSS. Keep track of what's happening over on [GitHub](https://github.com/siteorigin/so-css/).
46
-
47
- == Installation ==
48
-
49
- 1. Upload and install SiteOrigin CSS in the same way you'd install any other plugin.
50
- 2. Read the [usage documentation](http://siteorigin.com/css/getting-started/) on SiteOrigin.
51
-
52
- == Screenshots ==
53
- 1. Inspector for finding elements on your site.
54
- 2. Simple visual controls including a background image uploader.
55
- 3. A full CSS editor that works in real-time with a preview of your site.
56
- 4. Code completion for all your theme's selectors.
57
-
58
- == Documentation ==
59
-
60
- [Documentation](https://siteorigin.com/css/getting-started/) is available on SiteOrigin.
61
-
62
- == Support ==
63
-
64
- We offer free support on the [SiteOrigin support forums](https://siteorigin.com/thread/).
65
-
66
- == Changelog ==
67
-
68
- = 1.1.5 - 19 September 2017 =
69
- * Use `home_url` instead of `site_url` to determine where to open CSS preview.
70
- * Increment and decrement buttons work when value empty or zero. Also added repeating action while button held down.
71
- * Scroll editor instead of the whole page so 'Save' button is always visible.
72
- * Set color CSS on visual editor and inspector.
73
- * Saving generated CSS to stylesheet file in uploads directory.
74
-
75
- = 1.1.4 - 31 January 2017 =
76
- * Updated CodeMirror to 2.25.2.
77
- * Removed extra line padding.
78
- * Better integration with WordPress.org translation.
79
-
80
- = 1.1.3 - 31 January 2017 =
81
- * Removed leading slash in paths after plugin_dir_url().
82
- * Updated to latest CodeMirror.
83
- * Fixed padding issue that was causing problems with Firefox and the color picker.
84
-
85
- = 1.1.2 - 11 November 2016 =
86
- * Ignore anything other than actual rules in media query subrules.
87
- * Removed depreciated jQuery function.
88
- * Updated CSSLint library.
89
- * Updated minicolors.
90
-
91
- = 1.1.1 - 28 September 2016 =
92
- * Properly handle errors in frontend CSS.
93
- * Added notice about SiteOrigin Premium.
94
-
95
- = 1.1 - 26 September 2016 =
96
- * Changed CSS parsing library. Fixed several issues with the visual editor mode.
97
- * Added address bar to preview window.
98
- * Small CSS fixes.
99
- * Small changes to allow adding more visual editor fields.
100
-
101
- = 1.0.8 - 15 August 2016 =
102
- * Fixed action link.
103
- * Support for GlotPress.
104
- * Removed unused code.
105
- * Handling of @imports for future addons.
106
-
107
- = 1.0.7 - 4 July 2016 =
108
- * Ensure user can copy/paste in editor via context menu.
109
- * Added plugin action links
110
- * Add classes on `body` element to selectors window.
111
-
112
- = 1.0.6 - 24 February 2016 =
113
- * Disabled autocompletion on single item (automatic autocompletion).
114
- * Fixed conflict with NextGen Gallery.
115
- * Only display relevant linting messages.
116
-
117
- = 1.0.5 - 21 January 2016 =
118
- * Updated to latest version of Code Mirror.
119
-
120
- = 1.0.4 - 10 November 2015 =
121
- * Fixed CSS parsing when going into visual mode.
122
-
123
- = 1.0.3 - 29 October 2015 =
124
- * Changed video image
125
- * Adjust revision times by GMT offset.
126
- * Don't overwrite media queries sub styles, rather just append them.
127
-
128
- = 1.0.2 =
129
- * Dequeue functionality that conflicted with WordPress color picker, if it's enqueued.
130
- * Removed wp_styles for compatibility with older versions of WordPress
131
-
132
- = 1.0.1 =
133
- * Fixed conflicts with CSS editor in SiteOrigin themes.
134
- * Force dequeue scripts that cause problems with main editing interface.
135
- * Made it easier to follow links with inspector enabled.
136
-
137
- = 1.0 =
138
- * Initial release.
 
 
 
 
 
 
 
 
1
+ === SiteOrigin CSS ===
2
+ Tags: css, design, edit, customize
3
+ Requires at least: 3.9
4
+ Tested up to: 4.9
5
+ Stable tag: 1.2.0
6
+ Build time: 2018-06-06T16:02:13+02:00
7
+ License: GPLv2 or later
8
+ Contributors: gpriday
9
+ Donate link: https://siteorigin.com/downloads/contribution/
10
+
11
+ SiteOrigin CSS is the simple, yet powerful CSS editor for WordPress. It gives you visual controls that let you edit the look and feel of your site in real-time.
12
+
13
+ == Description ==
14
+
15
+ SiteOrigin CSS is the simple, yet powerful CSS editor for WordPress. It gives you visual controls that let you edit the look and feel of your site in real-time.
16
+
17
+ We've created a site editing experience that will suit both beginners and advanced users alike. Beginners will love the simple visual controls and real-time preview. Advanced users will love the code autocompletion that makes writing CSS faster than ever.
18
+
19
+ [vimeo https://vimeo.com/129660380]
20
+
21
+ = Inspector =
22
+
23
+ The hardest part of editing your site's design using CSS is usually finding the correct selector to use. The powerful inspector that comes with SiteOrigin CSS makes this easy. While viewing a full preview of your site, just click on an element and it'll help you identify the best selector to use to target that element.
24
+
25
+ The Inspector will help you even if you have no idea what a CSS selector is.
26
+
27
+ = Visual Editor =
28
+
29
+ Don't like playing around with code? No problem. SiteOrigin CSS has a set of simple controls that make it easy to choose colors, styles and measurements. Combined with the Inspector, you'll be able to make changes in just a few clicks.
30
+
31
+ = CSS Editor =
32
+
33
+ SiteOrigin CSS has a powerful CSS editor, the likes of which you'd usually only expect from high-end IDEs. It has autocompletion for both CSS selectors and attributes. It also features very useful CSS linting that'll help you identify issues in your code before you publish your changes.
34
+
35
+ = It's Free =
36
+
37
+ We're committed to keeping SiteOrigin CSS, free. You can install it on as many sites as you like without ever worrying about licensing. All future updates and upgrades will be free, and we even offer free support over on our friendly support forums.
38
+
39
+ = Works With Any Theme =
40
+
41
+ There's an ever-growing collection of awesome WordPress themes, and now with SiteOrigin CSS you can edit every single one of them to your heart's content. No matter what theme you're using, SiteOrigin CSS will work perfectly.
42
+
43
+ = Actively Developed =
44
+
45
+ We're actively developing SiteOrigin CSS. Keep track of what's happening over on [GitHub](https://github.com/siteorigin/so-css/).
46
+
47
+ == Installation ==
48
+
49
+ 1. Upload and install SiteOrigin CSS in the same way you'd install any other plugin.
50
+ 2. Read the [usage documentation](http://siteorigin.com/css/getting-started/) on SiteOrigin.
51
+
52
+ == Screenshots ==
53
+ 1. Inspector for finding elements on your site.
54
+ 2. Simple visual controls including a background image uploader.
55
+ 3. A full CSS editor that works in real-time with a preview of your site.
56
+ 4. Code completion for all your theme's selectors.
57
+
58
+ == Documentation ==
59
+
60
+ [Documentation](https://siteorigin.com/css/getting-started/) is available on SiteOrigin.
61
+
62
+ == Support ==
63
+
64
+ We offer free support on the [SiteOrigin support forums](https://siteorigin.com/thread/).
65
+
66
+ == Changelog ==
67
+
68
+ = 1.2.0 - 6 June 2018 =
69
+ * Updated CSS library.
70
+ * UI changes to make it more obvious when viewing revision.
71
+ * Ensure revisions are sorted in descending time order.
72
+ * Don't link to revision currently being displayed.
73
+ * Add search functionality to editor.
74
+ * Enable persistent search and JumpToLine.
75
+
76
+ = 1.1.5 - 19 September 2017 =
77
+ * Use `home_url` instead of `site_url` to determine where to open CSS preview.
78
+ * Increment and decrement buttons work when value empty or zero. Also added repeating action while button held down.
79
+ * Scroll editor instead of the whole page so 'Save' button is always visible.
80
+ * Set color CSS on visual editor and inspector.
81
+ * Saving generated CSS to stylesheet file in uploads directory.
82
+
83
+ = 1.1.4 - 31 January 2017 =
84
+ * Updated CodeMirror to 2.25.2.
85
+ * Removed extra line padding.
86
+ * Better integration with WordPress.org translation.
87
+
88
+ = 1.1.3 - 31 January 2017 =
89
+ * Removed leading slash in paths after plugin_dir_url().
90
+ * Updated to latest CodeMirror.
91
+ * Fixed padding issue that was causing problems with Firefox and the color picker.
92
+
93
+ = 1.1.2 - 11 November 2016 =
94
+ * Ignore anything other than actual rules in media query subrules.
95
+ * Removed depreciated jQuery function.
96
+ * Updated CSSLint library.
97
+ * Updated minicolors.
98
+
99
+ = 1.1.1 - 28 September 2016 =
100
+ * Properly handle errors in frontend CSS.
101
+ * Added notice about SiteOrigin Premium.
102
+
103
+ = 1.1 - 26 September 2016 =
104
+ * Changed CSS parsing library. Fixed several issues with the visual editor mode.
105
+ * Added address bar to preview window.
106
+ * Small CSS fixes.
107
+ * Small changes to allow adding more visual editor fields.
108
+
109
+ = 1.0.8 - 15 August 2016 =
110
+ * Fixed action link.
111
+ * Support for GlotPress.
112
+ * Removed unused code.
113
+ * Handling of @imports for future addons.
114
+
115
+ = 1.0.7 - 4 July 2016 =
116
+ * Ensure user can copy/paste in editor via context menu.
117
+ * Added plugin action links
118
+ * Add classes on `body` element to selectors window.
119
+
120
+ = 1.0.6 - 24 February 2016 =
121
+ * Disabled autocompletion on single item (automatic autocompletion).
122
+ * Fixed conflict with NextGen Gallery.
123
+ * Only display relevant linting messages.
124
+
125
+ = 1.0.5 - 21 January 2016 =
126
+ * Updated to latest version of Code Mirror.
127
+
128
+ = 1.0.4 - 10 November 2015 =
129
+ * Fixed CSS parsing when going into visual mode.
130
+
131
+ = 1.0.3 - 29 October 2015 =
132
+ * Changed video image
133
+ * Adjust revision times by GMT offset.
134
+ * Don't overwrite media queries sub styles, rather just append them.
135
+
136
+ = 1.0.2 =
137
+ * Dequeue functionality that conflicted with WordPress color picker, if it's enqueued.
138
+ * Removed wp_styles for compatibility with older versions of WordPress
139
+
140
+ = 1.0.1 =
141
+ * Fixed conflicts with CSS editor in SiteOrigin themes.
142
+ * Force dequeue scripts that cause problems with main editing interface.
143
+ * Made it easier to follow links with inspector enabled.
144
+
145
+ = 1.0 =
146
+ * Initial release.
so-css.php CHANGED
@@ -1,491 +1,774 @@
1
- <?php
2
- /*
3
- Plugin Name: SiteOrigin CSS
4
- Description: An advanced CSS editor from SiteOrigin.
5
- Version: 1.1.5
6
- Author: SiteOrigin
7
- Author URI: https://siteorigin.com
8
- Plugin URI: https://siteorigin.com/css/
9
- License: GPL3
10
- License URI: https://www.gnu.org/licenses/gpl-3.0.txt
11
- Text Domain: so-css
12
- */
13
-
14
- // Handle the legacy CSS editor that came with SiteOrigin themes
15
- include plugin_dir_path( __FILE__ ) . 'inc/legacy.php';
16
-
17
- define('SOCSS_VERSION', '1.1.5');
18
- define('SOCSS_JS_SUFFIX', '.min');
19
-
20
- /**
21
- * Class SiteOrigin_CSS The main class for the SiteOrigin CSS Editor
22
- */
23
- class SiteOrigin_CSS {
24
- private $theme;
25
- private $snippet_paths;
26
-
27
- function __construct(){
28
- $this->theme = basename( get_template_directory() );
29
- $this->snippet_paths = array();
30
-
31
- // Main header actions
32
- add_action( 'plugins_loaded', array($this, 'set_plugin_textdomain') );
33
- add_action( 'wp_head', array($this, 'action_wp_head'), 20 );
34
-
35
- // All the admin actions
36
- add_action( 'admin_menu', array($this, 'action_admin_menu') );
37
- add_action( 'admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'), 20 );
38
- add_action( 'admin_enqueue_scripts', array($this, 'dequeue_admin_scripts'), 19 );
39
- add_action( 'load-appearance_page_so_custom_css', array($this, 'add_help_tab') );
40
- add_action( 'admin_footer', array($this, 'action_admin_footer') );
41
-
42
- // Add the action links.
43
- add_action( 'plugin_action_links_' . plugin_basename(__FILE__), array($this, 'plugin_action_links') );
44
-
45
- // The request to hide the getting started video
46
- add_action( 'wp_ajax_socss_hide_getting_started', array( $this, 'admin_action_hide_getting_started' ) );
47
-
48
- if( isset( $_GET['so_css_preview'] ) && !is_admin() ) {
49
-
50
- add_action( 'plugins_loaded', array($this, 'disable_ngg_resource_manager') );
51
- add_filter( 'show_admin_bar', '__return_false' );
52
- add_filter( 'wp_enqueue_scripts', array($this, 'enqueue_inspector_scripts') );
53
- add_filter( 'wp_footer', array($this, 'inspector_templates') );
54
-
55
- // We'll be grabbing all the enqueued scripts and outputting them
56
- add_action( 'wp_enqueue_scripts', array($this, 'inline_inspector_scripts'), 100 );
57
- }
58
- }
59
-
60
- /**
61
- * Get a singleton of the SiteOrigin CSS.
62
- *
63
- * @return SiteOrigin_CSS
64
- */
65
- static function single(){
66
- static $single;
67
-
68
- if( empty($single) ) {
69
- $single = new SiteOrigin_CSS();
70
- }
71
-
72
- return $single;
73
- }
74
-
75
- /**
76
- * Display the custom CSS in the header.
77
- */
78
- function action_wp_head() {
79
- $upload_dir = wp_upload_dir();
80
- $upload_dir_path = $upload_dir['basedir'] . '/so-css/';
81
-
82
- $css_file_name = 'so-css-' . $this->theme;
83
- $css_file_path = $upload_dir_path . $css_file_name . '.css';
84
-
85
- if ( empty( $_GET['so_css_preview'] ) && ! is_admin() && file_exists( $css_file_path ) ) {
86
- wp_enqueue_style(
87
- 'so-css-' . $this->theme,
88
- set_url_scheme( $upload_dir['baseurl'] . '/so-css/' . $css_file_name . '.css' ),
89
- array(),
90
- $this->get_latest_revision_timestamp()
91
- );
92
- } else {
93
- $custom_css = get_option( 'siteorigin_custom_css[' . $this->theme . ']', '' );
94
- // We just need to enqueue a dummy style
95
- if ( ! empty( $custom_css ) ) {
96
- echo "<style id='" . sanitize_html_class($this->theme) . "-custom-css' class='siteorigin-custom-css' type='text/css'>\n";
97
- echo self::sanitize_css( $custom_css ) . "\n";
98
- echo "</style>\n";
99
- }
100
- }
101
- }
102
-
103
- function set_plugin_textdomain(){
104
- load_plugin_textdomain( 'so-css', false, plugin_dir_path( __FILE__ ) . 'lang/' );
105
- }
106
-
107
- /**
108
- * Action to run on the admin action.
109
- */
110
- function action_admin_menu(){
111
- add_theme_page( __( 'Custom CSS', 'so-css' ), __( 'Custom CSS', 'so-css' ), 'edit_theme_options', 'so_custom_css', array( $this, 'display_admin_page' ) );
112
-
113
- if ( current_user_can('edit_theme_options') && isset( $_POST['siteorigin_custom_css_save'] ) ) {
114
- check_admin_referer( 'custom_css', '_sononce' );
115
-
116
- // Sanitize CSS input. Should keep most tags, apart from script and style tags.
117
- $custom_css = self::sanitize_css( filter_input(INPUT_POST, 'custom_css' ) );
118
-
119
- $current = get_option('siteorigin_custom_css[' . $this->theme . ']');
120
- if( $current === false ) {
121
- add_option( 'siteorigin_custom_css[' . $this->theme . ']', $custom_css , '', 'no' );
122
- }
123
- else {
124
- update_option( 'siteorigin_custom_css[' . $this->theme . ']', $custom_css );
125
- }
126
-
127
- // If this has changed, then add a revision.
128
- if ( $current != $custom_css ) {
129
- $revisions = get_option( 'siteorigin_custom_css_revisions[' . $this->theme . ']' );
130
- if ( empty( $revisions ) ) {
131
- add_option( 'siteorigin_custom_css_revisions[' . $this->theme . ']', array(), '', 'no' );
132
- $revisions = array();
133
- }
134
- $revisions[ time() ] = $custom_css;
135
-
136
- // Sort the revisions and cut off any old ones.
137
- krsort($revisions);
138
- $revisions = array_slice($revisions, 0, 15, true);
139
-
140
- update_option( 'siteorigin_custom_css_revisions[' . $this->theme . ']', $revisions );
141
-
142
- if( WP_Filesystem() ) {
143
- global $wp_filesystem;
144
- $upload_dir = wp_upload_dir();
145
- $upload_dir_path = $upload_dir['basedir'] . '/so-css/';
146
-
147
- if ( ! $wp_filesystem->is_dir( $upload_dir_path ) ) {
148
- $wp_filesystem->mkdir( $upload_dir_path );
149
- }
150
-
151
- $css_file_name = 'so-css-' . $this->theme;
152
- $css_file_path = $upload_dir_path . $css_file_name . '.css';
153
-
154
- if ( file_exists( $css_file_path ) ) {
155
- $wp_filesystem->delete( $css_file_path );
156
- }
157
-
158
- $wp_filesystem->put_contents(
159
- $css_file_path,
160
- $custom_css
161
- );
162
-
163
- }
164
- }
165
- }
166
- }
167
-
168
- /**
169
- * Display the help tab
170
- */
171
- function add_help_tab(){
172
- $screen = get_current_screen();
173
- $screen->add_help_tab( array(
174
- 'id' => 'custom-css',
175
- 'title' => __( 'Custom CSS', 'so-css' ),
176
- 'content' => '<p>'
177
- . sprintf( __( "SiteOrigin CSS adds any custom CSS you enter here into your site's header. ", 'so-css' ) )
178
- . __( "These changes will persist across updates so it's best to make all your changes here. ", 'so-css' )
179
- . '</p>'
180
- ) );
181
- }
182
-
183
- function enqueue_admin_scripts( $page ){
184
- if( $page != 'appearance_page_so_custom_css' ) return;
185
-
186
- // Core WordPress stuff that we use
187
- wp_enqueue_media();
188
-
189
- // Enqueue the codemirror scripts. Call Underscore and Backbone dependencies so they're enqueued first to prevent conflicts.
190
- wp_enqueue_script( 'codemirror', plugin_dir_url(__FILE__) . 'lib/codemirror/lib/codemirror' . SOCSS_JS_SUFFIX . '.js', array( 'underscore', 'backbone' ), '5.2.0' );
191
- wp_enqueue_script( 'codemirror-mode-css', plugin_dir_url(__FILE__) . 'lib/codemirror/mode/css/css' . SOCSS_JS_SUFFIX . '.js', array(), '5.2.0' );
192
-
193
- // Add in all the linting libs
194
- wp_enqueue_script( 'codemirror-lint', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/lint/lint' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror' ), '5.2.0' );
195
- wp_enqueue_script( 'codemirror-lint-css', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/lint/css-lint' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror', 'codemirror-lint-css-lib' ), '5.2.0' );
196
- wp_enqueue_script( 'codemirror-lint-css-lib', plugin_dir_url(__FILE__) . 'js/csslint' . SOCSS_JS_SUFFIX . '.js', array(), '0.10.0' );
197
-
198
- // The CodeMirror autocomplete library
199
- wp_enqueue_script( 'codemirror-show-hint', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/hint/show-hint' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror' ), '5.2.0' );
200
-
201
- // All the CodeMirror styles
202
- wp_enqueue_style( 'codemirror', plugin_dir_url(__FILE__) . 'lib/codemirror/lib/codemirror.css', array(), '5.2.0' );
203
- wp_enqueue_style( 'codemirror-theme-neat', plugin_dir_url(__FILE__) . 'lib/codemirror/theme/neat.css', array(), '5.2.0' );
204
- wp_enqueue_style( 'codemirror-lint-css', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/lint/lint.css', array(), '5.2.0' );
205
- wp_enqueue_style( 'codemirror-show-hint', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/hint/show-hint.css', array( ), '5.2.0' );
206
-
207
- // Enqueue the scripts for theme CSS processing
208
- wp_enqueue_script( 'siteorigin-css-parser-lib', plugin_dir_url(__FILE__) . 'js/css' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), SOCSS_VERSION );
209
-
210
- // There are conflicts between CSS linting and the built in WordPress color picker, so use something else
211
- wp_enqueue_style('siteorigin-custom-css-minicolors', plugin_dir_url(__FILE__) . 'lib/minicolors/jquery.minicolors.css', array(), '2.1.7' );
212
- wp_enqueue_script('siteorigin-custom-css-minicolors', plugin_dir_url(__FILE__) . 'lib/minicolors/jquery.minicolors' . SOCSS_JS_SUFFIX . '.js', array('jquery'), '2.1.7' );
213
-
214
- // We need Font Awesome
215
- wp_enqueue_style( 'siteorigin-custom-css-font-awesome', plugin_dir_url(__FILE__) . 'lib/fontawesome/css/font-awesome.min.css', array( ), SOCSS_VERSION );
216
-
217
- // URI parsing for preview navigation
218
- wp_enqueue_script( 'siteorigin-uri', plugin_dir_url(__FILE__) . 'js/URI' . SOCSS_JS_SUFFIX . '.js', array( ), SOCSS_VERSION, true );
219
-
220
- // All the custom SiteOrigin CSS stuff
221
- wp_enqueue_script( 'siteorigin-custom-css', plugin_dir_url(__FILE__) . 'js/editor' . SOCSS_JS_SUFFIX . '.js', array( 'jquery', 'underscore', 'backbone', 'siteorigin-css-parser-lib', 'codemirror' ), SOCSS_VERSION, true );
222
- wp_enqueue_style( 'siteorigin-custom-css', plugin_dir_url(__FILE__) . 'css/admin.css', array( ), SOCSS_VERSION );
223
-
224
- wp_localize_script( 'siteorigin-custom-css', 'socssOptions', array(
225
- 'themeCSS' => SiteOrigin_CSS::single()->get_theme_css(),
226
- // Pretty confusing, but it seems we should be using `home_url` and NOT `site_url`
227
- // as described here => https://wordpress.stackexchange.com/a/50605
228
- 'homeURL' => add_query_arg( 'so_css_preview', '1', home_url() ),
229
- 'snippets' => $this->get_snippets(),
230
-
231
- 'propertyControllers' => apply_filters( 'siteorigin_css_property_controllers', $this->get_property_controllers() ),
232
-
233
- 'loc' => array(
234
- 'unchanged' => __('Unchanged', 'so-css'),
235
- 'select' => __('Select', 'so-css'),
236
- 'select_image' => __('Select Image', 'so-css'),
237
- 'leave' => __('Are you sure you want to leave without saving?', 'so-css'),
238
- )
239
- ) );
240
-
241
- // This is for the templates required by the CSS editor
242
- add_action( 'admin_footer', array($this, 'action_admin_footer') );
243
- }
244
-
245
- /**
246
- * @param $page
247
- */
248
- function dequeue_admin_scripts( $page ) {
249
- if( $page != 'appearance_page_so_custom_css' ) return;
250
-
251
- // Dequeue the core WordPress color picker on the custom CSS page.
252
- // This script causes conflicts and other plugins seem to be enqueueing it on the SO CSS admin page.
253
- wp_dequeue_script('wp-color-picker');
254
- wp_dequeue_style('wp-color-picker');
255
- }
256
-
257
- /**
258
- * Get all the available property controllers
259
- */
260
- function get_property_controllers() {
261
- return include plugin_dir_path( __FILE__ ) . 'inc/controller-config.php';
262
- }
263
-
264
- /**
265
- * Display the templates for the CSS Editor
266
- */
267
- function action_admin_footer(){
268
- include plugin_dir_path( __FILE__ ) . 'tpl/js-templates.php';
269
- }
270
-
271
- function plugin_action_links( $links ){
272
- if( isset($links['edit']) ) unset( $links['edit'] );
273
- $links['css_editor'] = '<a href="' . admin_url('themes.php?page=so_custom_css') . '">'.__('CSS Editor', 'so-css').'</a>';
274
- $links['support'] = '<a href="https://siteorigin.com/thread/" target="_blank">'.__('Support', 'so-css').'</a>';
275
- return $links;
276
- }
277
-
278
- function display_admin_page(){
279
- $theme = basename( get_template_directory() );
280
-
281
- $custom_css = get_option( 'siteorigin_custom_css[' . $theme . ']', '' );
282
- $custom_css_revisions = get_option('siteorigin_custom_css_revisions[' . $theme . ']');
283
-
284
- if( !empty( $_GET['theme'] ) && $_GET['theme'] == $theme && !empty( $_GET['time'] ) && !empty( $custom_css_revisions[$_GET['time']] ) ) {
285
- $custom_css = $custom_css_revisions[$_GET['time']];
286
- $revision = true;
287
- }
288
-
289
- include plugin_dir_path( __FILE__ ) . 'tpl/page.php';
290
- }
291
-
292
-
293
- function display_teaser(){
294
- return apply_filters( 'siteorigin_premium_upgrade_teaser', true ) &&
295
- ! defined( 'SITEORIGIN_PREMIUM_VERSION' );
296
- }
297
-
298
- /**
299
- *
300
- */
301
- function admin_action_hide_getting_started(){
302
- if( !isset($_GET['_wpnonce']) || !wp_verify_nonce( $_GET['_wpnonce'], 'hide' ) ) return;
303
-
304
- $user = wp_get_current_user();
305
- if( !empty( $user ) ) {
306
- update_user_meta( $user->ID, 'socss_hide_gs', true );
307
- }
308
- }
309
-
310
- /**
311
- * Add one or more paths to the registered snippet paths
312
- *
313
- * @param string|array $path
314
- */
315
- function register_snippet_path( $path ){
316
- $this->snippet_paths = array_merge( $this->snippet_paths, (array) $path );
317
- }
318
-
319
- /**
320
- * Get all the available snippets
321
- *
322
- * @return array|bool
323
- */
324
- function get_snippets(){
325
- // Get the snippet paths
326
- $snippet_paths = apply_filters( 'siteorigin_css_snippet_paths', $this->snippet_paths );
327
- if( empty($snippet_paths) ) return array();
328
-
329
- static $snippets = array();
330
- if( !empty($snippets) ) return $snippets;
331
-
332
- if( !WP_Filesystem() ) return false;
333
- global $wp_filesystem;
334
- foreach( $snippet_paths as $path ) {
335
- foreach( glob($path . '/*.css') as $css_file ) {
336
- $data = get_file_data( $css_file, array(
337
- 'Name' => 'Name',
338
- 'Description' => 'Description',
339
- ) );
340
-
341
- // Get the CSS and strip out the first header
342
- $css = $wp_filesystem->get_contents( $css_file );
343
- $css = preg_replace('!/\*.*?\*/!s', '', $css, 1);
344
-
345
- $snippets[] = wp_parse_args( $data, array(
346
- 'css' => str_replace( "\t", ' ', trim($css) ),
347
- ) );
348
- }
349
- }
350
-
351
- usort($snippets, array( $this, 'sort_snippet_callback' ) );
352
- return $snippets;
353
- }
354
-
355
- /**
356
- * Sort snippets by name.
357
- *
358
- * @param $a
359
- * @param $b
360
- *
361
- * @return int
362
- */
363
- static function sort_snippet_callback( $a, $b ){
364
- return $a['Name'] > $b['Name'] ? 1 : -1;
365
- }
366
-
367
- /**
368
- * A very simple CSS sanitization function.
369
- *
370
- * @param $css
371
- *
372
- * @return string
373
- */
374
- static function sanitize_css( $css ){
375
- return trim( strip_tags( $css ) );
376
- }
377
-
378
- /**
379
- * Get all the available theme CSS
380
- */
381
- function get_theme_css(){
382
- $css = '';
383
- if( file_exists( get_template_directory() . '/style.css' ) ) {
384
- $css .= file_get_contents( get_template_directory() . '/style.css' );
385
- }
386
-
387
- if( is_child_theme() ) {
388
- $css .= file_get_contents( get_stylesheet_directory() . '/style.css' );
389
- }
390
-
391
- // Remove all CSS comments
392
- $regex = array(
393
- "`^([\t\s]+)`ism"=>'',
394
- "`^\/\*(.+?)\*\/`ism"=>"",
395
- "`([\n\A;]+)\/\*(.+?)\*\/`ism"=>"$1",
396
- "`([\n\A;\s]+)//(.+?)[\n\r]`ism"=>"$1\n",
397
- "`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism"=>"\n"
398
- );
399
- $css = preg_replace( array_keys($regex), $regex, $css );
400
- $css = preg_replace('/\s+/', ' ', $css);
401
-
402
- return $css;
403
- }
404
-
405
- /**
406
- * Get the editor description
407
- *
408
- * @return string
409
- */
410
- static function editor_description(){
411
- $theme = wp_get_theme();
412
- return sprintf( __( 'Changes apply to %s and its child themes', 'so-css' ), $theme->get('Name') );
413
- }
414
-
415
- function enqueue_inspector_scripts(){
416
- if( !current_user_can('edit_theme_options') ) return;
417
-
418
- wp_enqueue_style( 'dashicons' );
419
-
420
- wp_enqueue_script( 'siteorigin-css-parser-lib', plugin_dir_url(__FILE__) . 'js/css' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), SOCSS_VERSION );
421
-
422
- wp_enqueue_script('siteorigin-css-sizes', plugin_dir_url(__FILE__) . 'js/jquery.sizes' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), '0.33' );
423
- wp_enqueue_script('siteorigin-css-specificity', plugin_dir_url(__FILE__) . 'js/specificity' . SOCSS_JS_SUFFIX . '.js', array( ) );
424
- wp_enqueue_script('siteorigin-css-inspector', plugin_dir_url(__FILE__) . 'js/inspector' . SOCSS_JS_SUFFIX . '.js', array( 'jquery', 'underscore', 'backbone' ), SOCSS_VERSION, true );
425
- wp_enqueue_style('siteorigin-css-inspector', plugin_dir_url(__FILE__) . 'css/inspector.css', array( ), SOCSS_VERSION );
426
-
427
- wp_localize_script('siteorigin-css-inspector', 'socssOptions', array(
428
-
429
- ) );
430
- }
431
-
432
- function inspector_templates(){
433
- if( !current_user_can('edit_theme_options') ) return;
434
-
435
- include plugin_dir_path( __FILE__ ) . 'tpl/inspector-templates.php';
436
- }
437
-
438
- /**
439
- * Change the stylesheets to all be inline
440
- */
441
- function inline_inspector_scripts(){
442
- if( !current_user_can('edit_theme_options') ) return;
443
-
444
- $regex = array(
445
- "`^([\t\s]+)`ism"=>'',
446
- "`^\/\*(.+?)\*\/`ism"=>"",
447
- "`([\n\A;]+)\/\*(.+?)\*\/`ism"=>"$1",
448
- "`([\n\A;\s]+)//(.+?)[\n\r]`ism"=>"$1\n",
449
- "`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism"=>"\n"
450
- );
451
-
452
- global $wp_styles;
453
- if( empty($wp_styles->queue) ) return;
454
-
455
- // Make each of the scripts inline
456
- foreach( $wp_styles->queue as $handle ) {
457
- if( $handle === 'siteorigin-css-inspector' || $handle === 'dashicons' ) continue;
458
- $style = $wp_styles->registered[$handle];
459
- if( empty($style->src) || substr($style->src, 0, 4) !== 'http' ) continue;
460
- $response = wp_remote_get( $style->src );
461
- if( is_wp_error($response) || $response['response']['code'] !== 200 || empty($response['body']) ) continue;
462
-
463
- $css = $response['body'];
464
- $css = preg_replace( array_keys($regex), $regex, $css );
465
-
466
- ?>
467
- <script type="text/css" class="socss-theme-styles" id="socss-inlined-style-<?php echo sanitize_html_class( $handle ) ?>">
468
- <?php echo strip_tags( $css ) ?>
469
- </script>
470
- <?php
471
- }
472
- }
473
-
474
- function disable_ngg_resource_manager() {
475
- if( !current_user_can('edit_theme_options') ) return;
476
-
477
- //The NextGen Gallery plugin does some weird interfering with the output buffer.
478
- define('NGG_DISABLE_RESOURCE_MANAGER', true);
479
- }
480
-
481
- private function get_latest_revision_timestamp() {
482
- $revisions = get_option( 'siteorigin_custom_css_revisions[' . $this->theme . ']' );
483
- krsort( $revisions );
484
- $revision_times = array_keys( $revisions );
485
-
486
- return $revision_times[0];
487
- }
488
- }
489
-
490
- // Initialize the single
491
- SiteOrigin_CSS::single();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: SiteOrigin CSS
4
+ Description: An advanced CSS editor from SiteOrigin.
5
+ Version: 1.2.0
6
+ Author: SiteOrigin
7
+ Author URI: https://siteorigin.com
8
+ Plugin URI: https://siteorigin.com/css/
9
+ License: GPL3
10
+ License URI: https://www.gnu.org/licenses/gpl-3.0.txt
11
+ Text Domain: so-css
12
+ */
13
+
14
+ // Handle the legacy CSS editor that came with SiteOrigin themes
15
+ include plugin_dir_path( __FILE__ ) . 'inc/legacy.php';
16
+
17
+ define( 'SOCSS_VERSION', '1.2.0' );
18
+ define( 'SOCSS_JS_SUFFIX', '.min' );
19
+
20
+ /**
21
+ * Class SiteOrigin_CSS The main class for the SiteOrigin CSS Editor
22
+ */
23
+ class SiteOrigin_CSS {
24
+ private $theme;
25
+ private $snippet_paths;
26
+
27
+ function __construct() {
28
+ $this->theme = basename( get_template_directory() );
29
+ $this->snippet_paths = array();
30
+
31
+ // Main header actions
32
+ add_action( 'plugins_loaded', array( $this, 'set_plugin_textdomain' ) );
33
+ add_action( 'wp_head', array( $this, 'action_wp_head' ), 20 );
34
+
35
+ // All the admin actions
36
+ add_action( 'admin_menu', array( $this, 'action_admin_menu' ) );
37
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ), 20 );
38
+ add_action( 'admin_enqueue_scripts', array( $this, 'dequeue_admin_scripts' ), 19 );
39
+ add_action( 'load-appearance_page_so_custom_css', array( $this, 'add_help_tab' ) );
40
+
41
+ // Add the action links.
42
+ add_action( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );
43
+
44
+ // The request to hide the getting started video
45
+ add_action( 'wp_ajax_socss_hide_getting_started', array( $this, 'admin_action_hide_getting_started' ) );
46
+
47
+ add_action( 'wp_ajax_socss_get_post_css', array( $this, 'admin_action_get_post_css' ) );
48
+ add_action( 'wp_ajax_socss_get_revisions_list', array( $this, 'admin_action_get_revisions_list' ) );
49
+
50
+ if ( ! is_admin() ) {
51
+ if( isset( $_GET['so_css_preview'] ) ) {
52
+
53
+ add_action( 'plugins_loaded', array($this, 'disable_ngg_resource_manager') );
54
+ add_filter( 'show_admin_bar', '__return_false' );
55
+ add_filter( 'wp_enqueue_scripts', array($this, 'enqueue_inspector_scripts') );
56
+ add_filter( 'wp_footer', array($this, 'inspector_templates') );
57
+
58
+ // We'll be grabbing all the enqueued scripts and outputting them
59
+ add_action( 'wp_enqueue_scripts', array($this, 'inline_inspector_scripts'), 100 );
60
+ }
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Get a singleton of the SiteOrigin CSS.
66
+ *
67
+ * @return SiteOrigin_CSS
68
+ */
69
+ static function single() {
70
+ static $single;
71
+
72
+ if ( empty( $single ) ) {
73
+ $single = new SiteOrigin_CSS();
74
+ }
75
+
76
+ return $single;
77
+ }
78
+
79
+ /**
80
+ * Retrieve the current custom CSS for a given theme and post id combination.
81
+ *
82
+ * @param $theme string The name of the theme for which to retrieve custom CSS.
83
+ * @param $post_id int The ID of the specific post for which to retrieve custom CSS.
84
+ *
85
+ * @return string The custom CSS for the theme and post ID combination.
86
+ */
87
+ function get_custom_css( $theme, $post_id = null ) {
88
+ $css_key = 'siteorigin_custom_css[' . $theme . ']';
89
+ if ( empty( $post_id ) ) {
90
+ return get_option( $css_key, '' );
91
+ }
92
+
93
+ return get_post_meta( $post_id, $css_key, true );
94
+ }
95
+
96
+ /**
97
+ * Save custom CSS for a given theme and post id combination.
98
+ *
99
+ * @param $custom_css string The custom CSS to save.
100
+ * @param $theme string The name of the theme for which to save custom CSS.
101
+ * @param $post_id int The ID of the specific post for which to save custom CSS.
102
+ *
103
+ * @return bool Whether or not saving the custom CSS was successful.
104
+ */
105
+ function save_custom_css( $custom_css, $theme, $post_id = null ) {
106
+ $css_key = 'siteorigin_custom_css[' . $theme . ']';
107
+ if ( empty( $post_id ) ) {
108
+ $current = get_option( $css_key );
109
+ if ( $current === false ) {
110
+ return add_option( $css_key, $custom_css, '', 'no' );
111
+ } else {
112
+ return update_option( $css_key, $custom_css );
113
+ }
114
+ }
115
+
116
+ if ( metadata_exists( 'post', $post_id, $css_key ) ) {
117
+ return update_post_meta( $post_id, $css_key, $custom_css );
118
+ }
119
+
120
+ return add_post_meta( $post_id, $css_key, $custom_css );
121
+ }
122
+
123
+ /**
124
+ * Save custom CSS for a given theme and post id combination to a file in the uploads directory to allow for caching.
125
+ *
126
+ * @param $custom_css
127
+ * @param $theme
128
+ * @param null $post_id
129
+ */
130
+ function save_custom_css_file( $custom_css, $theme, $post_id = null ) {
131
+ if ( WP_Filesystem() ) {
132
+ global $wp_filesystem;
133
+ $upload_dir = wp_upload_dir();
134
+ $upload_dir_path = $upload_dir['basedir'] . '/so-css/';
135
+
136
+ if ( ! $wp_filesystem->is_dir( $upload_dir_path ) ) {
137
+ $wp_filesystem->mkdir( $upload_dir_path );
138
+ }
139
+
140
+ $css_file_name = 'so-css-' . $theme . ( ! empty( $post_id ) ? '_' . $post_id : '' );
141
+ $css_file_path = $upload_dir_path . $css_file_name . '.css';
142
+
143
+ if ( file_exists( $css_file_path ) ) {
144
+ $wp_filesystem->delete( $css_file_path );
145
+ }
146
+
147
+ $wp_filesystem->put_contents(
148
+ $css_file_path,
149
+ $custom_css
150
+ );
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Retrieve the previous revisions of custom CSS for a given theme and post id combination.
156
+ *
157
+ * @param $theme string The name of the theme for which to retrieve custom CSS revisions.
158
+ * @param $post_id int The ID of the specific post for which to retrieve custom CSS revisions.
159
+ *
160
+ * @return array The custom CSS revisions for the theme and post ID combination.
161
+ */
162
+ function get_custom_css_revisions( $theme, $post_id = null ) {
163
+ $css_key = 'siteorigin_custom_css_revisions[' . $theme . ']';
164
+ if ( empty( $post_id ) ) {
165
+ return get_option( $css_key, '' );
166
+ }
167
+
168
+ return get_post_meta( $post_id, $css_key, true );
169
+ }
170
+
171
+ /**
172
+ * Adds a custom CSS revision for a given theme and post id combination.
173
+ *
174
+ * @param $custom_css string The custom CSS to add as a revision.
175
+ * @param $theme string The name of the theme for which to save custom CSS.
176
+ * @param $post_id int The ID of the specific post for which to save custom CSS.
177
+ *
178
+ * @return bool Whether or not adding the custom CSS revision was successful.
179
+ */
180
+ function add_custom_css_revision( $custom_css, $theme, $post_id = null ) {
181
+ $revisions = $this->get_custom_css_revisions( $this->theme, $post_id );
182
+
183
+ $css_key = 'siteorigin_custom_css_revisions[' . $theme . ']';
184
+
185
+ if ( empty( $revisions ) ) {
186
+ $revisions = array();
187
+ if ( empty( $post_id ) ) {
188
+ add_option( $css_key, $revisions, '', 'no' );
189
+ } else {
190
+ add_post_meta( $post_id, $css_key, $revisions );
191
+ }
192
+ }
193
+ $revisions[ time() ] = $custom_css;
194
+
195
+ // Sort the revisions and cut off any old ones.
196
+ krsort( $revisions );
197
+ $revisions = array_slice( $revisions, 0, 15, true );
198
+
199
+ if ( empty( $post_id ) ) {
200
+ return update_option( $css_key, $revisions );
201
+ }
202
+
203
+ return update_post_meta( $post_id, $css_key, $revisions );
204
+ }
205
+
206
+ /**
207
+ * Display the custom CSS in the header.
208
+ */
209
+ function action_wp_head() {
210
+
211
+ $this->enqueue_custom_css( $this->theme );
212
+
213
+ if ( is_singular() ) {
214
+ $this->enqueue_custom_css( $this->theme, get_the_ID() );
215
+ }
216
+
217
+ }
218
+
219
+ /**
220
+ * Enqueue the custom CSS for the given theme and post id combination.
221
+ *
222
+ * @param $theme string The name of the theme for which to enqueue custom CSS.
223
+ * @param $post_id int The ID of the specific post for which to enqueue custom CSS.
224
+ *
225
+ */
226
+ function enqueue_custom_css( $theme, $post_id = null ) {
227
+
228
+ $upload_dir = wp_upload_dir();
229
+ $upload_dir_path = $upload_dir['basedir'] . '/so-css/';
230
+
231
+ $css_id = $theme . ( ! empty( $post_id ) ? '_' . $post_id : '' );
232
+ $css_file_name = 'so-css-' . $css_id;
233
+ $css_file_path = $upload_dir_path . $css_file_name . '.css';
234
+
235
+ if ( empty( $_GET['so_css_preview'] ) && ! is_admin() && file_exists( $css_file_path ) ) {
236
+ wp_enqueue_style(
237
+ 'so-css-' . $css_id,
238
+ set_url_scheme( $upload_dir['baseurl'] . '/so-css/' . $css_file_name . '.css' ),
239
+ array(),
240
+ $this->get_latest_revision_timestamp()
241
+ );
242
+ } else {
243
+ $custom_css = $this->get_custom_css( $theme, $post_id );
244
+ // We just need to enqueue a dummy style
245
+ if ( ! empty( $custom_css ) ) {
246
+ echo "<style id='" . sanitize_html_class( $css_id ) . "-custom-css' class='siteorigin-custom-css' type='text/css'>\n";
247
+ echo self::sanitize_css( $custom_css ) . "\n";
248
+ echo "</style>\n";
249
+ }
250
+ }
251
+ }
252
+
253
+ function set_plugin_textdomain() {
254
+ load_plugin_textdomain( 'so-css', false, plugin_dir_path( __FILE__ ) . 'lang/' );
255
+ }
256
+
257
+ /**
258
+ * Action to run on the admin action.
259
+ */
260
+ function action_admin_menu() {
261
+ add_theme_page( __( 'Custom CSS', 'so-css' ), __( 'Custom CSS', 'so-css' ), 'edit_theme_options', 'so_custom_css', array(
262
+ $this,
263
+ 'display_admin_page'
264
+ ) );
265
+
266
+ if ( current_user_can( 'edit_theme_options' ) && isset( $_POST['siteorigin_custom_css_save'] ) ) {
267
+ check_admin_referer( 'custom_css', '_sononce' );
268
+
269
+ // Sanitize CSS input. Should keep most tags, apart from script and style tags.
270
+ $custom_css = self::sanitize_css( filter_input( INPUT_POST, 'custom_css' ) );
271
+ $selected_post_id = filter_input( INPUT_POST, 'selected_post_id', FILTER_VALIDATE_INT );
272
+
273
+ $current = $this->get_custom_css( $this->theme, $selected_post_id );
274
+ $this->save_custom_css( $custom_css, $this->theme, $selected_post_id );
275
+
276
+ // If this has changed, then add a revision.
277
+ if ( $current != $custom_css ) {
278
+ $this->add_custom_css_revision( $custom_css, $this->theme, $selected_post_id );
279
+
280
+ $this->save_custom_css_file( $custom_css, $this->theme, $selected_post_id );
281
+ }
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Display the help tab
287
+ */
288
+ function add_help_tab() {
289
+ $screen = get_current_screen();
290
+ $screen->add_help_tab( array(
291
+ 'id' => 'custom-css',
292
+ 'title' => __( 'Custom CSS', 'so-css' ),
293
+ 'content' => '<p>'
294
+ . sprintf( __( "SiteOrigin CSS adds any custom CSS you enter here into your site's header. ", 'so-css' ) )
295
+ . __( "These changes will persist across updates so it's best to make all your changes here. ", 'so-css' )
296
+ . '</p>'
297
+ ) );
298
+ }
299
+
300
+ function enqueue_admin_scripts( $page ) {
301
+ if ( $page != 'appearance_page_so_custom_css' ) {
302
+ return;
303
+ }
304
+
305
+ // Core WordPress stuff that we use
306
+ wp_enqueue_media();
307
+
308
+ // Enqueue the codemirror scripts. Call Underscore and Backbone dependencies so they're enqueued first to prevent conflicts.
309
+ wp_enqueue_script( 'codemirror', plugin_dir_url( __FILE__ ) . 'lib/codemirror/lib/codemirror' . SOCSS_JS_SUFFIX . '.js', array(
310
+ 'underscore',
311
+ 'backbone'
312
+ ), '5.2.0' );
313
+ wp_enqueue_script( 'codemirror-mode-css', plugin_dir_url( __FILE__ ) . 'lib/codemirror/mode/css/css' . SOCSS_JS_SUFFIX . '.js', array(), '5.2.0' );
314
+
315
+ // Add in all the linting libs
316
+ wp_enqueue_script( 'codemirror-lint', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/lint/lint' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror' ), '5.2.0' );
317
+ wp_enqueue_script( 'codemirror-lint-css', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/lint/css-lint' . SOCSS_JS_SUFFIX . '.js', array(
318
+ 'codemirror',
319
+ 'codemirror-lint-css-lib'
320
+ ), '5.2.0' );
321
+ wp_enqueue_script( 'codemirror-lint-css-lib', plugin_dir_url( __FILE__ ) . 'js/csslint' . SOCSS_JS_SUFFIX . '.js', array(), '0.10.0' );
322
+
323
+ // The CodeMirror autocomplete library
324
+ wp_enqueue_script( 'codemirror-show-hint', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/hint/show-hint' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror' ), '5.2.0' );
325
+
326
+ // CodeMirror search and dialog addons
327
+ wp_enqueue_script( 'codemirror-dialog', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/dialog/dialog' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror' ), '5.2.0' );
328
+ wp_enqueue_style( 'codemirror-dialog', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/dialog/dialog' . SOCSS_JS_SUFFIX . '.css', '5.2.0' );
329
+
330
+ wp_enqueue_script( 'codemirror-search', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/search/search' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror' ), '5.37.0' );
331
+ wp_enqueue_script( 'codemirror-search-searchcursor', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/search/searchcursor' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror', 'codemirror-search' ), '5.37.0' );
332
+ wp_enqueue_script( 'codemirror-search-match-cursor', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/search/match-highlighter' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror', 'codemirror-search' ), '5.37.0' );
333
+ wp_enqueue_script( 'codemirror-search-matchesonscrollbar', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/search/matchesonscrollbar' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror', 'codemirror-search' ), '5.37.0' );
334
+ wp_enqueue_style( 'codemirror-search-matchesonscrollbar', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/search/matchesonscrollbar' . SOCSS_JS_SUFFIX . '.css', array(), '5.37.0' );
335
+ wp_enqueue_script( 'codemirror-scroll-annotatescrollbar', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/scroll/annotatescrollbar' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror', 'codemirror-search', 'codemirror-search-matchesonscrollbar' ), '5.37.0' );
336
+ wp_enqueue_script( 'codemirror-jump-to-line', plugin_dir_url(__FILE__) . 'lib/codemirror/addon/search/jump-to-line' . SOCSS_JS_SUFFIX . '.js', array( 'codemirror', 'codemirror-search' ), '5.37.0' );
337
+
338
+ // All the CodeMirror styles
339
+ wp_enqueue_style( 'codemirror', plugin_dir_url( __FILE__ ) . 'lib/codemirror/lib/codemirror.css', array(), '5.2.0' );
340
+ wp_enqueue_style( 'codemirror-theme-neat', plugin_dir_url( __FILE__ ) . 'lib/codemirror/theme/neat.css', array(), '5.2.0' );
341
+ wp_enqueue_style( 'codemirror-lint-css', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/lint/lint.css', array(), '5.2.0' );
342
+ wp_enqueue_style( 'codemirror-show-hint', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/hint/show-hint.css', array(), '5.2.0' );
343
+
344
+ // Enqueue the scripts for theme CSS processing
345
+ wp_enqueue_script( 'siteorigin-css-parser-lib', plugin_dir_url( __FILE__ ) . 'js/css' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), SOCSS_VERSION );
346
+
347
+ // There are conflicts between CSS linting and the built in WordPress color picker, so use something else
348
+ wp_enqueue_style( 'siteorigin-custom-css-minicolors', plugin_dir_url( __FILE__ ) . 'lib/minicolors/jquery.minicolors.css', array(), '2.1.7' );
349
+ wp_enqueue_script( 'siteorigin-custom-css-minicolors', plugin_dir_url( __FILE__ ) . 'lib/minicolors/jquery.minicolors' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), '2.1.7' );
350
+
351
+ // We need Font Awesome
352
+ wp_enqueue_style( 'siteorigin-custom-css-font-awesome', plugin_dir_url( __FILE__ ) . 'lib/fontawesome/css/font-awesome.min.css', array(), SOCSS_VERSION );
353
+
354
+ // URI parsing for preview navigation
355
+ wp_enqueue_script( 'siteorigin-uri', plugin_dir_url( __FILE__ ) . 'js/URI' . SOCSS_JS_SUFFIX . '.js', array(), SOCSS_VERSION, true );
356
+
357
+ // All the custom SiteOrigin CSS stuff
358
+ wp_enqueue_script( 'siteorigin-custom-css', plugin_dir_url(__FILE__) . 'js/editor' . SOCSS_JS_SUFFIX . '.js', array( 'jquery', 'underscore', 'backbone', 'siteorigin-css-parser-lib', 'codemirror' ), SOCSS_VERSION, true );
359
+ wp_enqueue_style( 'siteorigin-custom-css', plugin_dir_url(__FILE__) . 'css/admin.css', array( ), SOCSS_VERSION );
360
+
361
+
362
+ // Pretty confusing, but it seems we should be using `home_url` and NOT `site_url`
363
+ // as described here => https://wordpress.stackexchange.com/a/50605
364
+ $init_url = home_url();
365
+
366
+ if ( ! empty( $socss_post_id ) && is_int( $socss_post_id ) ) {
367
+ $init_url = set_url_scheme( get_permalink( $socss_post_id ) );
368
+ }
369
+
370
+ $open_visual_editor = ! empty( $_REQUEST['open_visual_editor'] );
371
+
372
+ $home_url = add_query_arg( 'so_css_preview', '1', $init_url );
373
+
374
+ $theme = wp_get_theme();
375
+
376
+ wp_localize_script( 'siteorigin-custom-css', 'socssOptions', array(
377
+ 'themeCSS' => SiteOrigin_CSS::single()->get_theme_css(),
378
+ 'themeName' => $theme->get( 'Name' ),
379
+ 'editorDescriptions' => array(
380
+ 'global' => __( 'Changes apply to <%= themeName %> and its child themes', 'so-css' ),
381
+ 'post' => __( 'Changes apply to the post <%= postTitle %> when the current theme is <%= themeName %> or its child themes', 'so-css' ),
382
+ ),
383
+ 'homeURL' => $home_url,
384
+ 'postCssUrlRoot' => wp_nonce_url( admin_url('admin-ajax.php?action=socss_get_post_css'), 'get_post_css' ),
385
+ 'getRevisionsListAjaxUrl' => wp_nonce_url( admin_url('admin-ajax.php?action=socss_get_revisions_list'), 'get_revisions_list' ),
386
+ 'openVisualEditor' => $open_visual_editor,
387
+
388
+ 'propertyControllers' => apply_filters( 'siteorigin_css_property_controllers', $this->get_property_controllers() ),
389
+
390
+ 'loc' => array(
391
+ 'unchanged' => __( 'Unchanged', 'so-css' ),
392
+ 'select' => __( 'Select', 'so-css' ),
393
+ 'select_image' => __( 'Select Image', 'so-css' ),
394
+ 'leave' => __( 'Are you sure you want to leave without saving?', 'so-css' ),
395
+ )
396
+ ) );
397
+
398
+ // This is for the templates required by the CSS editor. Ideally this would be out in the footer, but we need
399
+ // it earlier for dependent scripts.
400
+ include plugin_dir_path( __FILE__ ) . 'tpl/js-templates.php';
401
+ }
402
+
403
+ /**
404
+ * @param $page
405
+ */
406
+ function dequeue_admin_scripts( $page ) {
407
+ if ( $page != 'appearance_page_so_custom_css' ) {
408
+ return;
409
+ }
410
+
411
+ // Dequeue the core WordPress color picker on the custom CSS page.
412
+ // This script causes conflicts and other plugins seem to be enqueueing it on the SO CSS admin page.
413
+ wp_dequeue_script( 'wp-color-picker' );
414
+ wp_dequeue_style( 'wp-color-picker' );
415
+ }
416
+
417
+ /**
418
+ * Get all the available property controllers
419
+ */
420
+ function get_property_controllers() {
421
+ return include plugin_dir_path( __FILE__ ) . 'inc/controller-config.php';
422
+ }
423
+
424
+ function plugin_action_links( $links ) {
425
+ if ( isset( $links['edit'] ) ) {
426
+ unset( $links['edit'] );
427
+ }
428
+ $links['css_editor'] = '<a href="' . admin_url( 'themes.php?page=so_custom_css' ) . '">' . __( 'CSS Editor', 'so-css' ) . '</a>';
429
+ $links['support'] = '<a href="https://siteorigin.com/thread/" target="_blank">' . __( 'Support', 'so-css' ) . '</a>';
430
+
431
+ return $links;
432
+ }
433
+
434
+ function display_admin_page() {
435
+
436
+ $socss_post_id = filter_input( INPUT_GET, 'socss_post_id', FILTER_VALIDATE_INT );
437
+ $theme = filter_input( INPUT_GET, 'theme' );
438
+ $time = filter_input( INPUT_GET, 'time', FILTER_VALIDATE_INT );
439
+
440
+ $custom_css = $this->get_custom_css( $this->theme, $socss_post_id );
441
+ $custom_css_revisions = $this->get_custom_css_revisions( $this->theme, $socss_post_id );
442
+ $current_revision = 0;
443
+
444
+ if ( ! empty( $theme ) && $theme == $this->theme && ! empty( $time ) && ! empty( $custom_css_revisions[ $time ] ) ) {
445
+ $current_revision = $time;
446
+ $custom_css = $custom_css_revisions[ $time ];
447
+ }
448
+
449
+ if ( ! empty( $custom_css_revisions ) ) {
450
+ krsort( $custom_css_revisions );
451
+ }
452
+
453
+ $theme = basename( get_template_directory() );
454
+
455
+ include plugin_dir_path( __FILE__ ) . 'tpl/page.php';
456
+ }
457
+
458
+
459
+ function display_teaser() {
460
+ return apply_filters( 'siteorigin_premium_upgrade_teaser', true ) &&
461
+ ! defined( 'SITEORIGIN_PREMIUM_VERSION' );
462
+ }
463
+
464
+ /**
465
+ * Generates the url to edit the custom CSS for a post.
466
+ */
467
+ function get_edit_css_link( $post ) {
468
+ $url = admin_url( 'themes.php?page=so_custom_css' );
469
+ if ( ! is_int( $post ) ) {
470
+ $post = get_post( $post );
471
+ $post = $post->ID;
472
+ }
473
+
474
+ return empty( $post ) ? $url : add_query_arg( array(
475
+ 'socss_post_id' => urlencode( $post ),
476
+ 'open_visual_editor' => 1,
477
+ ), $url );
478
+ }
479
+ /**
480
+ *
481
+ */
482
+ function admin_action_hide_getting_started() {
483
+ if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'hide' ) ) {
484
+ return;
485
+ }
486
+
487
+ $user = wp_get_current_user();
488
+ if ( ! empty( $user ) ) {
489
+ update_user_meta( $user->ID, 'socss_hide_gs', true );
490
+ }
491
+ }
492
+
493
+ /**
494
+ * Retrieves the post specific CSS for the supplied postId.
495
+ */
496
+ function admin_action_get_post_css() {
497
+ if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'get_post_css' ) ) {
498
+ wp_die(
499
+ __( 'The supplied nonce is invalid.', 'siteorigin-panels' ),
500
+ __( 'Invalid nonce.', 'siteorigin-panels' ),
501
+ 403
502
+ );
503
+ }
504
+
505
+ $post_id = filter_input( INPUT_GET, 'postId', FILTER_VALIDATE_INT );
506
+
507
+ $current = $this->get_custom_css( $this->theme, $post_id );
508
+
509
+ $url = empty( $post_id ) ? home_url() : set_url_scheme( get_permalink( $post_id ) );
510
+
511
+ wp_send_json( array( 'css' => empty( $current ) ? '' : $current, 'postUrl' => $url ) );
512
+ }
513
+
514
+ /**
515
+ * Retrieves the past revisions of post specific CSS for the supplied postId.
516
+ */
517
+ function admin_action_get_revisions_list() {
518
+ if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'get_revisions_list' ) ) {
519
+ wp_die(
520
+ __( 'The supplied nonce is invalid.', 'siteorigin-panels' ),
521
+ __( 'Invalid nonce.', 'siteorigin-panels' ),
522
+ 403
523
+ );
524
+ }
525
+
526
+ $post_id = filter_input( INPUT_GET, 'postId', FILTER_VALIDATE_INT );
527
+
528
+ $this->custom_css_revisions_list( $this->theme, $post_id );
529
+
530
+ wp_die();
531
+ }
532
+
533
+ function custom_css_revisions_list( $theme, $post_id = null, $current_revision = null ) {
534
+
535
+ $revisions = $this->get_custom_css_revisions( $theme, $post_id );
536
+
537
+ if ( is_array( $revisions ) ) {
538
+ $i = 0;
539
+ foreach ( $revisions as $time => $css ) {
540
+ $is_current = ( empty( $current_revision ) && $i == 0 ) || ( ! empty( $current_revision ) && $time == $current_revision );
541
+ $query_args = array( 'theme' => $theme, 'time' => $time, 'open_visual_editor' => false );
542
+ if ( ! empty( $post_id ) ) {
543
+ $query_args['socss_post_id'] = $post_id;
544
+ }
545
+ ?>
546
+ <li>
547
+ <?php if ( ! $is_current ) : ?>
548
+ <a href="<?php echo esc_url( add_query_arg( $query_args, admin_url( 'themes.php?page=so_custom_css' ) ) ) ?>"
549
+ class="load-css-revision">
550
+ <?php endif; ?>
551
+ <?php echo date('j F Y @ H:i:s', $time + get_option('gmt_offset') * 60 * 60) ?>
552
+ <?php if ( ! $is_current ) : ?>
553
+ </a>
554
+ <?php endif; ?>
555
+ (<?php printf( __('%d chars', 'so-css'), strlen( $css ) ) ?>)<?php if ( $i == 0 ) : ?> (<?php _e( 'Latest', 'so-css' ) ?>)<?php endif; ?>
556
+ </li>
557
+ <?php
558
+ $i++;
559
+ }
560
+ }
561
+ }
562
+
563
+ /**
564
+ * Add one or more paths to the registered snippet paths
565
+ *
566
+ * @param string|array $path
567
+ */
568
+ function register_snippet_path( $path ) {
569
+ $this->snippet_paths = array_merge( $this->snippet_paths, (array) $path );
570
+ }
571
+
572
+ /**
573
+ * Get all the available snippets
574
+ *
575
+ * @return array|bool
576
+ */
577
+ function get_snippets() {
578
+ // Get the snippet paths
579
+ $snippet_paths = apply_filters( 'siteorigin_css_snippet_paths', $this->snippet_paths );
580
+ if ( empty( $snippet_paths ) ) {
581
+ return array();
582
+ }
583
+
584
+ static $snippets = array();
585
+ if ( ! empty( $snippets ) ) {
586
+ return $snippets;
587
+ }
588
+
589
+ if ( ! WP_Filesystem() ) {
590
+ return false;
591
+ }
592
+ global $wp_filesystem;
593
+ foreach ( $snippet_paths as $path ) {
594
+ foreach ( glob( $path . '/*.css' ) as $css_file ) {
595
+ $data = get_file_data( $css_file, array(
596
+ 'Name' => 'Name',
597
+ 'Description' => 'Description',
598
+ ) );
599
+
600
+ // Get the CSS and strip out the first header
601
+ $css = $wp_filesystem->get_contents( $css_file );
602
+ $css = preg_replace( '!/\*.*?\*/!s', '', $css, 1 );
603
+
604
+ $snippets[] = wp_parse_args( $data, array(
605
+ 'css' => str_replace( "\t", ' ', trim( $css ) ),
606
+ ) );
607
+ }
608
+ }
609
+
610
+ usort( $snippets, array( $this, 'sort_snippet_callback' ) );
611
+
612
+ return $snippets;
613
+ }
614
+
615
+ /**
616
+ * Sort snippets by name.
617
+ *
618
+ * @param $a
619
+ * @param $b
620
+ *
621
+ * @return int
622
+ */
623
+ static function sort_snippet_callback( $a, $b ) {
624
+ return $a['Name'] > $b['Name'] ? 1 : - 1;
625
+ }
626
+
627
+ /**
628
+ * A very simple CSS sanitization function.
629
+ *
630
+ * @param $css
631
+ *
632
+ * @return string
633
+ */
634
+ static function sanitize_css( $css ) {
635
+ return trim( strip_tags( $css ) );
636
+ }
637
+
638
+ /**
639
+ * Get all the available theme CSS
640
+ */
641
+ function get_theme_css() {
642
+ $css = '';
643
+ if ( file_exists( get_template_directory() . '/style.css' ) ) {
644
+ $css .= file_get_contents( get_template_directory() . '/style.css' );
645
+ }
646
+
647
+ if ( is_child_theme() ) {
648
+ $css .= file_get_contents( get_stylesheet_directory() . '/style.css' );
649
+ }
650
+
651
+ // Remove all CSS comments
652
+ $regex = array(
653
+ "`^([\t\s]+)`ism" => '',
654
+ "`^\/\*(.+?)\*\/`ism" => "",
655
+ "`([\n\A;]+)\/\*(.+?)\*\/`ism" => "$1",
656
+ "`([\n\A;\s]+)//(.+?)[\n\r]`ism" => "$1\n",
657
+ "`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism" => "\n"
658
+ );
659
+ $css = preg_replace( array_keys( $regex ), $regex, $css );
660
+ $css = preg_replace( '/\s+/', ' ', $css );
661
+
662
+ return $css;
663
+ }
664
+
665
+ /**
666
+ * Get the editor description
667
+ *
668
+ * @return string
669
+ */
670
+ static function editor_description() {
671
+ $theme = wp_get_theme();
672
+
673
+ return sprintf( __( 'Changes apply to %s and its child themes', 'so-css' ), $theme->get( 'Name' ) );
674
+ }
675
+
676
+ function enqueue_inspector_scripts() {
677
+ if ( ! current_user_can( 'edit_theme_options' ) ) {
678
+ return;
679
+ }
680
+
681
+ wp_enqueue_style( 'dashicons' );
682
+
683
+ wp_enqueue_script( 'siteorigin-css-parser-lib', plugin_dir_url( __FILE__ ) . 'js/css' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), SOCSS_VERSION );
684
+
685
+ wp_enqueue_script( 'siteorigin-css-sizes', plugin_dir_url( __FILE__ ) . 'js/jquery.sizes' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), '0.33' );
686
+ wp_enqueue_script( 'siteorigin-css-specificity', plugin_dir_url( __FILE__ ) . 'js/specificity' . SOCSS_JS_SUFFIX . '.js', array() );
687
+ wp_enqueue_script( 'siteorigin-css-inspector', plugin_dir_url( __FILE__ ) . 'js/inspector' . SOCSS_JS_SUFFIX . '.js', array(
688
+ 'jquery',
689
+ 'underscore',
690
+ 'backbone'
691
+ ), SOCSS_VERSION, true );
692
+ wp_enqueue_style( 'siteorigin-css-inspector', plugin_dir_url( __FILE__ ) . 'css/inspector.css', array(), SOCSS_VERSION );
693
+
694
+ wp_localize_script( 'siteorigin-css-inspector', 'socssOptions', array() );
695
+ }
696
+
697
+ function inspector_templates() {
698
+ if ( ! current_user_can( 'edit_theme_options' ) ) {
699
+ return;
700
+ }
701
+
702
+ include plugin_dir_path( __FILE__ ) . 'tpl/inspector-templates.php';
703
+ }
704
+
705
+ /**
706
+ * Change the stylesheets to all be inline
707
+ */
708
+ function inline_inspector_scripts() {
709
+ if ( ! current_user_can( 'edit_theme_options' ) ) {
710
+ return;
711
+ }
712
+
713
+ $regex = array(
714
+ "`^([\t\s]+)`ism" => '',
715
+ "`^\/\*(.+?)\*\/`ism" => "",
716
+ "`([\n\A;]+)\/\*(.+?)\*\/`ism" => "$1",
717
+ "`([\n\A;\s]+)//(.+?)[\n\r]`ism" => "$1\n",
718
+ "`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism" => "\n"
719
+ );
720
+
721
+ global $wp_styles;
722
+ if ( empty( $wp_styles->queue ) ) {
723
+ return;
724
+ }
725
+
726
+ // Make each of the scripts inline
727
+ foreach ( $wp_styles->queue as $handle ) {
728
+ if ( $handle === 'siteorigin-css-inspector' || $handle === 'dashicons' ) {
729
+ continue;
730
+ }
731
+ $style = $wp_styles->registered[ $handle ];
732
+ if ( empty( $style->src ) || substr( $style->src, 0, 4 ) !== 'http' ) {
733
+ continue;
734
+ }
735
+ $response = wp_remote_get( $style->src );
736
+ if ( is_wp_error( $response ) || $response['response']['code'] !== 200 || empty( $response['body'] ) ) {
737
+ continue;
738
+ }
739
+
740
+ $css = $response['body'];
741
+ $css = preg_replace( array_keys( $regex ), $regex, $css );
742
+
743
+ ?>
744
+ <script type="text/css" class="socss-theme-styles"
745
+ id="socss-inlined-style-<?php echo sanitize_html_class( $handle ) ?>">
746
+ <?php echo strip_tags( $css ); ?>
747
+ </script>
748
+ <?php
749
+ }
750
+ }
751
+
752
+ function disable_ngg_resource_manager() {
753
+ if ( ! current_user_can( 'edit_theme_options' ) ) {
754
+ return;
755
+ }
756
+
757
+ //The NextGen Gallery plugin does some weird interfering with the output buffer.
758
+ define( 'NGG_DISABLE_RESOURCE_MANAGER', true );
759
+ }
760
+
761
+ private function get_latest_revision_timestamp() {
762
+ $revisions = $this->get_custom_css_revisions( $this->theme );
763
+ if ( empty( $revisions ) ) {
764
+ return false;
765
+ }
766
+ krsort( $revisions );
767
+ $revision_times = array_keys( $revisions );
768
+
769
+ return $revision_times[0];
770
+ }
771
+ }
772
+
773
+ // Initialize the single
774
+ SiteOrigin_CSS::single();
tpl/js-templates.php CHANGED
@@ -1,54 +1,67 @@
1
- <script type="text/template" id="template-snippet-browser">
2
- <div class="snippet-browser-overlay">
3
-
4
- </div>
5
-
6
- <div class="snippet-browser-dialog">
7
- <div class="toolbar">
8
- <h1><?php _e('CSS Snippets', 'so-css') ?></h1>
9
- <span href="#" class="close">
10
- <span class="icon"></span>
11
- </span>
12
- </div>
13
- <div class="sidebar">
14
- <input type="text" class="snippet-search" placeholder="<?php esc_attr_e('Search Snippets', 'so-css') ?>" />
15
- <ul class="snippets">
16
- </ul>
17
- </div>
18
- <div class="main">
19
- <div class="snippet-view">
20
- <h2 class="snippet-title"></h2>
21
- <p class="snippet-description"></p>
22
- <pre class="snippet-code"></pre>
23
- </div>
24
- </div>
25
- <div class="buttons">
26
- <input type="button" class="insert-snippet button-primary" value="<?php esc_attr_e('Insert Snippet', 'so-css') ?>" />
27
- </div>
28
- </div>
29
- </script>
30
-
31
- <script type="text/template" id="template-sides-field">
32
- <div class="spacing-field">
33
-
34
- <ul class="select-tabs side-tabs">
35
- <li class="select-tab side-tab" data-direction="all"><div class="spacing-all"></div></li>
36
- <li class="select-tab side-tab" data-direction="top"><div class="spacing-top"></div></li>
37
- <li class="select-tab side-tab" data-direction="right"><div class="spacing-right"></div></li>
38
- <li class="select-tab side-tab" data-direction="bottom"><div class="spacing-bottom"></div></li>
39
- <li class="select-tab side-tab" data-direction="left"><div class="spacing-left"></div></li>
40
- </ul>
41
-
42
- <ul class="sides">
43
-
44
- </ul>
45
-
46
- </div>
47
- </script>
48
-
49
- <script type="text/template" id="template-preview-window">
50
- <div id="preview-navigator">
51
- <input type="text" data-invalid-uri="<?php esc_attr_e( "Invalid URI. Please make sure you're using a URL from the same site.", 'so-css' ) ?>" />
52
- </div>
53
- <iframe id="preview-iframe" seamless="seamless"></iframe>
54
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/template" id="template-snippet-browser">
2
+ <div class="snippet-browser-overlay">
3
+
4
+ </div>
5
+
6
+ <div class="snippet-browser-dialog">
7
+ <div class="toolbar">
8
+ <h1><?php _e('CSS Snippets', 'so-css') ?></h1>
9
+ <span href="#" class="close">
10
+ <span class="icon"></span>
11
+ </span>
12
+ </div>
13
+ <div class="sidebar">
14
+ <input type="text" class="snippet-search" placeholder="<?php esc_attr_e('Search Snippets', 'so-css') ?>" />
15
+ <ul class="snippets">
16
+ </ul>
17
+ </div>
18
+ <div class="main">
19
+ <div class="snippet-view">
20
+ <h2 class="snippet-title"></h2>
21
+ <p class="snippet-description"></p>
22
+ <pre class="snippet-code"></pre>
23
+ </div>
24
+ </div>
25
+ <div class="buttons">
26
+ <input type="button" class="insert-snippet button-primary" value="<?php esc_attr_e('Insert Snippet', 'so-css') ?>" />
27
+ </div>
28
+ </div>
29
+ </script>
30
+
31
+ <script type="text/template" id="template-sides-field">
32
+ <div class="spacing-field">
33
+
34
+ <ul class="select-tabs side-tabs">
35
+ <li class="select-tab side-tab" data-direction="all"><div class="spacing-all"></div></li>
36
+ <li class="select-tab side-tab" data-direction="top"><div class="spacing-top"></div></li>
37
+ <li class="select-tab side-tab" data-direction="right"><div class="spacing-right"></div></li>
38
+ <li class="select-tab side-tab" data-direction="bottom"><div class="spacing-bottom"></div></li>
39
+ <li class="select-tab side-tab" data-direction="left"><div class="spacing-left"></div></li>
40
+ </ul>
41
+
42
+ <ul class="sides">
43
+
44
+ </ul>
45
+
46
+ </div>
47
+ </script>
48
+
49
+ <script type="text/template" id="template-preview-window">
50
+ <div id="preview-navigator">
51
+ <input type="text" data-invalid-uri="<?php esc_attr_e( "Invalid URI. Please make sure you're using a URL from the same site.", 'so-css' ) ?>" />
52
+ </div>
53
+ <iframe id="preview-iframe" seamless="seamless"></iframe>
54
+ </script>
55
+
56
+ <script type="text/template" id="template-webfont-teaser">
57
+ <input type="text" value="" />
58
+ <small style="color: #888">
59
+ <?php
60
+ printf(
61
+ __( 'Get a %sGoogle Font%s selector.', 'so-css' ) ,
62
+ '<a href="https://siteorigin.com/downloads/premium/?featured_addon=plugin/web-font-selector" target="_blank">',
63
+ '</a>'
64
+ );
65
+ ?>
66
+ </small>
67
+ </script>
tpl/page.php CHANGED
@@ -1,134 +1,134 @@
1
- <?php
2
- /**
3
- * @var $custom_css_revisions array Saved revisions for the current theme.
4
- */
5
-
6
- $snippets = SiteOrigin_CSS::single()->get_snippets();
7
- $user = wp_get_current_user();
8
- ?>
9
-
10
- <div class="wrap" id="siteorigin-custom-css">
11
- <h2>
12
- <img src="<?php echo plugin_dir_url(__FILE__) . '../css/images/icon.png' ?>" class="icon" />
13
- <?php _e( 'SiteOrigin CSS', 'so-css' ) ?>
14
- </h2>
15
-
16
-
17
- <?php if( isset($_POST['siteorigin_custom_css_save']) ) : ?>
18
- <div class="updated settings-error"><p><?php _e('Site design updated.', 'so-css') ?></p></div>
19
- <?php endif; ?>
20
-
21
- <?php if(!empty($revision)) : ?>
22
- <div class="updated settings-error">
23
- <p><?php _e('Viewing a revision. Save CSS to keep using this revision.', 'so-css') ?></p>
24
- </div>
25
- <?php endif; ?>
26
-
27
- <div id="poststuff">
28
- <div id="so-custom-css-info">
29
-
30
- <?php if( !get_user_meta( $user->ID, 'socss_hide_gs' ) ) : ?>
31
- <div class="postbox" id="so-custom-css-getting-started">
32
- <h3 class="hndle">
33
- <span><?php _e('Getting Started Video', 'so-css') ?></span>
34
- <a href="<?php echo wp_nonce_url( admin_url('admin-ajax.php?action=socss_hide_getting_started'), 'hide' ) ?>" class="hide"><?php _e('Dismiss', 'so-css') ?></a>
35
- </h3>
36
- <div class="inside">
37
- <a href="https://siteorigin.com/css/getting-started/" target="_blank"><img src="<?php echo plugin_dir_url(__FILE__).'../css/images/video.jpg' ?>" /></a>
38
- </div>
39
- </div>
40
- <?php endif; ?>
41
-
42
- <div class="postbox" id="so-custom-css-revisions">
43
- <h3 class="hndle"><span><?php _e('CSS Revisions', 'so-css') ?></span></h3>
44
- <div class="inside">
45
- <ol data-confirm="<?php esc_attr_e('Are you sure you want to load this revision?', 'so-css') ?>">
46
- <?php
47
- if ( is_array( $custom_css_revisions ) ) {
48
- $is_current = true;
49
- foreach ( $custom_css_revisions as $time => $css ) {
50
- ?>
51
- <li>
52
- <?php if ( $is_current ) : ?>
53
- <?php echo date('j F Y @ H:i:s', $time + get_option('gmt_offset') * 60 * 60) ?> (Current)
54
- <?php $is_current = false; ?>
55
- <?php else : ?>
56
- <a href="<?php echo esc_url( add_query_arg( array( 'theme' => $theme, 'time' => $time ) ) ) ?>" class="load-css-revision"><?php echo date('j F Y @ H:i:s', $time + get_option('gmt_offset') * 60 * 60) ?></a>
57
- (<?php printf(__('%d chars', 'so-css'), strlen($css)) ?>)
58
- <?php endif; ?>
59
- </li>
60
- <?php
61
- }
62
- }
63
- ?>
64
- </ol>
65
- </div>
66
- </div>
67
-
68
- </div>
69
-
70
- <form action="<?php echo esc_url( admin_url('themes.php?page=so_custom_css') ) ?>" method="POST" id="so-custom-css-form">
71
-
72
- <div class="custom-css-toolbar">
73
- <div class="toolbar-function-buttons">
74
- <div class="toolbar-functions-dropdown">
75
- <span class="dashicons dashicons-menu"></span>
76
- </div>
77
- <ul class="toolbar-buttons">
78
- </ul>
79
- </div>
80
-
81
- <div class="toolbar-action-buttons">
82
-
83
- <a href="#visual" class="editor-visual socss-button">
84
- <span class="fa fa-eye"></span>
85
- </a>
86
-
87
- <a href="#expand" class="editor-expand socss-button">
88
- <span class="fa fa-expand"></span>
89
- <span class="fa fa-compress"></span>
90
- </a>
91
- </div>
92
- </div>
93
-
94
- <div class="custom-css-container">
95
- <textarea name="custom_css" id="custom-css-textarea" class="css-editor" rows="<?php echo max( 10, substr_count( $custom_css, "\n" )+1 ) ?>"><?php echo esc_textarea( $custom_css ) ?></textarea>
96
- <?php wp_nonce_field( 'custom_css', '_sononce' ) ?>
97
- </div>
98
- <p class="description"><?php SiteOrigin_CSS::editor_description() ?></p>
99
-
100
- <p class="submit">
101
- <input type="submit" name="siteorigin_custom_css_save" class="button-primary" value="<?php esc_attr_e( 'Save CSS', 'so-css' ); ?>" />
102
- </p>
103
-
104
- <div class="custom-css-preview">
105
-
106
- </div>
107
-
108
- <div class="decoration"></div>
109
-
110
- </form>
111
-
112
- <div id="so-custom-css-properties">
113
-
114
- <div class="toolbar">
115
- <select>
116
- </select>
117
- <div class="close socss-button">
118
- <span class="fa fa-check"></span>
119
- </div>
120
- </div>
121
-
122
- <ul class="section-tabs">
123
- </ul>
124
-
125
- <div class="sections">
126
- </div>
127
-
128
- </div>
129
-
130
- </div>
131
-
132
- <div class="clear"></div>
133
-
134
- </div>
1
+ <?php
2
+ /**
3
+ * @var $custom_css string The custom CSS string to be edited.
4
+ * @var $current_revision int If the CSS to be edited is a revision, this will contain the timestamp of the revision.
5
+ * @var $custom_css_revisions array Saved revisions for the current theme.
6
+ */
7
+
8
+ $snippets = SiteOrigin_CSS::single()->get_snippets();
9
+ $user = wp_get_current_user();
10
+ if ( ! empty( $current_revision ) ) {
11
+ $revision_date = date( 'j F Y @ H:i:s', $current_revision + get_option( 'gmt_offset' ) * 60 * 60 );
12
+ }
13
+ ?>
14
+
15
+ <div class="wrap" id="siteorigin-custom-css">
16
+ <h2>
17
+ <img src="<?php echo plugin_dir_url(__FILE__) . '../css/images/icon.png' ?>" class="icon" />
18
+ <?php _e( 'SiteOrigin CSS', 'so-css' ) ?>
19
+ </h2>
20
+
21
+
22
+ <?php if( isset($_POST['siteorigin_custom_css_save']) ) : ?>
23
+ <div class="notice notice-success"><p><?php _e('Site design updated.', 'so-css') ?></p></div>
24
+ <?php endif; ?>
25
+
26
+ <?php if ( ! empty( $current_revision ) ) : ?>
27
+ <div class="notice notice-warning">
28
+ <p><?php printf( __( 'Editing revision dated %s. Click %sRevert to this revision%s to keep using it.', 'so-css'), $revision_date, '<em>', '</em>' ) ?></p>
29
+ </div>
30
+ <?php endif; ?>
31
+
32
+ <div id="poststuff">
33
+ <div id="so-custom-css-info">
34
+
35
+ <?php if( $this->display_teaser() ) : ?>
36
+ <div class="postbox">
37
+ <h3 class="hndle"><span><?php _e('Get The Full Experience', 'so-css') ?></span></h3>
38
+ <div class="inside">
39
+ <?php printf( __( '%sSiteOrigin Premium%s adds a <strong>Google Web Font</strong> selector to SiteOrigin CSS so you can easily change any font.', 'so-css' ) , '<a href="https://siteorigin.com/downloads/premium/?featured_addon=plugins/web-font-selector" target="_blank">', '</a>' ); ?>
40
+ </div>
41
+ </div>
42
+ <?php endif; ?>
43
+
44
+ <?php if( !get_user_meta( $user->ID, 'socss_hide_gs' ) ) : ?>
45
+ <div class="postbox" id="so-custom-css-getting-started">
46
+ <h3 class="hndle">
47
+ <span><?php _e('Getting Started Video', 'so-css') ?></span>
48
+ <a href="<?php echo wp_nonce_url( admin_url('admin-ajax.php?action=socss_hide_getting_started'), 'hide' ) ?>" class="hide"><?php _e('Dismiss', 'so-css') ?></a>
49
+ </h3>
50
+ <div class="inside">
51
+ <a href="https://siteorigin.com/css/getting-started/" target="_blank"><img src="<?php echo plugin_dir_url(__FILE__).'../css/images/video.jpg' ?>" /></a>
52
+ </div>
53
+ </div>
54
+ <?php endif; ?>
55
+
56
+ <div class="postbox" id="so-custom-css-revisions">
57
+ <h3 class="hndle"><span><?php _e('CSS Revisions', 'so-css') ?></span></h3>
58
+ <div class="inside">
59
+ <ol class="custom-revisions-list" data-confirm="<?php esc_attr_e('Are you sure you want to load this revision?', 'so-css') ?>">
60
+ <?php
61
+ $this->custom_css_revisions_list( $theme, $socss_post_id, $current_revision );
62
+ ?>
63
+ </ol>
64
+ </div>
65
+ </div>
66
+
67
+ </div>
68
+
69
+ <form action="<?php echo esc_url( admin_url('themes.php?page=so_custom_css') ) ?>" method="POST" id="so-custom-css-form">
70
+
71
+ <div class="custom-css-toolbar">
72
+ <div class="toolbar-function-buttons">
73
+ <div class="toolbar-functions-dropdown">
74
+ <span class="dashicons dashicons-menu"></span>
75
+ </div>
76
+
77
+ <ul class="toolbar-buttons">
78
+ </ul>
79
+ </div>
80
+
81
+ <div class="toolbar-action-buttons">
82
+
83
+ <a href="#visual" class="editor-visual socss-button">
84
+ <span class="fa fa-eye"></span>
85
+ </a>
86
+
87
+ <a href="#expand" class="editor-expand socss-button">
88
+ <span class="fa fa-expand"></span>
89
+ <span class="fa fa-compress"></span>
90
+ </a>
91
+ </div>
92
+ </div>
93
+
94
+ <div class="custom-css-container">
95
+ <textarea name="custom_css" id="custom-css-textarea" class="css-editor" rows="<?php echo max( 10, substr_count( $custom_css, "\n" ) + 1 ) ?>"><?php echo esc_textarea( $custom_css ) ?></textarea>
96
+ <?php wp_nonce_field( 'custom_css', '_sononce' ) ?>
97
+ </div>
98
+ <p class="description"><?php echo SiteOrigin_CSS::editor_description(); ?></p>
99
+
100
+ <p class="submit">
101
+ <input type="submit" name="siteorigin_custom_css_save" class="button-primary" value="<?php esc_attr_e( ( ! empty ( $current_revision ) ? __( 'Revert to this revision', 'so-css' ) : __( 'Save CSS', 'so-css' ) ) ); ?>" />
102
+ </p>
103
+
104
+ <div class="custom-css-preview">
105
+
106
+ </div>
107
+
108
+ <div class="decoration"></div>
109
+
110
+ </form>
111
+
112
+ <div id="so-custom-css-properties">
113
+
114
+ <div class="toolbar">
115
+ <select>
116
+ </select>
117
+ <div class="close socss-button">
118
+ <span class="fa fa-check"></span>
119
+ </div>
120
+ </div>
121
+
122
+ <ul class="section-tabs">
123
+ </ul>
124
+
125
+ <div class="sections">
126
+ </div>
127
+
128
+ </div>
129
+
130
+ </div>
131
+
132
+ <div class="clear"></div>
133
+
134
+ </div>