@shijiu/jsview 2.0.1021 → 2.0.1073

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,9 +4,10 @@ const {
4
4
  StyleValue,
5
5
  StyleVariable
6
6
  } = require("./jsview-style-formator.cjs");
7
+ const Logger = require('@shijiu/jsview/tools/jsview-logger');
7
8
 
8
9
  class StyleChecker {
9
- static GetFormattedValue(propName, propValue) {
10
+ static GetFormattedValue(fileName, propName, propValue) {
10
11
  propValue = new StyleValue(propValue);
11
12
  if (StyleVariable.IsVariable(propValue)) {
12
13
  return propValue.get();
@@ -18,12 +19,12 @@ class StyleChecker {
18
19
  case StyleName.Layout.Left:
19
20
  case StyleName.Layout.Top:
20
21
  case StyleName.Layout.Width:
21
- formattedValue = StyleChecker.#GetLayoutValue(propName, propValue);
22
+ formattedValue = StyleChecker.#GetLayoutValue(fileName, propName, propValue);
22
23
  break;
23
24
  case StyleName.Background.BackgroundColor:
24
25
  case StyleName.Background.BackgroundImage:
25
26
  case StyleName.Background.BorderRadius:
26
- formattedValue = StyleChecker.#GetBackgroundValue(propName, propValue);
27
+ formattedValue = StyleChecker.#GetBackgroundValue(fileName, propName, propValue);
27
28
  break;
28
29
  case StyleName.Effect.BackfaceVisibility:
29
30
  case StyleName.Effect.BorderImage:
@@ -38,7 +39,7 @@ class StyleChecker {
38
39
  case StyleName.Effect.PerspectiveOrigin:
39
40
  case StyleName.Effect.Visibility:
40
41
  case StyleName.Effect.ZIndex:
41
- formattedValue = StyleChecker.#GetEffectValue(propName, propValue);
42
+ formattedValue = StyleChecker.#GetEffectValue(fileName, propName, propValue);
42
43
  break;
43
44
  case StyleName.Text.Color:
44
45
  case StyleName.Text.FontFamily:
@@ -55,11 +56,11 @@ class StyleChecker {
55
56
  case StyleName.Text.WebkitTextStroke:
56
57
  case StyleName.Text.WhiteSpace:
57
58
  case StyleName.Text.WordWrap:
58
- formattedValue = StyleChecker.#GetTextValue(propName, propValue);
59
+ formattedValue = StyleChecker.#GetTextValue(fileName, propName, propValue);
59
60
  break;
60
61
  case StyleName.Motion.Animation:
61
62
  case StyleName.Motion.Transition:
62
- formattedValue = StyleChecker.#GetMotionValue(propName, propValue);
63
+ formattedValue = StyleChecker.#GetMotionValue(fileName, propName, propValue);
63
64
  break;
64
65
  default:
65
66
  // 返回未处理的值
@@ -70,7 +71,7 @@ class StyleChecker {
70
71
  return formattedValue;
71
72
  }
72
73
 
73
- static GetFormattedKeyframe(propName, propValue) {
74
+ static GetFormattedKeyframe(fileName, propName, propValue) {
74
75
  let removedPxSuffix = false;
75
76
 
76
77
  // 去掉translate3d中的px单位
@@ -96,98 +97,95 @@ class StyleChecker {
96
97
  }
97
98
 
98
99
  if (removedPxSuffix) {
99
- const msg = `JsView Info:`
100
- + ` Auto optimize style keyframes ${propName},`
100
+ const msg = ` Auto optimize style keyframes ${propName},`
101
101
  + ` remove unnecessary 'px' suffix.`;
102
- console.info(msg);
102
+ Logger.Info(Logger.GetFileTag(fileName), msg);
103
103
  }
104
104
  const value = valueArray.join('translate3d');
105
105
 
106
106
  return value;
107
107
  }
108
108
 
109
- static #GetLayoutValue(propName, propValue) {
110
- const formattedValue = StyleChecker.#ConvertToInt32(propName, propValue);
109
+ static #GetLayoutValue(fileName, propName, propValue) {
110
+ const formattedValue = StyleChecker.#ConvertToInt32(fileName, propName, propValue);
111
111
 
112
112
  return formattedValue;
113
113
  }
114
114
 
115
- static #GetBackgroundValue(propName, propValue) {
115
+ static #GetBackgroundValue(fileName, propName, propValue) {
116
116
  let formattedValue = null;
117
117
  switch (propName) {
118
118
  case StyleName.Background.BorderRadius:
119
- formattedValue = StyleFormator.ConvertToString(propValue);
119
+ formattedValue = StyleFormator.ConvertToString(propName, propValue);
120
120
  if (formattedValue.includes?.('px')) {
121
121
  formattedValue = formattedValue.replace?.('px', ''); // 去掉px
122
122
 
123
- const msg = `JsView Info:`
124
- + ` Auto optimize style ${propName},`
123
+ const msg = ` Auto optimize style ${propName},`
125
124
  + ` remove unnecessary 'px'.`;
126
- console.info(msg);
125
+ Logger.Info(Logger.GetFileTag(fileName), msg);
127
126
  }
128
127
  break;
129
128
  default:
130
- formattedValue = StyleFormator.ConvertToString(propValue);
129
+ formattedValue = StyleFormator.ConvertToString(propName, propValue);
131
130
  break;
132
131
  }
133
132
 
134
133
  return formattedValue;
135
134
  }
136
135
 
137
- static #GetEffectValue(propName, propValue) {
136
+ static #GetEffectValue(fileName, propName, propValue) {
138
137
  let formattedValue = null;
139
138
  switch (propName) {
140
139
  case StyleName.Effect.Opacity:
141
- formattedValue = StyleFormator.ConvertToFloat(propValue);
140
+ formattedValue = StyleFormator.ConvertToFloat(propName, propValue);
142
141
  break;
143
142
  case StyleName.Effect.ZIndex:
144
- formattedValue = StyleFormator.ConvertToInt32(propValue);
143
+ formattedValue = StyleFormator.ConvertToInt32(propName, propValue);
145
144
  break;
146
145
  default:
147
- formattedValue = StyleFormator.ConvertToString(propValue);
146
+ formattedValue = StyleFormator.ConvertToString(propName, propValue);
148
147
  break;
149
148
  }
150
149
 
151
150
  return formattedValue;
152
151
  }
153
152
 
154
- static #GetTextValue(propName, propValue) {
153
+ static #GetTextValue(fileName, propName, propValue) {
155
154
  let formattedValue = null;
156
155
  switch (propName) {
157
156
  case StyleName.Text.FontSize:
158
157
  case StyleName.Text.LineHeight:
159
- formattedValue = StyleChecker.#ConvertToInt32(propName, propValue);
158
+ formattedValue = StyleChecker.#ConvertToInt32(fileName, propName, propValue);
160
159
  break;
161
160
  default:
162
- formattedValue = StyleFormator.ConvertToString(propValue);
161
+ formattedValue = StyleFormator.ConvertToString(propName, propValue);
163
162
  break;
164
163
  }
165
164
 
166
165
  return formattedValue;
167
166
  }
168
167
 
169
- static #GetMotionValue(propName, propValue) {
168
+ static #GetMotionValue(fileName, propName, propValue) {
170
169
  // 需要留到执行时处理
171
- const formattedValue = StyleFormator.ConvertToString(propValue);
170
+ const formattedValue = StyleFormator.ConvertToString(propName, propValue);
172
171
 
173
172
  return formattedValue;
174
173
  }
175
174
 
176
- static #ConvertToInt32(propName, propValue) {
175
+ static #ConvertToInt32(fileName, propName, propValue) {
177
176
  if (propValue.is(StyleValue.DataType.String)) {
178
177
  const strValue = propValue.get();
179
178
  StyleFormator.StringTrim(strValue);
180
179
  if (StyleFormator.StringEndsWith(strValue, "px")) {
181
180
  const fmtValue = StyleFormator.StringToInt32(strValue);
182
- const msg = `JsView Info:`
183
- + ` Auto optimize style propery ${propName},`
181
+ const msg = ` Auto optimize style propery ${propName},`
184
182
  + ` convert value from string ${strValue} to number ${fmtValue}.`;
185
- console.info(msg);
183
+ Logger.Info(Logger.GetFileTag(fileName), msg);
186
184
  return fmtValue;
187
185
  }
188
186
  }
189
187
 
190
- return StyleFormator.ConvertToInt32(propValue);
188
+ return StyleFormator.ConvertToInt32(propName, propValue);
191
189
  }
192
190
 
193
191
  }
@@ -370,6 +370,26 @@ class StyleValue {
370
370
  source = "";
371
371
  slice = null;
372
372
  };
373
+ static BackgroundImageImpl = class extends StyleValue.Base {
374
+ constructor(rawValue) {
375
+ super(rawValue);
376
+ }
377
+ type = 0;
378
+ static eType = {
379
+ UNKNOWN: 0,
380
+ LINEAR_GRADIENT: 1,
381
+ URL_PATH: 2,
382
+ };
383
+ static LinearGradient = class {
384
+ fromX = 0;
385
+ fromY = 0;
386
+ toX = 0;
387
+ toY = 0;
388
+ stops = []; // std::vector<ForgeFront::LinearGradientTexture::StopPoint>
389
+ };
390
+ linearGradient; // LinearGradient
391
+ urlPath = ""; // Image url type
392
+ };
373
393
  static DataType = class {
374
394
  static Null = 0;
375
395
  static Int32 = 1;
@@ -382,6 +402,7 @@ class StyleValue {
382
402
  static WebkitTextStroke = 8;
383
403
  static Transition = 9;
384
404
  static BorderImage = 10;
405
+ static BackgroundImage = 11;
385
406
  };
386
407
  static InvalidInt32 = Number.MIN_VALUE;
387
408
  static InvalidFloat = Number.NaN;
@@ -435,6 +456,48 @@ class StyleValue {
435
456
  this.data.index = index;
436
457
  this.data.value = value;
437
458
  }
459
+ toString() {
460
+ let result = null;
461
+ switch (this.data.index) {
462
+ case StyleValue.DataType.Null:
463
+ return "";
464
+ case StyleValue.DataType.Int32:
465
+ return String(this.get());
466
+ case StyleValue.DataType.Float:
467
+ return String(this.get());
468
+ case StyleValue.DataType.String:
469
+ result = this.get();
470
+ break;
471
+ case StyleValue.DataType.Animation:
472
+ result = this.get().rawValue;
473
+ break;
474
+ case StyleValue.DataType.Corner:
475
+ result = this.get().rawValue;
476
+ break;
477
+ case StyleValue.DataType.Rect:
478
+ result = this.get().rawValue;
479
+ break;
480
+ case StyleValue.DataType.TextShadow:
481
+ result = this.get().rawValue;
482
+ break;
483
+ case StyleValue.DataType.WebkitTextStroke:
484
+ result = this.get().rawValue;
485
+ break;
486
+ case StyleValue.DataType.Transition:
487
+ result = this.get().rawValue;
488
+ break;
489
+ case StyleValue.DataType.BorderImage:
490
+ result = this.get().rawValue;
491
+ break;
492
+ case StyleValue.DataType.BackgroundImage:
493
+ result = this.get().rawValue;
494
+ break;
495
+ default:
496
+ console.error("Failed to do StyleValue.toString()");
497
+ break;
498
+ }
499
+ return result ?? "";
500
+ }
438
501
  is(type) {
439
502
  return this.data.index == type;
440
503
  }
@@ -486,6 +549,7 @@ class StyleVariable {
486
549
  constructor() { throw new Error("new StyleVariable() is forbidden."); }
487
550
  }
488
551
 
552
+ let ForgeFront = Forge;
489
553
  class StyleFormator {
490
554
  /*** public ***/
491
555
  static StringToInt32(value) {
@@ -505,25 +569,119 @@ class StyleFormator {
505
569
  static StringEndsWith(value, ending) {
506
570
  return value.endsWith(ending);
507
571
  }
508
- static StringSplit(from, delimiter = " ") {
572
+ static StringSplit(from, delimiter = " ", startIdx = 0, endIdx = 0, doTrim = false) {
509
573
  if (!from) {
510
574
  from = "";
511
575
  }
512
- let arrays = from.trim().split(delimiter);
513
- if (delimiter !== ' ') {
514
- return arrays;
576
+ // apply startIdx/endIdx
577
+ if (endIdx == 0) {
578
+ // 0代表全字符
579
+ endIdx = from.length - 1;
515
580
  }
516
- //去除多个空格的条件下的影响
581
+ from = from.substring(startIdx, endIdx + 1);
582
+ let arrays = from.trim().split(delimiter);
583
+ // 去除多个空格的条件下的影响
584
+ // 结果string进行trim
517
585
  let ret = [];
518
586
  for (let item of arrays) {
519
587
  if (!item) {
520
588
  continue;
521
589
  }
590
+ if (doTrim) {
591
+ item = item.trim();
592
+ if (item.length == 0) {
593
+ continue;
594
+ }
595
+ }
522
596
  ret.push(item);
523
597
  }
524
598
  return ret;
525
599
  }
526
- static ConvertToInt32(value) {
600
+ static MergeBrackets(input, connector = null) {
601
+ let output = [];
602
+ let packString = "";
603
+ let notMergedPrevious = null;
604
+ let mergedString = null;
605
+ let bracket_depth = 0;
606
+ let useSstream = false;
607
+ for (let str of input) {
608
+ let start_pos = 0;
609
+ while (start_pos < str.length) {
610
+ if (bracket_depth > 0) {
611
+ let end_pos = str.indexOf(")", start_pos);
612
+ let next_bracket_pos = str.indexOf("(", start_pos);
613
+ if (next_bracket_pos != -1 && (end_pos == -1 || next_bracket_pos < end_pos)) {
614
+ bracket_depth++;
615
+ start_pos = next_bracket_pos + 1;
616
+ }
617
+ else {
618
+ // 到目前为止没有深度增加
619
+ // 可能1: 有新正括号,但晚于反括号
620
+ // 可能2: 无新正括号,有反括号
621
+ // 可能3: 无新正括号,也无反括号
622
+ if (end_pos >= 0) {
623
+ // 上诉的可能1或可能2
624
+ bracket_depth--;
625
+ // 以反括号为节点继续后查
626
+ // 在新正括号在反括号之后的场景放到下一次循环来处理
627
+ start_pos = end_pos + 1;
628
+ }
629
+ else {
630
+ // 上诉的可能3
631
+ // 不需要后续的检查,保存depth状态,跳到下一个内容
632
+ break;
633
+ }
634
+ }
635
+ }
636
+ else {
637
+ let bracket_pos = str.indexOf("(", start_pos);
638
+ if (bracket_pos == -1) {
639
+ break;
640
+ }
641
+ bracket_depth++;
642
+ start_pos = bracket_pos + 1;
643
+ }
644
+ }
645
+ // 执行本次合并
646
+ if (useSstream) {
647
+ // 第三个及以上合并内容
648
+ if (connector) {
649
+ packString += connector;
650
+ }
651
+ packString += str;
652
+ }
653
+ else if (notMergedPrevious != null) {
654
+ // 第二个合并内容
655
+ packString += notMergedPrevious;
656
+ if (connector) {
657
+ packString += connector;
658
+ }
659
+ packString += str;
660
+ notMergedPrevious = null;
661
+ useSstream = true;
662
+ }
663
+ else {
664
+ // 第一个合并内容
665
+ notMergedPrevious = str; // 记录previousString
666
+ }
667
+ if (bracket_depth == 0) {
668
+ // 收尾
669
+ if (useSstream) {
670
+ mergedString = packString;
671
+ packString = "";
672
+ }
673
+ else {
674
+ mergedString = str;
675
+ }
676
+ output.push(mergedString);
677
+ // 重置所有状态
678
+ notMergedPrevious = null;
679
+ useSstream = false;
680
+ }
681
+ }
682
+ return output;
683
+ }
684
+ static ConvertToInt32(name, value) {
527
685
  if (value.is(StyleValue.DataType.Null)) {
528
686
  return 0;
529
687
  }
@@ -549,10 +707,14 @@ class StyleFormator {
549
707
  else if (value.is(StyleValue.DataType.Float)) {
550
708
  return value.get();
551
709
  }
552
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidInt32);
710
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidInt32, [
711
+ 'Failed to convert style ',
712
+ name, '=', value.toString(),
713
+ ', value type is supported.'
714
+ ]);
553
715
  return StyleValue.InvalidInt32;
554
716
  }
555
- static ConvertToFloat(value) {
717
+ static ConvertToFloat(name, value) {
556
718
  if (value.is(StyleValue.DataType.Null)) {
557
719
  return StyleValue.InvalidFloat;
558
720
  }
@@ -565,15 +727,23 @@ class StyleFormator {
565
727
  else if (value.is(StyleValue.DataType.Float)) {
566
728
  return value.get();
567
729
  }
568
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidFloat);
730
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidFloat, [
731
+ "Failed to convert style ",
732
+ name, '=', value.toString(),
733
+ ", value type is supported."
734
+ ]);
569
735
  return StyleValue.InvalidFloat;
570
736
  }
571
- static ConvertToString(value, upperCase = false) {
737
+ static ConvertToString(name, value, upperCase = false) {
572
738
  if (value.is(StyleValue.DataType.Null)) {
573
739
  return StyleValue.InvalidPointer;
574
740
  }
575
741
  if (value.is(StyleValue.DataType.String) == false) {
576
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer);
742
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer, [
743
+ "Failed to convert style ",
744
+ name, '=', value.toString(),
745
+ ", type is not string."
746
+ ]);
577
747
  }
578
748
  let propValue = value.get();
579
749
  if (propValue == null || propValue.length <= 0) {
@@ -584,7 +754,7 @@ class StyleFormator {
584
754
  }
585
755
  return propValue;
586
756
  }
587
- static ConvertToCorner(value) {
757
+ static ConvertToCorner(name, value) {
588
758
  if (value.is(StyleValue.DataType.Null)) {
589
759
  return StyleValue.InvalidPointer;
590
760
  }
@@ -611,16 +781,20 @@ class StyleFormator {
611
781
  corner.bottomLeft = (propValueSize > 3 ? parseInt(propValueArray[3]) : corner.bottomRight);
612
782
  }
613
783
  else {
614
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer);
784
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer, [
785
+ "Failed to convert style ",
786
+ name, '=', value.toString(),
787
+ ", type is not number or string."
788
+ ]);
615
789
  }
616
790
  return corner;
617
791
  }
618
- static ConvertToRect(value) {
792
+ static ConvertToRect(name, value) {
619
793
  if (value.is(StyleValue.DataType.Null)) {
620
794
  return StyleValue.InvalidPointer;
621
795
  }
622
796
  if (value.is(StyleValue.DataType.String) == false) {
623
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer);
797
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer, ['Failed to convert style ' + name + '=' + value + ', value type is not string.']);
624
798
  }
625
799
  const propValue = value.get();
626
800
  if (propValue == null || propValue.length <= 0) {
@@ -635,12 +809,16 @@ class StyleFormator {
635
809
  rect.left = (propValueSize > 3 ? parseInt(propValueArray[3]) : rect.right);
636
810
  return rect;
637
811
  }
638
- static ConvertToAnimation(value, compare = null) {
812
+ static ConvertToAnimation(name, value, compare = null) {
639
813
  if (value.is(StyleValue.DataType.Null)) {
640
814
  return StyleValue.InvalidPointer;
641
815
  }
642
816
  if (value.is(StyleValue.DataType.String) == false) {
643
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer);
817
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer, [
818
+ "Failed to convert style ",
819
+ name, '=', value.toString(),
820
+ ", type is not string."
821
+ ]);
644
822
  }
645
823
  const propValue = value.get();
646
824
  if (propValue == null || propValue.length <= 0) {
@@ -654,12 +832,16 @@ class StyleFormator {
654
832
  const anim = StyleFormator.ParseToAnimation(propValue);
655
833
  return anim;
656
834
  }
657
- static ConvertToTransition(value, compare = null) {
835
+ static ConvertToTransition(name, value, compare = null) {
658
836
  if (value.is(StyleValue.DataType.Null)) {
659
837
  return StyleValue.InvalidPointer;
660
838
  }
661
839
  if (value.is(StyleValue.DataType.String) == false) {
662
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer);
840
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer, [
841
+ "Failed to convert style ",
842
+ name, '=', value.toString(),
843
+ ", type is not string."
844
+ ]);
663
845
  }
664
846
  const propValue = value.get();
665
847
  if (propValue == null || propValue.length <= 0) {
@@ -696,7 +878,7 @@ class StyleFormator {
696
878
  // console.warn("StyleFormator.ConvertToTransition() arrays=" + JSON.stringify(arrays));
697
879
  const transition = new StyleValue.TransitionImpl(propValue);
698
880
  for (const item of arrays) {
699
- const ret = StyleFormator.ConvertToAnimation(new StyleValue(item));
881
+ const ret = StyleFormator.ConvertToAnimation(name, new StyleValue(item));
700
882
  if (ret == null) {
701
883
  continue;
702
884
  }
@@ -710,12 +892,16 @@ class StyleFormator {
710
892
  }
711
893
  return transition;
712
894
  }
713
- static ConvertToTextShadow(value) {
895
+ static ConvertToTextShadow(name, value) {
714
896
  if (value.is(StyleValue.DataType.Null)) {
715
897
  return StyleValue.InvalidPointer;
716
898
  }
717
899
  if (value.is(StyleValue.DataType.String) == false) {
718
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer);
900
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer, [
901
+ "Failed to convert style ",
902
+ name, '=', value.toString(),
903
+ ", type is not string."
904
+ ]);
719
905
  }
720
906
  const propValue = value.get();
721
907
  if (propValue == null || propValue.length <= 0) {
@@ -744,12 +930,16 @@ class StyleFormator {
744
930
  }
745
931
  return textShadow;
746
932
  }
747
- static ConvertToWebkitTextStroke(value) {
933
+ static ConvertToWebkitTextStroke(name, value) {
748
934
  if (value.is(StyleValue.DataType.Null)) {
749
935
  return StyleValue.InvalidPointer;
750
936
  }
751
937
  if (value.is(StyleValue.DataType.String) == false) {
752
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer);
938
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer, [
939
+ "Failed to convert style ",
940
+ name, '=', value.toString(),
941
+ ", type is not string."
942
+ ]);
753
943
  }
754
944
  const propValue = value.get();
755
945
  if (propValue == null || propValue.length <= 0) {
@@ -765,12 +955,16 @@ class StyleFormator {
765
955
  }
766
956
  return webkitTextStroke;
767
957
  }
768
- static ConvertToBorderImage(value) {
958
+ static ConvertToBorderImage(name, value) {
769
959
  if (value.is(StyleValue.DataType.Null)) {
770
960
  return StyleValue.InvalidPointer;
771
961
  }
772
962
  if (value.is(StyleValue.DataType.String) == false) {
773
- CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer);
963
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer, [
964
+ "Failed to convert style ",
965
+ name, '=', value.toString(),
966
+ ", type is not string."
967
+ ]);
774
968
  }
775
969
  const propValue = value.get();
776
970
  if (propValue == null || propValue.length <= 0) {
@@ -783,10 +977,103 @@ class StyleFormator {
783
977
  borderImage.source = propValueArray[0];
784
978
  }
785
979
  if (propValueSize > 1) {
786
- borderImage.slice = StyleFormator.ConvertToRect(new StyleValue(propValueArray[1]));
980
+ borderImage.slice = StyleFormator.ConvertToRect(name, new StyleValue(propValueArray[1]));
787
981
  }
788
982
  return borderImage;
789
983
  }
984
+ static ConvertToBackgroundImage(name, value) {
985
+ if (value.is(StyleValue.DataType.Null)) {
986
+ return StyleValue.InvalidPointer;
987
+ }
988
+ if (value.is(StyleValue.DataType.String) == false) {
989
+ CHECK_AND_RETVAL(ErrCode.InvalidArgument, StyleValue.InvalidPointer, [
990
+ "Failed to convert style ",
991
+ name, '=', value.toString(),
992
+ ", type is not string."
993
+ ]);
994
+ }
995
+ let propValue = value.get();
996
+ if (propValue == null || propValue.length <= 0) {
997
+ return StyleValue.InvalidPointer;
998
+ }
999
+ const backgroundImage = new StyleValue.BackgroundImageImpl(propValue);
1000
+ const gradientPrefix = "linear-gradient(";
1001
+ if (propValue.indexOf(gradientPrefix) == 0) {
1002
+ propValue = StyleFormator.StringTrim(propValue);
1003
+ backgroundImage.type = StyleValue.BackgroundImageImpl.eType.LINEAR_GRADIENT;
1004
+ backgroundImage.linearGradient = new StyleValue.BackgroundImageImpl.LinearGradient();
1005
+ backgroundImage.urlPath = propValue;
1006
+ let propValueArray = StyleFormator.StringSplit(propValue, ",", gradientPrefix.length, propValue.length - 2 /* 去掉最后的括号 */);
1007
+ propValueArray = StyleFormator.MergeBrackets(propValueArray, ",");
1008
+ let propValueSize = propValueArray.length;
1009
+ if (propValueSize > 0) {
1010
+ // check direction
1011
+ let firstDefine = propValueArray[0];
1012
+ if (firstDefine.indexOf("to ") != -1) {
1013
+ propValueArray.splice(0, 1); // 删除头结点
1014
+ let stopsCount = propValueArray.length;
1015
+ if (firstDefine.indexOf("left") != -1) {
1016
+ // 向左
1017
+ backgroundImage.linearGradient.fromX = stopsCount + 1;
1018
+ backgroundImage.linearGradient.toX = 0;
1019
+ }
1020
+ else if (firstDefine.indexOf("right") != -1) {
1021
+ // 向右
1022
+ backgroundImage.linearGradient.fromX = 0;
1023
+ backgroundImage.linearGradient.toX = stopsCount + 1;
1024
+ }
1025
+ else {
1026
+ // X上无方向
1027
+ backgroundImage.linearGradient.fromX = 0;
1028
+ backgroundImage.linearGradient.toX = 0;
1029
+ }
1030
+ if (firstDefine.indexOf("top") != -1) {
1031
+ // 向上
1032
+ backgroundImage.linearGradient.fromY = stopsCount + 1;
1033
+ backgroundImage.linearGradient.toY = 0;
1034
+ }
1035
+ else if (firstDefine.indexOf("bottom") != -1) {
1036
+ // 向下
1037
+ backgroundImage.linearGradient.fromY = 0;
1038
+ backgroundImage.linearGradient.toY = stopsCount + 1;
1039
+ }
1040
+ else {
1041
+ // Y上无方向
1042
+ backgroundImage.linearGradient.fromY = 0;
1043
+ backgroundImage.linearGradient.toY = 0;
1044
+ }
1045
+ }
1046
+ else {
1047
+ // 默认从上到下
1048
+ backgroundImage.linearGradient.fromX = 0;
1049
+ backgroundImage.linearGradient.toX = 0;
1050
+ backgroundImage.linearGradient.fromY = 0;
1051
+ backgroundImage.linearGradient.toY = 2;
1052
+ }
1053
+ }
1054
+ if (propValueSize < 2) {
1055
+ // stops 颜色值不足,至少应该有起始和结束两种颜色
1056
+ console.error(`linear gradient format error: str=${value}`);
1057
+ return null;
1058
+ }
1059
+ let stepGap = 1 / propValueArray.length;
1060
+ let stopsCount = propValueArray.length;
1061
+ for (let i = 0; i < stopsCount; i++) {
1062
+ let stopColor = propValueArray[i];
1063
+ stopColor = StyleFormator.StringTrim(stopColor);
1064
+ let stopPoint = new ForgeFront.LinearGradientTexture.StopPoint();
1065
+ stopPoint.color = stopColor;
1066
+ stopPoint.stopPosition = (i != stopsCount - 1 ? i * stepGap : 1);
1067
+ backgroundImage.linearGradient.stops.push(stopPoint);
1068
+ }
1069
+ }
1070
+ else {
1071
+ // Url path形式
1072
+ backgroundImage.type = StyleValue.BackgroundImageImpl.eType.URL_PATH;
1073
+ backgroundImage.urlPath = propValue;
1074
+ }
1075
+ return backgroundImage;
1076
+ }
790
1077
  static ParseToAnimation(value) {
791
1078
  const trimmed = StyleFormator.StringTrim(value);
792
1079
  let arrays = [];
@@ -797,7 +1084,7 @@ class StyleFormator {
797
1084
  const bezierArray = StyleFormator.StringSplit(trimmed, bezierStr);
798
1085
  for (const item of bezierArray) {
799
1086
  const subArrays = StyleFormator.StringSplit(item);
800
- arrays.concat(subArrays);
1087
+ arrays = [...arrays, ...subArrays];
801
1088
  }
802
1089
  arrays.push(bezierStr);
803
1090
  }