1 | import { Property, InheritedProperty, clearInheritedProperties, propagateInheritableProperties, propagateInheritableCssProperties, initNativeView } from '../properties';
|
2 | import { CSSUtils } from '../../../css/system-classes';
|
3 | import { Source } from '../../../utils/debug';
|
4 | import { Binding } from '../bindable';
|
5 | import { Trace } from '../../../trace';
|
6 | import { Observable, WrappedValue } from '../../../data/observable';
|
7 | import { Style } from '../../styling/style';
|
8 | import { paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty } from '../../styling/style-properties';
|
9 |
|
10 | import { getClass } from '../../../utils/types';
|
11 | import { profile } from '../../../profiling';
|
12 | import * as ssm from '../../styling/style-scope';
|
13 | let domNodeModule;
|
14 | function ensuredomNodeModule() {
|
15 | if (!domNodeModule) {
|
16 | domNodeModule = require('../../../debugger/dom-node');
|
17 | }
|
18 | }
|
19 | let styleScopeModule;
|
20 | function ensureStyleScopeModule() {
|
21 | if (!styleScopeModule) {
|
22 | styleScopeModule = require('../../styling/style-scope');
|
23 | }
|
24 | }
|
25 | const defaultBindingSource = {};
|
26 | export function getAncestor(view, criterion) {
|
27 | let matcher = null;
|
28 | if (typeof criterion === 'string') {
|
29 | matcher = (view) => view.typeName === criterion;
|
30 | }
|
31 | else {
|
32 | matcher = (view) => view instanceof criterion;
|
33 | }
|
34 | for (let parent = view.parent; parent != null; parent = parent.parent) {
|
35 | if (matcher(parent)) {
|
36 | return parent;
|
37 | }
|
38 | }
|
39 | return null;
|
40 | }
|
41 | export function getViewById(view, id) {
|
42 | if (!view) {
|
43 | return undefined;
|
44 | }
|
45 | if (view.id === id) {
|
46 | return view;
|
47 | }
|
48 | let retVal;
|
49 | const descendantsCallback = function (child) {
|
50 | if (child.id === id) {
|
51 | retVal = child;
|
52 |
|
53 | return false;
|
54 | }
|
55 | return true;
|
56 | };
|
57 | eachDescendant(view, descendantsCallback);
|
58 | return retVal;
|
59 | }
|
60 | export function getViewByDomId(view, domId) {
|
61 | if (!view) {
|
62 | return undefined;
|
63 | }
|
64 | if (view._domId === domId) {
|
65 | return view;
|
66 | }
|
67 | let retVal;
|
68 | const descendantsCallback = function (child) {
|
69 | if (view._domId === domId) {
|
70 | retVal = child;
|
71 |
|
72 | return false;
|
73 | }
|
74 | return true;
|
75 | };
|
76 | eachDescendant(view, descendantsCallback);
|
77 | return retVal;
|
78 | }
|
79 | export function eachDescendant(view, callback) {
|
80 | if (!callback || !view) {
|
81 | return;
|
82 | }
|
83 | let continueIteration;
|
84 | const localCallback = function (child) {
|
85 | continueIteration = callback(child);
|
86 | if (continueIteration) {
|
87 | child.eachChild(localCallback);
|
88 | }
|
89 | return continueIteration;
|
90 | };
|
91 | view.eachChild(localCallback);
|
92 | }
|
93 | let viewIdCounter = 1;
|
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 | var Flags;
|
126 | (function (Flags) {
|
127 | Flags["superOnLoadedCalled"] = "Loaded";
|
128 | Flags["superOnUnloadedCalled"] = "Unloaded";
|
129 | })(Flags || (Flags = {}));
|
130 | var SuspendType;
|
131 | (function (SuspendType) {
|
132 | SuspendType[SuspendType["Incremental"] = 0] = "Incremental";
|
133 | SuspendType[SuspendType["Loaded"] = 1048576] = "Loaded";
|
134 | SuspendType[SuspendType["NativeView"] = 2097152] = "NativeView";
|
135 | SuspendType[SuspendType["UISetup"] = 4194304] = "UISetup";
|
136 | SuspendType[SuspendType["IncrementalCountMask"] = -7340033] = "IncrementalCountMask";
|
137 | })(SuspendType || (SuspendType = {}));
|
138 | (function (SuspendType) {
|
139 | function toString(type) {
|
140 | return (type ? 'suspended' : 'resumed') + '(' + 'Incremental: ' + (type & SuspendType.IncrementalCountMask) + ', ' + 'Loaded: ' + !(type & SuspendType.Loaded) + ', ' + 'NativeView: ' + !(type & SuspendType.NativeView) + ', ' + 'UISetup: ' + !(type & SuspendType.UISetup) + ')';
|
141 | }
|
142 | SuspendType.toString = toString;
|
143 | })(SuspendType || (SuspendType = {}));
|
144 | export class ViewBase extends Observable {
|
145 | constructor() {
|
146 | super();
|
147 | this._onLoadedCalled = false;
|
148 | this._onUnloadedCalled = false;
|
149 | this._cssState = new ssm.CssState(new WeakRef(this));
|
150 | this.pseudoClassAliases = {
|
151 | highlighted: ['active', 'pressed'],
|
152 | };
|
153 | this.cssClasses = new Set();
|
154 | this.cssPseudoClasses = new Set();
|
155 | this._domId = viewIdCounter++;
|
156 | this._style = new Style(new WeakRef(this));
|
157 | this.notify({ eventName: ViewBase.createdEvent, type: this.constructor.name, object: this });
|
158 | }
|
159 |
|
160 | get parentNode() {
|
161 | return this._templateParent || this.parent;
|
162 | }
|
163 | set parentNode(node) {
|
164 | this._templateParent = node;
|
165 | }
|
166 | get nativeView() {
|
167 |
|
168 | return this.nativeViewProtected;
|
169 | }
|
170 | set nativeView(value) {
|
171 | this.setNativeView(value);
|
172 | }
|
173 |
|
174 | get typeName() {
|
175 | return getClass(this);
|
176 | }
|
177 | get style() {
|
178 | return this._style;
|
179 | }
|
180 | set style(inlineStyle /* | string */) {
|
181 | if (typeof inlineStyle === 'string') {
|
182 | this.setInlineStyle(inlineStyle);
|
183 | }
|
184 | else {
|
185 | throw new Error('View.style property is read-only.');
|
186 | }
|
187 | }
|
188 | get android() {
|
189 |
|
190 | return this._androidView;
|
191 | }
|
192 | get ios() {
|
193 |
|
194 | return this._iosView;
|
195 | }
|
196 | get isLoaded() {
|
197 | return this._isLoaded;
|
198 | }
|
199 | get ['class']() {
|
200 | return this.className;
|
201 | }
|
202 | set ['class'](v) {
|
203 | this.className = v;
|
204 | }
|
205 | getViewById(id) {
|
206 | return getViewById(this, id);
|
207 | }
|
208 | getViewByDomId(domId) {
|
209 | return getViewByDomId(this, domId);
|
210 | }
|
211 | get page() {
|
212 | if (this.parent) {
|
213 | return this.parent.page;
|
214 | }
|
215 | return null;
|
216 | }
|
217 | ensureDomNode() {
|
218 | if (!this.domNode) {
|
219 | ensuredomNodeModule();
|
220 | this.domNode = new domNodeModule.DOMNode(this);
|
221 | }
|
222 | }
|
223 |
|
224 |
|
225 | set(name, value) {
|
226 | this[name] = WrappedValue.unwrap(value);
|
227 | }
|
228 | onLoaded() {
|
229 | this.setFlag(Flags.superOnLoadedCalled, true);
|
230 | if (this._isLoaded) {
|
231 | return;
|
232 | }
|
233 | this._isLoaded = true;
|
234 | this._cssState.onLoaded();
|
235 | this._resumeNativeUpdates(SuspendType.Loaded);
|
236 | this.eachChild((child) => {
|
237 | this.loadView(child);
|
238 | return true;
|
239 | });
|
240 | this._emit('loaded');
|
241 | }
|
242 | onUnloaded() {
|
243 | this.setFlag(Flags.superOnUnloadedCalled, true);
|
244 | if (!this._isLoaded) {
|
245 | return;
|
246 | }
|
247 | this._suspendNativeUpdates(SuspendType.Loaded);
|
248 | this.eachChild((child) => {
|
249 | this.unloadView(child);
|
250 | return true;
|
251 | });
|
252 | this._isLoaded = false;
|
253 | this._cssState.onUnloaded();
|
254 | this._emit('unloaded');
|
255 | }
|
256 | _layoutParent() {
|
257 | if (this.parent) {
|
258 | this.parent._layoutParent();
|
259 | }
|
260 | }
|
261 | _suspendNativeUpdates(type) {
|
262 | if (type) {
|
263 | this._suspendNativeUpdatesCount = this._suspendNativeUpdatesCount | type;
|
264 | }
|
265 | else {
|
266 | this._suspendNativeUpdatesCount++;
|
267 | }
|
268 | }
|
269 | _resumeNativeUpdates(type) {
|
270 | if (type) {
|
271 | this._suspendNativeUpdatesCount = this._suspendNativeUpdatesCount & ~type;
|
272 | }
|
273 | else {
|
274 | if ((this._suspendNativeUpdatesCount & SuspendType.IncrementalCountMask) === 0) {
|
275 | throw new Error(`Invalid call to ${this}._resumeNativeUpdates`);
|
276 | }
|
277 | this._suspendNativeUpdatesCount--;
|
278 | }
|
279 | if (!this._suspendNativeUpdatesCount) {
|
280 | this.onResumeNativeUpdates();
|
281 | }
|
282 | }
|
283 | _batchUpdate(callback) {
|
284 | try {
|
285 | this._suspendNativeUpdates(SuspendType.Incremental);
|
286 | return callback();
|
287 | }
|
288 | finally {
|
289 | this._resumeNativeUpdates(SuspendType.Incremental);
|
290 | }
|
291 | }
|
292 | setFlag(flag, value) {
|
293 | switch (flag) {
|
294 | case Flags.superOnLoadedCalled:
|
295 | this._onLoadedCalled = value;
|
296 | break;
|
297 | case Flags.superOnUnloadedCalled:
|
298 | this._onUnloadedCalled = value;
|
299 | break;
|
300 | }
|
301 | }
|
302 | isFlagSet(flag) {
|
303 | switch (flag) {
|
304 | case Flags.superOnLoadedCalled:
|
305 | return this._onLoadedCalled;
|
306 | case Flags.superOnUnloadedCalled:
|
307 | return this._onUnloadedCalled;
|
308 | }
|
309 | }
|
310 | callFunctionWithSuper(flag, func) {
|
311 | this.setFlag(flag, false);
|
312 | func();
|
313 | if (!this.isFlagSet(flag)) {
|
314 | throw new Error(`super.${flag} not called in ${this}`);
|
315 | }
|
316 | }
|
317 | callLoaded() {
|
318 | this.callFunctionWithSuper(Flags.superOnLoadedCalled, () => this.onLoaded());
|
319 | }
|
320 | callUnloaded() {
|
321 | this.callFunctionWithSuper(Flags.superOnUnloadedCalled, () => this.onUnloaded());
|
322 | }
|
323 | notifyPseudoClassChanged(pseudoClass) {
|
324 | this.notify({ eventName: ':' + pseudoClass, object: this });
|
325 | }
|
326 | getAllAliasedStates(name) {
|
327 | const allStates = [];
|
328 | allStates.push(name);
|
329 | if (name in this.pseudoClassAliases) {
|
330 | for (let i = 0; i < this.pseudoClassAliases[name].length; i++) {
|
331 | allStates.push(this.pseudoClassAliases[name][i]);
|
332 | }
|
333 | }
|
334 | return allStates;
|
335 | }
|
336 | addPseudoClass(name) {
|
337 | const allStates = this.getAllAliasedStates(name);
|
338 | for (let i = 0; i < allStates.length; i++) {
|
339 | if (!this.cssPseudoClasses.has(allStates[i])) {
|
340 | this.cssPseudoClasses.add(allStates[i]);
|
341 | this.notifyPseudoClassChanged(allStates[i]);
|
342 | }
|
343 | }
|
344 | }
|
345 | deletePseudoClass(name) {
|
346 | const allStates = this.getAllAliasedStates(name);
|
347 | for (let i = 0; i < allStates.length; i++) {
|
348 | if (this.cssPseudoClasses.has(allStates[i])) {
|
349 | this.cssPseudoClasses.delete(allStates[i]);
|
350 | this.notifyPseudoClassChanged(allStates[i]);
|
351 | }
|
352 | }
|
353 | }
|
354 | bindingContextChanged(data) {
|
355 | this.bindings.get('bindingContext').bind(data.value);
|
356 | }
|
357 | bind(options, source = defaultBindingSource) {
|
358 | const targetProperty = options.targetProperty;
|
359 | this.unbind(targetProperty);
|
360 | if (!this.bindings) {
|
361 | this.bindings = new Map();
|
362 | }
|
363 | const binding = new Binding(this, options);
|
364 | this.bindings.set(targetProperty, binding);
|
365 | let bindingSource = source;
|
366 | if (bindingSource === defaultBindingSource) {
|
367 | bindingSource = this.bindingContext;
|
368 | binding.sourceIsBindingContext = true;
|
369 | if (targetProperty === 'bindingContext') {
|
370 | this.bindingContextBoundToParentBindingContextChanged = true;
|
371 | const parent = this.parent;
|
372 | if (parent) {
|
373 | parent.on('bindingContextChange', this.bindingContextChanged, this);
|
374 | }
|
375 | else {
|
376 | this.shouldAddHandlerToParentBindingContextChanged = true;
|
377 | }
|
378 | }
|
379 | }
|
380 | binding.bind(bindingSource);
|
381 | }
|
382 | unbind(property) {
|
383 | const bindings = this.bindings;
|
384 | if (!bindings) {
|
385 | return;
|
386 | }
|
387 | const binding = bindings.get(property);
|
388 | if (binding) {
|
389 | binding.unbind();
|
390 | bindings.delete(property);
|
391 | if (binding.sourceIsBindingContext) {
|
392 | if (property === 'bindingContext') {
|
393 | this.shouldAddHandlerToParentBindingContextChanged = false;
|
394 | this.bindingContextBoundToParentBindingContextChanged = false;
|
395 | const parent = this.parent;
|
396 | if (parent) {
|
397 | parent.off('bindingContextChange', this.bindingContextChanged, this);
|
398 | }
|
399 | }
|
400 | }
|
401 | }
|
402 | }
|
403 | performLayout(currentRun = 0) {
|
404 |
|
405 |
|
406 |
|
407 | if (this._shouldDelayLayout() && currentRun < 100) {
|
408 | setTimeout(() => this.performLayout(currentRun), currentRun);
|
409 | currentRun++;
|
410 | }
|
411 | else {
|
412 | this.parent.requestLayout();
|
413 | }
|
414 | }
|
415 | requestLayout() {
|
416 |
|
417 | const parent = this.parent;
|
418 | if (parent) {
|
419 | this.performLayout();
|
420 | }
|
421 | }
|
422 | eachChild(callback) {
|
423 |
|
424 | }
|
425 | _addView(view, atIndex) {
|
426 | if (Trace.isEnabled()) {
|
427 | Trace.write(`${this}._addView(${view}, ${atIndex})`, Trace.categories.ViewHierarchy);
|
428 | }
|
429 | if (!view) {
|
430 | throw new Error('Expecting a valid View instance.');
|
431 | }
|
432 | if (!(view instanceof ViewBase)) {
|
433 | throw new Error(view + ' is not a valid View instance.');
|
434 | }
|
435 | if (view.parent) {
|
436 | throw new Error('View already has a parent. View: ' + view + ' Parent: ' + view.parent);
|
437 | }
|
438 | view.parent = this;
|
439 | this._addViewCore(view, atIndex);
|
440 | view._parentChanged(null);
|
441 | if (this.domNode) {
|
442 | this.domNode.onChildAdded(view);
|
443 | }
|
444 | }
|
445 | _addViewCore(view, atIndex) {
|
446 | propagateInheritableProperties(this, view);
|
447 | view._inheritStyleScope(this._styleScope);
|
448 | propagateInheritableCssProperties(this.style, view.style);
|
449 | if (this._context) {
|
450 | view._setupUI(this._context, atIndex);
|
451 | }
|
452 | if (this._isLoaded) {
|
453 | this.loadView(view);
|
454 | }
|
455 | }
|
456 | loadView(view) {
|
457 | if (view && !view.isLoaded) {
|
458 | view.callLoaded();
|
459 | }
|
460 | }
|
461 | _shouldDelayLayout() {
|
462 | return false;
|
463 | }
|
464 | unloadView(view) {
|
465 | if (view && view.isLoaded) {
|
466 | view.callUnloaded();
|
467 | }
|
468 | }
|
469 | |
470 |
|
471 |
|
472 | _removeView(view) {
|
473 | if (Trace.isEnabled()) {
|
474 | Trace.write(`${this}._removeView(${view})`, Trace.categories.ViewHierarchy);
|
475 | }
|
476 | if (view.parent !== this) {
|
477 | throw new Error('View not added to this instance. View: ' + view + ' CurrentParent: ' + view.parent + ' ExpectedParent: ' + this);
|
478 | }
|
479 | if (this.domNode) {
|
480 | this.domNode.onChildRemoved(view);
|
481 | }
|
482 | this._removeViewCore(view);
|
483 | view.parent = undefined;
|
484 | view._parentChanged(this);
|
485 | }
|
486 | |
487 |
|
488 |
|
489 | _removeViewCore(view) {
|
490 | this.unloadView(view);
|
491 | if (view._context) {
|
492 | view._tearDownUI();
|
493 | }
|
494 | }
|
495 | createNativeView() {
|
496 | return undefined;
|
497 | }
|
498 | disposeNativeView() {
|
499 | this.notify({
|
500 | eventName: ViewBase.disposeNativeViewEvent,
|
501 | object: this,
|
502 | });
|
503 | }
|
504 | initNativeView() {
|
505 |
|
506 | }
|
507 | resetNativeView() {
|
508 |
|
509 | }
|
510 | resetNativeViewInternal() {
|
511 |
|
512 |
|
513 |
|
514 |
|
515 |
|
516 |
|
517 |
|
518 |
|
519 |
|
520 |
|
521 |
|
522 |
|
523 |
|
524 |
|
525 |
|
526 |
|
527 | }
|
528 | _setupAsRootView(context) {
|
529 | this._setupUI(context);
|
530 | }
|
531 | _setupUI(context, atIndex, parentIsLoaded) {
|
532 | if (this._context === context) {
|
533 |
|
534 |
|
535 | if (this.reusable) {
|
536 | if (this.parent && !this._isAddedToNativeVisualTree) {
|
537 | const nativeIndex = this.parent._childIndexToNativeChildIndex(atIndex);
|
538 | this._isAddedToNativeVisualTree = this.parent._addViewToNativeVisualTree(this, nativeIndex);
|
539 | }
|
540 | }
|
541 | return;
|
542 | }
|
543 | else if (this._context) {
|
544 | this._tearDownUI(true);
|
545 | }
|
546 | this._context = context;
|
547 |
|
548 |
|
549 | let nativeView = this.nativeViewProtected;
|
550 |
|
551 |
|
552 |
|
553 |
|
554 |
|
555 |
|
556 | if (!nativeView) {
|
557 | nativeView = this.createNativeView();
|
558 | }
|
559 | if (global.isAndroid) {
|
560 |
|
561 |
|
562 | if (this._androidView !== nativeView || !this.reusable) {
|
563 | this._androidView = nativeView;
|
564 | if (nativeView) {
|
565 | if (this._isPaddingRelative === undefined) {
|
566 | this._isPaddingRelative = nativeView.isPaddingRelative();
|
567 | }
|
568 | let result = nativeView.defaultPaddings;
|
569 | if (result === undefined) {
|
570 | result = org.nativescript.widgets.ViewHelper.getPadding(nativeView);
|
571 | nativeView.defaultPaddings = result;
|
572 | }
|
573 | this._defaultPaddingTop = result.top;
|
574 | this._defaultPaddingRight = result.right;
|
575 | this._defaultPaddingBottom = result.bottom;
|
576 | this._defaultPaddingLeft = result.left;
|
577 | const style = this.style;
|
578 | if (!paddingTopProperty.isSet(style)) {
|
579 | this.effectivePaddingTop = this._defaultPaddingTop;
|
580 | }
|
581 | if (!paddingRightProperty.isSet(style)) {
|
582 | this.effectivePaddingRight = this._defaultPaddingRight;
|
583 | }
|
584 | if (!paddingBottomProperty.isSet(style)) {
|
585 | this.effectivePaddingBottom = this._defaultPaddingBottom;
|
586 | }
|
587 | if (!paddingLeftProperty.isSet(style)) {
|
588 | this.effectivePaddingLeft = this._defaultPaddingLeft;
|
589 | }
|
590 | }
|
591 | }
|
592 | }
|
593 | else {
|
594 | this._iosView = nativeView;
|
595 | }
|
596 | this.setNativeView(nativeView);
|
597 | if (this.parent) {
|
598 | const nativeIndex = this.parent._childIndexToNativeChildIndex(atIndex);
|
599 | this._isAddedToNativeVisualTree = this.parent._addViewToNativeVisualTree(this, nativeIndex);
|
600 | }
|
601 | this._resumeNativeUpdates(SuspendType.UISetup);
|
602 | this.eachChild((child) => {
|
603 | child._setupUI(context);
|
604 | return true;
|
605 | });
|
606 | }
|
607 | setNativeView(value) {
|
608 | if (this.__nativeView === value) {
|
609 | return;
|
610 | }
|
611 | if (this.__nativeView) {
|
612 | this._suspendNativeUpdates(SuspendType.NativeView);
|
613 |
|
614 | }
|
615 | this.__nativeView = this.nativeViewProtected = value;
|
616 | if (this.__nativeView) {
|
617 | this._suspendedUpdates = undefined;
|
618 | this.initNativeView();
|
619 | this._resumeNativeUpdates(SuspendType.NativeView);
|
620 | }
|
621 | }
|
622 | destroyNode(forceDestroyChildren) {
|
623 | this.reusable = false;
|
624 | this._tearDownUI(forceDestroyChildren);
|
625 | }
|
626 | _tearDownUI(force) {
|
627 |
|
628 | if (!this._context) {
|
629 | return;
|
630 | }
|
631 | const preserveNativeView = this.reusable && !force;
|
632 | this.resetNativeViewInternal();
|
633 | if (!preserveNativeView) {
|
634 | this.eachChild((child) => {
|
635 | child._tearDownUI(force);
|
636 | return true;
|
637 | });
|
638 | }
|
639 | if (this.parent) {
|
640 | this.parent._removeViewFromNativeVisualTree(this);
|
641 | }
|
642 |
|
643 |
|
644 |
|
645 |
|
646 |
|
647 |
|
648 |
|
649 |
|
650 |
|
651 |
|
652 |
|
653 |
|
654 |
|
655 |
|
656 |
|
657 |
|
658 |
|
659 | if (!preserveNativeView) {
|
660 | this.disposeNativeView();
|
661 | this._suspendNativeUpdates(SuspendType.UISetup);
|
662 | if (global.isAndroid) {
|
663 | this.setNativeView(null);
|
664 | this._androidView = null;
|
665 | }
|
666 |
|
667 | this._context = null;
|
668 | }
|
669 | if (this.domNode) {
|
670 | this.domNode.dispose();
|
671 | this.domNode = undefined;
|
672 | }
|
673 | }
|
674 | _childIndexToNativeChildIndex(index) {
|
675 | return index;
|
676 | }
|
677 | |
678 |
|
679 |
|
680 | _addViewToNativeVisualTree(view, atIndex) {
|
681 | if (view._isAddedToNativeVisualTree) {
|
682 | throw new Error('Child already added to the native visual tree.');
|
683 | }
|
684 | return true;
|
685 | }
|
686 | |
687 |
|
688 |
|
689 | _removeViewFromNativeVisualTree(view) {
|
690 | view._isAddedToNativeVisualTree = false;
|
691 | }
|
692 | _goToVisualState(state) {
|
693 | if (Trace.isEnabled()) {
|
694 | Trace.write(this + ' going to state: ' + state, Trace.categories.Style);
|
695 | }
|
696 | if (state === this._visualState) {
|
697 | return;
|
698 | }
|
699 | this.deletePseudoClass(this._visualState);
|
700 | this._visualState = state;
|
701 | this.addPseudoClass(state);
|
702 | }
|
703 | |
704 |
|
705 |
|
706 |
|
707 |
|
708 |
|
709 | _applyXmlAttribute(attribute, value) {
|
710 | console.log('ViewBase._applyXmlAttribute(...) is deprecated; set attributes as plain properties instead');
|
711 | if (attribute === 'style' || attribute === 'rows' || attribute === 'columns' || attribute === 'fontAttributes') {
|
712 | this[attribute] = value;
|
713 | return true;
|
714 | }
|
715 | return false;
|
716 | }
|
717 | setInlineStyle(style) {
|
718 | if (typeof style !== 'string') {
|
719 | throw new Error('Parameter should be valid CSS string!');
|
720 | }
|
721 | ensureStyleScopeModule();
|
722 | styleScopeModule.applyInlineStyle(this, style, undefined);
|
723 | }
|
724 | _parentChanged(oldParent) {
|
725 | const newParent = this.parent;
|
726 |
|
727 | if (oldParent) {
|
728 | clearInheritedProperties(this);
|
729 | if (this.bindingContextBoundToParentBindingContextChanged) {
|
730 | oldParent.off('bindingContextChange', this.bindingContextChanged, this);
|
731 | }
|
732 | }
|
733 | else if (this.shouldAddHandlerToParentBindingContextChanged) {
|
734 | newParent.on('bindingContextChange', this.bindingContextChanged, this);
|
735 | this.bindings.get('bindingContext').bind(newParent.bindingContext);
|
736 | }
|
737 | }
|
738 | onResumeNativeUpdates() {
|
739 |
|
740 | initNativeView(this, undefined, undefined);
|
741 | }
|
742 | toString() {
|
743 | let str = this.typeName;
|
744 | if (this.id) {
|
745 | str += `<${this.id}>`;
|
746 | }
|
747 | else {
|
748 | str += `(${this._domId})`;
|
749 | }
|
750 | const source = Source.get(this);
|
751 | if (source) {
|
752 | str += `@${source};`;
|
753 | }
|
754 | return str;
|
755 | }
|
756 | _onCssStateChange() {
|
757 | this._cssState.onChange();
|
758 | eachDescendant(this, (child) => {
|
759 | child._cssState.onChange();
|
760 | return true;
|
761 | });
|
762 | }
|
763 | _inheritStyleScope(styleScope) {
|
764 |
|
765 |
|
766 | if (this._isStyleScopeHost) {
|
767 | return;
|
768 | }
|
769 | if (this._styleScope !== styleScope) {
|
770 | this._styleScope = styleScope;
|
771 | this._onCssStateChange();
|
772 | this.eachChild((child) => {
|
773 | child._inheritStyleScope(styleScope);
|
774 | return true;
|
775 | });
|
776 | }
|
777 | }
|
778 | showModal(...args) {
|
779 | const parent = this.parent;
|
780 | return parent && parent.showModal(...args);
|
781 | }
|
782 | closeModal(...args) {
|
783 | const parent = this.parent;
|
784 | if (parent) {
|
785 | parent.closeModal(...args);
|
786 | }
|
787 | }
|
788 | _dialogClosed() {
|
789 | eachDescendant(this, (child) => {
|
790 | child._dialogClosed();
|
791 | return true;
|
792 | });
|
793 | }
|
794 | _onRootViewReset() {
|
795 | eachDescendant(this, (child) => {
|
796 | child._onRootViewReset();
|
797 | return true;
|
798 | });
|
799 | }
|
800 | }
|
801 | ViewBase.loadedEvent = 'loaded';
|
802 | ViewBase.unloadedEvent = 'unloaded';
|
803 | ViewBase.createdEvent = 'created';
|
804 | ViewBase.disposeNativeViewEvent = 'disposeNativeView';
|
805 | __decorate([
|
806 | profile,
|
807 | __metadata("design:type", Function),
|
808 | __metadata("design:paramtypes", []),
|
809 | __metadata("design:returntype", void 0)
|
810 | ], ViewBase.prototype, "onLoaded", null);
|
811 | __decorate([
|
812 | profile,
|
813 | __metadata("design:type", Function),
|
814 | __metadata("design:paramtypes", []),
|
815 | __metadata("design:returntype", void 0)
|
816 | ], ViewBase.prototype, "onUnloaded", null);
|
817 | __decorate([
|
818 | profile,
|
819 | __metadata("design:type", Function),
|
820 | __metadata("design:paramtypes", [String]),
|
821 | __metadata("design:returntype", void 0)
|
822 | ], ViewBase.prototype, "addPseudoClass", null);
|
823 | __decorate([
|
824 | profile,
|
825 | __metadata("design:type", Function),
|
826 | __metadata("design:paramtypes", [String]),
|
827 | __metadata("design:returntype", void 0)
|
828 | ], ViewBase.prototype, "deletePseudoClass", null);
|
829 | __decorate([
|
830 | profile,
|
831 | __metadata("design:type", Function),
|
832 | __metadata("design:paramtypes", []),
|
833 | __metadata("design:returntype", void 0)
|
834 | ], ViewBase.prototype, "requestLayout", null);
|
835 | __decorate([
|
836 | profile,
|
837 | __metadata("design:type", Function),
|
838 | __metadata("design:paramtypes", [ViewBase, Number]),
|
839 | __metadata("design:returntype", void 0)
|
840 | ], ViewBase.prototype, "_addView", null);
|
841 | __decorate([
|
842 | profile,
|
843 | __metadata("design:type", Function),
|
844 | __metadata("design:paramtypes", [Object, Number, Boolean]),
|
845 | __metadata("design:returntype", void 0)
|
846 | ], ViewBase.prototype, "_setupUI", null);
|
847 | __decorate([
|
848 | profile,
|
849 | __metadata("design:type", Function),
|
850 | __metadata("design:paramtypes", [Boolean]),
|
851 | __metadata("design:returntype", void 0)
|
852 | ], ViewBase.prototype, "_tearDownUI", null);
|
853 | ViewBase.prototype.isCollapsed = false;
|
854 | ViewBase.prototype._oldLeft = 0;
|
855 | ViewBase.prototype._oldTop = 0;
|
856 | ViewBase.prototype._oldRight = 0;
|
857 | ViewBase.prototype._oldBottom = 0;
|
858 | ViewBase.prototype.effectiveMinWidth = 0;
|
859 | ViewBase.prototype.effectiveMinHeight = 0;
|
860 | ViewBase.prototype.effectiveWidth = 0;
|
861 | ViewBase.prototype.effectiveHeight = 0;
|
862 | ViewBase.prototype.effectiveMarginTop = 0;
|
863 | ViewBase.prototype.effectiveMarginRight = 0;
|
864 | ViewBase.prototype.effectiveMarginBottom = 0;
|
865 | ViewBase.prototype.effectiveMarginLeft = 0;
|
866 | ViewBase.prototype.effectivePaddingTop = 0;
|
867 | ViewBase.prototype.effectivePaddingRight = 0;
|
868 | ViewBase.prototype.effectivePaddingBottom = 0;
|
869 | ViewBase.prototype.effectivePaddingLeft = 0;
|
870 | ViewBase.prototype.effectiveBorderTopWidth = 0;
|
871 | ViewBase.prototype.effectiveBorderRightWidth = 0;
|
872 | ViewBase.prototype.effectiveBorderBottomWidth = 0;
|
873 | ViewBase.prototype.effectiveBorderLeftWidth = 0;
|
874 | ViewBase.prototype._defaultPaddingTop = 0;
|
875 | ViewBase.prototype._defaultPaddingRight = 0;
|
876 | ViewBase.prototype._defaultPaddingBottom = 0;
|
877 | ViewBase.prototype._defaultPaddingLeft = 0;
|
878 | ViewBase.prototype._isViewBase = true;
|
879 | ViewBase.prototype.recycleNativeView = 'never';
|
880 | ViewBase.prototype.reusable = false;
|
881 | ViewBase.prototype._suspendNativeUpdatesCount = SuspendType.Loaded | SuspendType.NativeView | SuspendType.UISetup;
|
882 | export const bindingContextProperty = new InheritedProperty({
|
883 | name: 'bindingContext',
|
884 | });
|
885 | bindingContextProperty.register(ViewBase);
|
886 | export const hiddenProperty = new Property({
|
887 | name: 'hidden',
|
888 | defaultValue: false,
|
889 | affectsLayout: global.isIOS,
|
890 | valueConverter: booleanConverter,
|
891 | valueChanged: (target, oldValue, newValue) => {
|
892 | if (target) {
|
893 | target.isCollapsed = !!newValue;
|
894 | }
|
895 | },
|
896 | });
|
897 | hiddenProperty.register(ViewBase);
|
898 | export const classNameProperty = new Property({
|
899 | name: 'className',
|
900 | valueChanged(view, oldValue, newValue) {
|
901 | const cssClasses = view.cssClasses;
|
902 | const rootViewsCssClasses = CSSUtils.getSystemCssClasses();
|
903 | const shouldAddModalRootViewCssClasses = cssClasses.has(CSSUtils.MODAL_ROOT_VIEW_CSS_CLASS);
|
904 | const shouldAddRootViewCssClasses = cssClasses.has(CSSUtils.ROOT_VIEW_CSS_CLASS);
|
905 | cssClasses.clear();
|
906 | if (shouldAddModalRootViewCssClasses) {
|
907 | cssClasses.add(CSSUtils.MODAL_ROOT_VIEW_CSS_CLASS);
|
908 | }
|
909 | else if (shouldAddRootViewCssClasses) {
|
910 | cssClasses.add(CSSUtils.ROOT_VIEW_CSS_CLASS);
|
911 | }
|
912 | rootViewsCssClasses.forEach((c) => cssClasses.add(c));
|
913 | if (typeof newValue === 'string' && newValue !== '') {
|
914 | newValue.split(' ').forEach((c) => cssClasses.add(c));
|
915 | }
|
916 | view._onCssStateChange();
|
917 | },
|
918 | });
|
919 | classNameProperty.register(ViewBase);
|
920 | export const idProperty = new Property({
|
921 | name: 'id',
|
922 | valueChanged: (view, oldValue, newValue) => view._onCssStateChange(),
|
923 | });
|
924 | idProperty.register(ViewBase);
|
925 | export function booleanConverter(v) {
|
926 | const lowercase = (v + '').toLowerCase();
|
927 | if (lowercase === 'true') {
|
928 | return true;
|
929 | }
|
930 | else if (lowercase === 'false') {
|
931 | return false;
|
932 | }
|
933 | throw new Error(`Invalid boolean: ${v}`);
|
934 | }
|
935 |
|
\ | No newline at end of file |