-
Notifications
You must be signed in to change notification settings - Fork 4
/
lcCardLayoutToWeb-IMPORT.livecodescript
2037 lines (1699 loc) · 89.7 KB
/
lcCardLayoutToWeb-IMPORT.livecodescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
script "lcCardLayoutToWeb-IMPORT"
/*
Design, text, images and code by Richard K. Herz, 2017-2021
Copyrights held by Richard K. Herz
https://github.com/RichardHerz
Licensed for use under the GNU General Public License v3.0
https://www.gnu.org/licenses/gpl-3.0.en.html
*/
constant kProjectName = "lcCardLayoutToWeb" -- controls with this in name aren't written to html
-- make sure value of constant kProjectName is the same in both script files
constant kFieldShift = 16 -- was 16, subtract to shift locked fields when exporting <p> tags, add on import
-- make sure value of constant kFieldShift is the same in both script files
constant kCssTopShift = 50 -- value used in css file for computed shift of elements
-- make sure value of constant kCssTopShift is the same in both script files
constant kTextFontExportAdd = 3 -- was 3, value to add to font size on export, subtract on import
-- make sure value of constant kTextFontExportAdd is the same in both script files
constant kScriptTagPrefix = "scriptTag" -- used on IMPORT and EXPORT of script tags in html body
-- make sure value of constant kScriptTagPrefix is the same in both script files
constant kCommentTagPrefix = "commentTag" -- used on IMPORT and EXPORT of script tags in html body
-- make sure value of constant kCommentTagPrefix is the same in both script files
-- item list of added html value and events that are saved on import
-- value is text to be shown in unlocked input fields and as button labels
-- in fGetHtmlEvents skip value for unlocked input fields or get two values written on subsequent export
-- in fGetHtmlEvents skip value for standard buttons or get two values written on subsequent export
constant kEventList = "value,onchange,oninput,onclick,ondrag,onmouseup"
-- use kReporter "true" to activate all reports below to msg box
-- or use a special value to activate only selected reports below
-- EXAMPLE: if kReporter is "true" then put LF & tData after msg -- true displays all
-- EXAMPLE: if kReporter is "TEST" then put LF & tData after msg -- only displays some
constant kReporter = "false"
local oScrollbarList -- used to set the vScrollbar of groups
-----------------------------
/*
TAGS DONE -----------
div = group
p = locked field
img = image
select = menu button
input with no type = unlocked field
input with type="button" = button
input with type="range" = scrollbar
label > input type="checkbox" > span = checkbox
label > input type="radio" > span = radio button (will be several inside one div/group)
canvas
TAGS TO DO -----------
--
*/
-----------------------------
on deleteNonDevControls
-- this can be run before importing html and css data to make a new card layout
-- if card has old controls on it
answer "WARNING: DELETE ALL GROUPS AND CONTROLS OTHER THAN DEVELOPMENT CONTROLS?" with "yes" or "NO!"
if it is "NO!" then exit to top
repeat with tControlNumber = the number of controls down to 1
if the short name of control tControlNumber contains kProjectName then
-- skip these development controls
next repeat
end if
delete control tControlNumber
end repeat
set the cHeaderData of this card to empty
end deleteNonDevControls
-----------------------------
on importWebPage
-- calls function fMakeLiveCodeCard
set the defaultStack to kProjectName
-- CHECK IF CARD HAS NO CONTROLS OTHER THAN DEVELOPMENT CONTROLS
put "true" into tCleanOfControls
repeat with tControlNumber = 1 to the number of controls
if the short name of control tControlNumber contains kProjectName then
-- skip these development controls
next repeat
end if
put "false" into tCleanOfControls
end repeat
if tCleanOfControls is not "true" then
answer "WARNING: DELETE ALL GROUPS AND CONTROLS OTHER THAN DEVELOPMENT CONTROLS"
exit to top
end if
-- Note on LC syntax: "answer file" only allows one file to be selected
-- "answer files" allows more than one file to be selected and returns paths on separate lines
put empty into tHtmlFile
answer file "select HTML file" with type "html|html|html"
if the result is empty then
put it into tHtmlFile
if ".html" is in tHtmlFile then
-- assume OK for now but check if at end
else
answer "This is not an html file"
put empty into tHtmlFile
end if -- end if ".html" is in tHtmlFile
end if -- end if the result is empty
if tHtmlFile is not empty then
put empty into tCssFile
answer file "select CSS file" with type "css|css|css"
if the result is empty then
put it into tCssFile
if ".css" is in tCssFile then
-- assume OK for now but check if at end
else
answer "This is not a CSS file"
put empty into tCssFile
end if -- end if ".css" is in tCssFile
end if -- end if the result is empty
end if -- end if tHtmlFile is not empty
-- at this point should have tHtmlFile data
-- and may have tCssFile data if there is a css file
-- NOTE there may be a style tag(s) inside html data!
if tHmtlFile is not empty then
put "file:" before tHtmlFile
put url tHtmlFile into tHtmlFileData
else
exit to top
end if
if tCssFile is not empty then
put "file:" before tCssFile
put url tCssFile into tCssFileData
else
exit to top
end if
get fMakeLiveCodeCard(tHtmlFileData, tCssFileData)
select empty
beep
end importWebPage
-----------------------------
function fMakeLiveCodeCard pHtmlFileData, pCssFileData
-- uses constant kProjectName
-- is called by command importWebPage
put empty into tGrpList
put empty into tGrpLocList
put empty into oScrollbarList
-- get all data above <body>
put offset("<body>",pHtmlFileData) into tBodyStartChar
put char 1 to tBodyStartChar-1 of pHtmlFileData into tHeaderData
set the cHeaderData of this card to tHeaderData
-- MUST USE MESSAGE BOX FOR DEVELOPMENT RECORD - NOT FIELD
-- BECAUSE CAN'T ACCESS FIELD WHEN EDITING A GROUP easily at least
-- do not always put empty into msg here because will open msg box even if not used
if kReporter is not "false" then put empty into msg
if kReporter is "true" then put LF & tHeaderData into msg -- NOTE "INTO" FOR FIRST ONE
put tBodyStartChar into tSkipChar
add 5 to tSkipChar -- set to end > of <body>
put empty into tCommentList
repeat
put offset("<",pHtmlFileData,tSkipChar) into tNextTagStart
if tNextTagStart is 0 then exit repeat
add tNextTagStart to tSkipChar
put tSkipChar into tNextTagStart
-- -- save comments in body which are outside of other tags
-- if offset("!--",pHtmlFileData,tSkipChar) = 1 then
-- -- tSkipChar points to < of <!-- comment
-- if kReporter is "true" then put LF & "comment found" & LF after msg
-- -- want to skip to end comment in case have commented out some controls
-- put offset("-->",pHtmlFileData,tSkipChar) into tEndComment
-- add 2 to tEndComment -- include -> of -->
-- add tEndComment to tSkipChar
-- put tSkipChar into tEndComment
-- put char tNextTagStart to tEndComment of pHtmlFileData into tComment
-- if tComment contains "end of div div_" then
-- -- export writes end of div comments like this: <!-- end of div div_EMPTY_group_1017 -->
-- -- do not save these
-- else
-- put tComment & LF after tCommentList
-- -- tCommentList will be saved at end fMakeLiveCodeCard
-- -- these are comments in body which are outside of non-div tags
-- end if
-- next repeat
-- -- xxx need to save comments somewhere
-- -- xxx see fImportScriptTag which creates a button for each script tag in body
-- -- xxx this could be used for comments so they get put in (approx) place on export
-- end if
if offset("/div>",pHtmlFileData,tSkipChar) = 1 then
-- tSkipChar points to < of </div>
if kReporter is "true" then put LF & "JUST BEFORE get fImportGroupEnd, tGrpList = " & "---||" & tGrpList & "||---" & LF after msg
if kReporter is "true" then put LF & "JUST BEFORE get fImportGroupEnd, tGrpLocList = " & "---||" & tGrpLocList & "||---" & LF after msg
get fImportGroupEnd(tSkipChar, tGrpList, tGrpLocList)
put it into tResult
put tResult["SkipChar"] into tSkipChar
put tResult["GrpList"] into tGrpList
put tResult["GrpLocList"] into tGrpLocList
if kReporter is "true" then put LF & "JUST AFTER get fImportGroupEnd, tGrpList = " & "---||" & tGrpList & "||---" & LF after msg
if kReporter is "true" then put LF & "JUST AFTER get fImportGroupEnd, tGrpLocList = " & "---||" & tGrpLocList & "||---" & LF after msg
next repeat
end if
if offset("/",pHtmlFileData,tSkipChar) = 1 then
-- tSkipChar points to < of </tag
-- these are usually handled in tag functions but get for </body> and </html>
add 1 to tSkipChar -- get off this
next repeat
end if
put offset(space,pHtmlFileData,tSkipChar) into tNextSpaceChar
-- but could be <tag> and space down the line...
-- make sure it's not past end this tag
put offset(">",pHtmlFileData,tSkipChar) into tNextEndChar
if tNextEndChar < tNextSpaceChar then
-- not a tag with an attribute such as type or id
add tSkipChar to tNextEndChar
put char tSkipChar + 1 to tNextEndChar - 1 of pHtmlFileData into tTagName
if kReporter is "true" then
put LF & "tNextEndChar < tNextSpaceChar so not a tag with attribute such as type or id, tTagName = " & tTagName & LF after msg
end if
else
add tSkipChar to tNextSpaceChar
put char tNextTagStart + 1 to tNextSpaceChar - 1 of pHtmlFileData into tTagName
if kReporter is "true" then
put LF & "before switch in makeLiveCodeCard, tTagName = " & tTagName & LF after msg
end if
end if
switch tTagName
case "div"
-- check if PLOTDIV div or TEXTDIV or regular div
put fGetHtmlAttribute(tSkipChar, pHtmlFileData, "id") into tID
if "_PLOTDIV_" is in tID then
-- special html div for x-y plot to be imported as specially named LC button
if kReporter is "true" then put LF & "JUST BEFORE get fImportPLOTDIV, tGrpList = " & "---||" & tGrpList & "||---" & LF after msg
if kReporter is "true" then put LF & "JUST BEFORE get fImportPLOTDIV, tGrpLocList = " & "---||" & tGrpLocList & "||---" & LF after msg
put fImportPLOTDIV(tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList) into tSkipChar
if kReporter is "true" then -- ELSE DID NOT LIKE SINGLE LINE IF HERE
put LF & "JUST AFTER get fImportPLOTDIV, tSkipChar = " & tSkipChar & LF after msg
end if
else if "_TEXTDIV_" is in tID then
-- special html div for multi-line text to be imported as specially named LC button
if kReporter is "true" then put LF & "JUST BEFORE get fImportTEXTDIV, tGrpList = " & "---||" & tGrpList & "||---" & LF after msg
if kReporter is "true" then put LF & "JUST BEFORE get fImportTEXTDIV, tGrpLocList = " & "---||" & tGrpLocList & "||---" & LF after msg
put fImportTEXTDIV(tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList) into tSkipChar
if kReporter is "true" then -- ELSE DID NOT LIKE SINGLE LINE IF HERE
put LF & "JUST AFTER get fImportTEXTDIV, tSkipChar = " & tSkipChar & LF after msg
end if
else
-- import regular html div = LC group
if kReporter is "true" then put LF & "JUST BEFORE get fImportGroupStart, tGrpList = " & "---||" & tGrpList & "||---" & LF after msg
if kReporter is "true" then put LF & "JUST BEFORE get fImportGroupStart, tGrpLocList = " & "---||" & tGrpLocList & "||---" & LF after msg
get fImportGroupStart(tSkipChar, pHtmlFileData, pCssFileData, tGrpList, tGrpLocList)
put it into tResult
put tResult["SkipChar"] into tSkipChar
put tResult["GrpList"] into tGrpList
put tResult["GrpLocList"] into tGrpLocList
if kReporter is "true" then put LF & "JUST AFTER get fImportGroupStart, tGrpList = " & "---||" & tGrpList & "||---" & LF after msg
if kReporter is "true" then put LF & "JUST AFTER get fImportGroupStart, tGrpLocList = " & "---||" & tGrpLocList & "||---" & LF after msg
end if
break
case "p"
-- import p = locked field
put fImportLockedField(tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList) into tSkipChar
break
case "img"
-- import img = image
put fImportImage(tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList) into tSkipChar
break
case "select"
-- import select = menu button
put fImportMenuButton(tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList) into tSkipChar
break
case "input"
-- import input that are not inside <label tags
-- 3 types: none = unlocked field, button = button, range = slider
put fImportInputTag(tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList) into tSkipChar
break
case "label"
-- import label
-- need to look for <input inside
-- two input types: checkbox, radio button
-- <label <input followed by <span
put fImportLabelTag(tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList) into tSkipChar
break
case "canvas"
put fImportCANVAS(tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList) into tSkipChar
break
case "script"
-- these are script tags in html body outside other tags
put fImportScriptTag(tSkipChar, pHtmlFileData) into tSkipChar
break
case "!--"
-- these are comment tags in html body outside other tags
put fImportCommentTag(tSkipChar, pHtmlFileData) into tSkipChar
break
default
-- ignore for now
end switch
end repeat
-- save comment list, if any
if tCommentList is empty then
-- no comments found in body outside of non-div tags, other than end of div
else
put "<!-- *** START COLLECTION OF COMMENTS IN BODY OUTSIDE NON-DIV TAGS *** -->" & LF before tCommentList
put "<!-- *** END COLLECTION OF COMMENTS IN BODY OUTSIDE NON-DIV TAGS *** -->" & LF after tCommentList
put the cHeaderData of this card into tHeaderData
put LF & tCommentList after tHeaderData
set the cHeaderData of this card to tHeaderData
end if
-- xxx for unknown reason, at least in LC 9(dp6), setting the vScrollbar property of a group
-- xxx in fGetSetControlProps changed in some unknown way the left value
-- xxx that was set in the topLeft of one of the groups inside the group with the vScrollbar
-- xxx saving the vScrollbar property value in fGetSetControlProps and then setting it now works
-- oScrollbarList is set in case "LCvScrollbar" of switch in function fGetSetControlProps
if oScrollbarList is not empty then
set the itemDelimiter to "$" -- need delimiter that does not appear in a file name
repeat for each line tLine in oScrollbarList
put item 1 of tLine into tControlName
put item 2 of tLine into tValue
try
-- xxx for now, quick fix of plot div having LCvScrollBar but error on import to PLOTDIV button
-- maybe check fGetSetControlProps and
-- only add to list if name contains group or field or text input
set the vScrollbar of tControlName to tValue
end try
end repeat
set the itemDelimiter to comma
end if
end fMakeLiveCodeCard
-----------------------------
function fImportCANVAS tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList
-- this is to import to LC a BUTTON that represents the area of an HTML CANVAS element
-- used for generating images on HTML canvas by Javascript
-- need to return updated tSkipChar
-- EXAMPLE: <canvas id="canvas_CANVAS_rate" width="400" height="200"></canvas> <!-- ... etc.
-- THIS GETS IMPORTED TO LC AS A BUTTON
-- GET CONTROL ID
put fGetHtmlAttribute(tSkipChar, pHtmlFileData, "id") into tID
-- tID used below in GET CSS
put tID into tCanvas
replace "_" with space in tCanvas
-- prefix "canvas" added in export, others added later might not have it
if word 1 of tCanvas is "canvas" then delete word 1 of tCanvas
-- USE "CANVAS" as first word of short name of LC button to identify an html canvas element
if word 1 of tCanvas is not "CANVAS" then put "CANVAS" and space before tCanvas
-- CREATE BUTTON TO REPRESENT HTML CANVAS
create button
set the name of it to tCanvas
-- below are special properties for the button
set the style of button tCanvas to rectangle
set the showName of button tCanvas to true
set the label of button tCanvas to empty
-- set the showBorder of button tCanvas to true
-- set the borderWidth of button tCanvas to 2
-- set the backColor of button tCanvas to 0,255,0
-- NOTE new button representing canvas will get LC default width & height since none
-- specified in CSS for canvas elements
-- need to get width and height from HTML and set the new button
-- EXAMPLE: <canvas id="canvas_CANVAS_rate" width="400" height="200"></canvas> <!-- ... etc.
--
-- NOTE must use quotes (width="400") and not apostrophes (width='400') nor neither (width=400)
-- and no units (px) nor spaces for import by this project - see function fGetHtmlAttribute in IMPORT script stack
put the long name of button tCanvas into tControlLongName -- NOTE button tCanvas
-- FIRST GET WIDTH & HEIGHT FROM HTML & SET
put fGetHtmlAttribute(tSkipChar, pHtmlFileData, "width") into tWidth
put fGetHtmlAttribute(tSkipChar, pHtmlFileData, "height") into tHeight
set the width of button tControlLongName to tWidth
set the height of button tControlLongName to tHeight
-- THEN GET CSS & SET OTHER CONTROL PROPERTIES
get fGetSetControlProps(tID, tControlLongName, pCssFileData, tGrpLocList)
-- update tSkipChar before returning
put offset("</canvas>",pHtmlFileData,tSkipChar) into tEndChar
add tEndChar to tSkipChar
put offset(">",pHtmlFileData,tSkipChar) into tEndChar
add tEndChar to tSkipChar
return tSkipChar
end fImportCANVAS
-----------------------------
function fImportScriptTag tSkipChar, pHtmlFileData
-- this is for <script> tags that appear in the html body (those in header get saved with header)
-- this creates a button whose custom property cScriptTagCode contains the entire
-- script tag and contents from and including <script> to </script>
-- on export, this code will be written to html in approximately the location in the html in which it
-- appeared before import
-- cScriptTagCode must match name used in both IMPORT and EXPORT scripts
-- create button
create button
-- build uniqe name in variable tButton starting with the prefix kScriptTagPrefix
set the name of it to kScriptTagPrefix
put the id of button kScriptTagPrefix into tID
put kScriptTagPrefix && tID into tButton
set the name of button kScriptTagPrefix to tButton
-- now can refer to control as button tButton
-- below are special properties for the button
set the topLeft of button tButton to 0,40 -- will get overlapping buttons if more than one script tag in body
set the style of button tButton to rectangle
set the showBorder of button tButton to true
set the borderWidth of button tButton to 2
set the backColor of button tButton to 200,200,255
-- HIDE the button because assume will not do any script editing
-- in the LiveCode design stack
-- the script tag and code will still get exported to html on export
hide button tButton
-- get the script tag and save it
put offset("</script>",pHtmlFileData,tSkipChar) into tEndChar
add tSkipChar to tEndChar
add 8 to tEndChar -- move from < to > in </script>
put char tSkipChar to tEndChar of pHtmlFileData into tScriptCode
put LF after tScriptCode
-- name of custom prop cScriptTagCode must match name used in both IMPORT and EXPORT scripts
set the cScriptTagCode of button tButton to tScriptCode
-- update tSkipChar and return
put tEndChar into tSkipChar
return tSkipChar
end fImportScriptTag
-----------------------------
function fImportCommentTag tSkipChar, pHtmlFileData
-- this is for <!-- comment tags that appear in the html body (those in header get saved with header)
-- this creates a button whose custom property cCommentTagCode contains the entire
-- comment tag and contents from and including <!-- to -->
-- on export, this code will be written to html in approximately the location in the html in which it
-- appeared before import
-- cCommentTagCode must match name used in both IMPORT and EXPORT scripts
-- get the comment tag FIRST so can check it for default "end of div" comment
put offset("-->",pHtmlFileData,tSkipChar) into tEndChar
add tSkipChar to tEndChar
add 2 to tEndChar -- move from - to > in -->
put char tSkipChar to tEndChar of pHtmlFileData into tCommentCode
put LF after tCommentCode
if tCommentCode contains "end of div div_" then
-- do not save these, since they are produced by EXPORT script for all div endings
else
-- create button
create button
-- build uniqe name in variable tButton starting with the prefix kCommentTagPrefix
set the name of it to kCommentTagPrefix
put the id of button kCommentTagPrefix into tID
put kCommentTagPrefix && tID into tButton
set the name of button kCommentTagPrefix to tButton
-- now can refer to control as button tButton
-- below are special properties for the button
set the topLeft of button tButton to 0,80 -- will get overlapping buttons if more than one comment tag in body
set the style of button tButton to rectangle
set the showBorder of button tButton to true
set the borderWidth of button tButton to 2
set the backColor of button tButton to 200,255,200
-- HIDE the button because assume will not add any coments
-- in the LiveCode design stack
-- the comment tag and code will still get exported to html on export
hide button tButton
-- name of custom prop cCommentTagCode must match name used in both IMPORT and EXPORT scripts
set the cCommentTagCode of button tButton to tCommentCode
end if -- end of if tComment contains "end of div div_"
-- update tSkipChar and return
put tEndChar into tSkipChar
return tSkipChar
end fImportCommentTag
-----------------------------
function fImportLabelTag tSkipChar, pHtmlFileData, pCssFileData, tGrpLocList
if kReporter is "true" then put LF & "enter fImportLabelTag" & LF after msg
-- tSkipChar points to < of <label
-- need to return updated tSkipChar
-- THERE ARE TWO TYPES
-- need to look for <input inside of <label and </label>
-- two input types: checkbox, radio button
-- <label followed by <input followed by <span
-- EXAMPLE OF CHECKBOX
-- <label id="checkbox_Check1_1046_LABEL">
-- <input type="checkbox" id="checkbox_Check1_1046">
-- <span id="checkbox_Check1_1046_SPAN">Check1</span>
-- </label>
-- EXAMPLE OF RADIO BUTTONS - ALL INSIDE A DIV HANDLED BY fImportGroupStart and ...End
-- HERE JUST IMPORT ONE OF THE RADIO BUTTONS -- THAT IS, ONE LABEL TAG
-- <label id="radio_Radio2_1043_LABEL" name="radio_of_group_RADIO_group">
-- <input type="radio" id="radio_Radio2_1043" name="radio_of_group_RADIO_group">
-- <span id="radio_Radio2_1043_SPAN">Radio2</span>
-- </label>
-- <label id="radio_Radio1_1044_LABEL" name="radio_of_group_RADIO_group">
-- <input type="radio" id="radio_Radio1_1044" name="radio_of_group_RADIO_group" checked>
-- <span id="radio_Radio1_1044_SPAN">Radio1</span>
-- </label>
put offset("</label>",pHtmlFileData,tSkipChar) into tEndChar
put offset("type=",pHtmlFileData,tSkipChar) into tTypeChar
put empty into tType
if (tTypeChar < tEndChar) then
add tSkipChar to tTypeChar
add 6 to tTypeChar -- just inside " of type="
put offset(quote,pHtmlFileData,tTypeChar) into tQuoteChar
subtract 1 from tQuoteChar
add tTypeChar to tQuoteChar
put char tTypeChar to tQuoteChar of pHtmlFileData into tType
end if
-- radiobutton is LC button style property for radio buttons
if tType is "radio" then put "radiobutton" into tType
get fImportCheckOrRadioButton(tSkipChar, tType, pHtmlFileData, pCssFileData, tGrpLocList)
if kReporter is "true" then put LF & "exit fImportLabelTag" & LF after msg
-- update tSkipChar here before returning
put offset("</label>",pHtmlFileData,tSkipChar) into tEndChar
add tEndChar to tSkipChar
put offset(">",pHtmlFileData,tSkipChar) into tEndChar
add tEndChar to tSkipChar
return tSkipChar
end fImportLabelTag
-----------------------------
function fGetHtmlAttribute pSkipChar, pFileData, pTargetName
-- ASSUMES no spaces outside of quotes in, e.g., pTargetName="target value"
-- ASSUMES pSkipChar points to < of <parentTag
if kReporter is "true" then put LF & LF & "=!=!=!=!=!= ENTER fGetHtmlAttribute =!=!=!=!=!=" after msg
if kReporter is "true" then put LF & "pSkipChar =" & pSkipChar after msg
if kReporter is "true" then put LF & "-------------------------------" after msg
-- if kReporter is "true" then put LF & "pFileData =" & LF & pFileData after msg
-- if kReporter is "true" then put LF & "-------------------------------" after msg
if kReporter is "true" then put LF & "pTargetName =" & pTargetName after msg
if kReporter is "true" then put LF & "-------------------------------" after msg
-- previously had trouble for this: target=""
-- so revised original script to a more complex script below
-- get end of parent tag to make sure this attribute inside this tag
put offset(">", pFileData, pSkipChar) into tTagEndChar
add pSkipChar to tTagEndChar
-- search below only in this tag
put char pSkipChar to tTagEndChar of pFileData into tTagData
if kReporter is "true" then put LF & "fGetHtmlAttribute, tTagData = " & tTagData after msg -- development field
-- ASSUME no space between pTargetName and ="
put offset(pTargetName & "=" & quote, tTagData) into tTargetStartChar
if tTargetStartChar = 0 then
put empty into tTargetValue
if kReporter is "TEST" then
put LF & "fGetHtmlAttribute, tTargetStartChar = 0" after msg -- development field
end if
else
put the number of chars of pTargetName into tNum
add 2 to tNum -- + 2 to step inside ="
add tNum to tTargetStartChar -- move inside first quote
put offset(quote, tTagData, tTargetStartChar) into tTargetEndChar
if tTargetEndChar = 0 then
if kReporter is "TEST" then
put LF & "fGetHtmlAttribute, tTargetEndChar = 0" after msg -- development field
end if
-- can get this for target="" looking from inside first quote
put empty into tTargetValue
else
subtract 1 from tTargetEndChar -- step back before second quote
add tTargetStartChar to tTargetEndChar
put char tTargetStartChar to tTargetEndChar of tTagData into tTargetValue
end if
end if
-- fix problem when control added by hand to html file and not by export from this project
-- will have no html id attribute, so need to supply one
if pTargetName is "id" then
if tTargetValue is empty then
-- need to create a unique id to use for name of future control
-- which hasn't been created yet, so can't use it's new livecode id
put the number of controls of this card into tNum
add 1 to tNum
put "control" && tNum into tTargetValue
end if
end if
if kReporter is "true" then put LF & "leaving fGetHtmlAttribute, tTargetValue to RETURN = " & tTargetValue & LF after msg -- development field
if kReporter is "true" then put LF & LF & "=!=!=!=!=!= LEAVE fGetHtmlAttribute =!=!=!=!=!=" after msg
return tTargetValue
end fGetHtmlAttribute
-----------------------------
function fGetHtmlEvents pTagType, pSkipChar, pHtmlFileData
-- uses function fGetHtmlAttribute
-- returns any html events and javascript functions they invoke
-- input param pSkipChar points to "<" at start of tag in pHtmlFileData
if kReporter is "true" then put LF & LF & "=*=*=*=*=*= ENTER fGetHtmlEvents =*=*=*=*=*=" after msg
put 0 into tCounter
repeat for each item tEvent in kEventList -- kEventList is a constant of this script
if tEvent is "value" and pTagType is "unlocked field" then
-- skip value for unlocked field so do not get additional value attributes on export after this import
-- since export takes field contents and writes them as value attribute
next repeat
end if
if tEvent is "value" and pTagType is "standard button" then
-- skip value for standard button so do not get additional value attributes on export after this import
next repeat
end if
put fGetHtmlAttribute(pSkipChar, pHtmlFileData, tEvent) into tEventCode
if tEventCode is not empty then
add 1 to tCounter
put tEvent into item 1 of line tCounter of tEventCodeLines
put tEventCode into item 2 of line tCounter of tEventCodeLines
end if
end repeat
if kReporter is "true" then put LF & "leaving fGetHtmlEvents, tEventCodeLines = " & LF & tEventCodeLines after msg
if kReporter is "true" then put LF & LF & "=*=*=*=*=*= LEAVE fGetHtmlEvents =*=*=*=*=*=" after msg
return tEventCodeLines
end fGetHtmlEvents
-----------------------------
function fSaveHtmlEvents pEventCodeLines, pControl_ID
-- SAVE ANY HTML EVENT CODE IN CUSTOM PROPS
-- naming convention for html events saved as LC custom props is, e.g., event_onchange
-- make sure same convention in both IMPORT and EXPORT script stacks
repeat for each line tLine in pEventCodeLines
put item 1 of tLine into tEventName
put item 2 of tLine into tEventCode
put "event_" before tEventName
set the tEventName of control id pControl_ID to tEventCode
end repeat
end fSaveHtmlEvents
-----------------------------
function fGetReporter tSkipChar, pHtmlFileData
put char tSkipChar-20 to tSkipChar+20 of pHtmlFileData into tReport
-- replace <> because some LC answer and text editors treat as HTML and/or colorize
replace "<" with "*" in tReport -- use one char so don't throw off count in report text
replace ">" with "*" in tReport -- use one char so don't throw off count in report text
put LF & "+/- 20 of (tSkipChar = " & tSkipChar & ") is: " after msg
put LF & "---||" & tReport & "||---" & LF after msg
end fGetReporter
-----------------------------
function fGetStripOuterSpace tText
-- used to strip junk from both ends of text in <p> tag
-- need to use compound conditions because can be in any order, e.g., space LF tab space
repeat while char 1 of tText is space OR char 1 of tText is LF OR char 1 of tText is tab
delete char 1 of tText
end repeat
repeat while the last char of tText is space OR the last char of tText is LF OR the last char of tText is tab
delete the last char of tText
end repeat
return tText
end fGetStripOuterSpace
-----------------------------
function fGetSetControlProps pID, pControlLongName, pCssFileData, tGrpLocList, pSpanFlag
-- returns true if css has a transform property
-- which will be the case for vertical sliders (scales, ranges)
-- xxx problems if "#" & tID mentioned in a comment in CSS file
put offset(space & "of",pControlLongName) into tMarkChar
put char 1 to tMarkChar-1 of pControlLongName into tControlName
-- tControlName is first words of long name of control before first "of"
-- for example, tControlName = button "radio 2"
-- the long name does not work, at least when control is inside a group
if kReporter is "true" then put LF & LF & "========== ENTER fGetSetControlProps =========" after msg
if kReporter is "true" then put LF & "fGetSetControlProps, tControlName = " & LF & tControlName & LF after msg
if kReporter is "true" then put LF & LF & "enter function fGetSetControlProps, pID = " & LF & pID & LF after msg
if kReporter is "true" then put LF & LF & "enter function fGetSetControlProps, tGrpLocList = " & LF & tGrpLocList & LF after msg
put empty into tCssData
if pCssFileData is not empty then
-- check complete CSS line matches because, e.g.,
-- may have "button_1" 1st in file and "button" 2nd in file
-- and don't want to find "button_1" with simple search for "button"
put 0 into tLineSkip
repeat
put lineoffset("#" & pID, pCssFileData, tLineSkip) into tLineNum
if tLineNum = 0 then exit repeat
add tLineNum to tLineSkip
put tLineSkip into tLineNum
put line tLineNum of pCssFileData into tLineDataOrig
put tLineDataOrig into tLineDataStripped
replace space with empty in tLineDataStripped
replace "{" with empty in tLineDataStripped
replace "#" with empty in tLineDataStripped
replace LF with empty in tLineDataStripped
if tLineDataStripped = pID then
-- got a hit, need char offset
put offset(tLineDataOrig, pCssFileData) into tStartChar
exit repeat
end if
end repeat
put offset("}",pCssFileData,tStartChar) into tEndChar
add tStartChar to tEndChar
put char tStartChar to tEndChar of pCssFileData into tCssData
if kReporter is "true" then
put LF & tCssData & LF after msg
end if
end if
put 0,0 into tTopLeft
put "false" into tTransformFlag
if tCssData is not empty then
-- assume top and bottom lines don't have data but the other lines do
set the itemDelimiter to colon
put "false" into flagLCthreeD
put "false" into flagLCshowBorder
repeat for each line n in tCssData
if n contains "#" then next repeat
if n contains "}" then exit repeat
if n contains "/*" then
put offset("/*",n) into tStart
put offset("*/",n) into tEnd
if tEnd <= tStart then
-- no */ in this line
put the number of characters of n into tEnd
else
add 1 to tEnd -- move to / of */
end if
delete char tStart to tEnd of n
end if
if n contains "*/" then
-- lines with /* taken care of above
-- so this line just has */
put offset("*/",n) into tEnd
add 1 to tEnd -- move to / of */
delete char 1 to tEnd of n
end if
put word 1 of item 1 of n into tProp -- so don't get spaces
put item 2 of n into tValue
put fGetStripOuterSpace(tValue) into tValue
-- watch out for a calc(), which I've used in earlier development for quick fix
-- EXAMPLE: :root {--shift: 50px;}
-- USED IN ELEMENT PROP: top: calc(var(--shift) + 700px);
if tValue contains "calc" then
put offset("+",tValue) into tPlusChar -- assume a space after plus
put offset("px",tValue) into tPXChar
put char tPlusChar + 2 to tPXChar -1 of tValue into tValue
-- see top of this file for constant value
add kCssTopShift to tValue
else
-- NEED TO DO THIS IF THERE IS NO CALC
delete the last char of tValue -- delete ;
replace "px" with empty in tValue -- if any, delete px
end if
-- -- NEED TO DO THIS IF THERE IS NO CALC
-- delete the last char of tValue -- delete ;
-- replace "px" with empty in tValue -- if any, delete px
-- only want to set font-size/textSize in _SPAN for radio buttons and checkboxes
if pSpanFlag is "true" then
if tProp is not "font-size" then
next repeat
end if
end if
switch tProp
case "position"
put tValue into tPosition
break
case "width"
put tValue into tWidth
break
case "height"
put tValue into tHeight
break
case "left"
set the itemDelimiter to comma
-- order in LC topLeft is left,top!
put tValue into item 1 of tTopLeft -- save, don't set topLeft yet
-- save, need to add container group left & setting height & width changes topLeft
set the itemDelimiter to colon
break
case "top"
set the itemDelimiter to comma
-- order in LC topLeft is left,top!
put tValue into item 2 of tTopLeft -- save, don't set topLeft yet
-- save, need to add container group left & setting height & width first changes topLeft
set the itemDelimiter to colon
break
case "font-size"
if tValue is a number then
subtract kTextFontExportAdd from tValue -- xxx better check if this is <p>
set the textSize of tControlName to tValue
end if
break
case "text-align"
set the textAlign of tControlName to tValue
break
case "opacity"
put 100*(1 - tValue) into ttemp
set the blendLevel of tControlName to ttemp
if tValue is a number and tValue > 0 then
set the opaque of tControlName to true
end if
break
case "visibility"
-- EXAMPLE: visibility: visible;
if kReporter is "true" then put LF & "VISIBILITY tValue = " & tValue & LF after msg
if tValue is "hidden" then
set the visible of tControlName to false
else
set the visible of tControlName to true
end if
break
case "border-style"
-- css border styles include: none, hidden, dotted, dashed, solid, double, groove, ridge, inset, outset
-- EXPORT has a checkbox to add CSS dotted when LC showBorder false
-- EXPORT otherwise saves LC showBorder true as CSS outset
-- EXPORT has special property LCshowBorder - see case below
if tValue is "none" or tValue is "hidden" then
set the showBorder of tControlName to false
else
set the showBorder of tControlName to true
end if
if tValue is "solid" then
set the threeD of tControlName to false
else
-- new for dotted frames around divs
-- but need to set threeD true for buttons elsewhere
set the threeD of tControlName to true
end if
break
case "border-width"
set the borderWidth of tControlName to tValue
break
case "background-color"
-- color setting of rgba used on export to handle LC opaque
if "rgba(" is in tValue then
-- EXAMPLE: background-color: rgba(102,255,255,0);
replace "rgba(" with empty in tValue
delete the last char of tValue -- delete ) where ; already deleted from tValue
-- itemDelimiter before this case is colon, not comma, need to save and reset below
put the itemDelimiter into tSavedItemDelimiter
set the itemDelimiter to comma
put the last item of tValue into tAlpha
delete the last item of tValue
-- original itemDelimiter before this case was not comma, need to reset to saved
set the itemDelimiter to tSavedItemDelimiter
set the backColor of tControlName to tValue
-- now handle tAlpha - set by this project to 0 (transparent) or 1 (opaque)
if tAlpha is 0 then
set the opaque of tControlName to false
else
-- should only get here with tAlpha = 1 when backColor of LC control was empty
-- and the opaque of LC control was true
set the opaque of tControlName to true
end if
else if "rgb(" is in tValue then
-- EXAMPLE: background-color: rgb(102,255,255);
-- should only get here if backColor of LC control not empty and opaque was true
replace "rgb(" with empty in tValue
delete the last char of tValue -- delete ) where ; already deleted from tValue
set the backColor of tControlName to tValue
set the opaque of tControlName to true
else
-- color value set some other way
-- can't handle yet
end if
break
case "transform"
-- used when rotate horizontal range to vertical in CSS
if kReporter is "true" then put LF & "SCROLLBAR TRANSFORM DETECTED" after msg
-- EXAMPLE ASSUMING ROTATION ONLY HERE, e.g., transform: rotate(90deg);
if tValue contains "rotate" then
-- only handle rotate transforms here
replace space with empty in tValue
replace semicolon with empty in tValue
replace "rotate(" with empty in tValue
-- replace "deg);" did not work, see separate replace semicolon above
replace "deg)" with empty in tValue
-- degree value should be left
put tValue into tTransformFlag
if kReporter is "true" then put LF & "in case transform, tTransformFlag = " & tTransformFlag after msg
end if
break
-- BELOW ARE SPECIAL PROPERTIES
-- ignored by CSS processor but used for better reversibility of export-import to this project
case "LCvScrollbar"
-- this is for vScrollbar property of scrolling groups and fields, not for scrollbar controls
-- special property added on export - not a standard CSS property
-- usually used for scrolling parent groups used in making long web pages
-- xxx for unknown reason, at least in LC 9(dp6), setting the vScrollbar property of a group
-- xxx in fGetSetControlProps changed in some unknown way the left value
-- xxx that was set in the topLeft of one of the groups inside the group with the vScrollbar
-- xxx saving the vScrollbar property value in fGetSetControlProps and then
-- xxx setting at the end of fMakeLiveCodeCard works
-- use oScrollbarList at end of function fMakeLiveCodeCard
put tControlName & "$" & tValue & LF after oScrollbarList -- need delimiter that does not appear in a file name
-- xxx set the vScrollbar of tControlName to tValue
break
case "LCthreeD"
if tValue is true then
set the threeD of tControlName to true
else
set the threeD of tControlName to false
end if
break
case "LCshowBorder"
if tValue is true then
set the showBorder of tControlName to true
else
set the showBorder of tControlName to false
end if
break
end switch
end repeat -- end repeat for each line n in tCssData
end if -- end if tCssData is not empty
-- itemDelimiter was set to colon inside IF structure immediately above, reset to default
set the itemDelimiter to comma
-- only want to set font-size/textSize in _SPAN for radio buttons and checkboxes
if pSpanFlag is "true" then exit fGetSetControlProps
if kReporter is "true" then put LF & "---||" & tGrpLocList & "||---" after msg
if kReporter is "true" then put LF & "tTopLeft (2 items) =" && tTopLeft after msg
if tGrpLocList is not empty then
put the last line of tGrpLocList into tLast
if kReporter is "true" then
put LF & "tLast (last line of tGrpLocList) = " & tLast after msg
end if
add item 1 of tLast to item 1 of tTopLeft
add item 2 of tLast to item 2 of tTopLeft
end if
if tTransformFlag = 90 OR tTransformFlag = 270 then
-- a vertical scrollbar
-- CSS/HTML range started out as horiz then transformed by rotation about center
if kReporter is "true" then
put LF & "in IF swapping width and height, tTransformFlag = " & tTransformFlag after msg
end if