diff --git a/ng2-components/ng2-activiti-form/index.ts b/ng2-components/ng2-activiti-form/index.ts
index b20bf4efb1..8ee90c9dd8 100644
--- a/ng2-components/ng2-activiti-form/index.ts
+++ b/ng2-components/ng2-activiti-form/index.ts
@@ -30,7 +30,7 @@ import { WidgetVisibilityService } from './src/services/widget-visibility.servic
import { ActivitiAlfrescoContentService } from './src/services/activiti-alfresco.service';
import { FormRenderingService } from './src/services/form-rendering.service';
import { HttpModule } from '@angular/http';
-import { WIDGET_DIRECTIVES } from './src/components/widgets/index';
+import { WIDGET_DIRECTIVES, MASK_DIRECTIVE } from './src/components/widgets/index';
export * from './src/components/activiti-form.component';
export * from './src/components/activiti-content.component';
@@ -67,7 +67,8 @@ export const ACTIVITI_FORM_PROVIDERS: any[] = [
HttpModule
],
declarations: [
- ...ACTIVITI_FORM_DIRECTIVES
+ ...ACTIVITI_FORM_DIRECTIVES,
+ ...MASK_DIRECTIVE
],
entryComponents: [
...WIDGET_DIRECTIVES
diff --git a/ng2-components/ng2-activiti-form/package.json b/ng2-components/ng2-activiti-form/package.json
index 2886e31b79..3dc28649b7 100644
--- a/ng2-components/ng2-activiti-form/package.json
+++ b/ng2-components/ng2-activiti-form/package.json
@@ -42,7 +42,6 @@
"@angular/platform-browser": "~4.0.0",
"@angular/platform-browser-dynamic": "~4.0.0",
"@angular/router": "~4.0.0",
-
"@angular/material": "2.0.0-beta.1",
"alfresco-js-api": "~1.4.0",
"core-js": "2.4.1",
diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts
index 7036dcd298..9cf614e1eb 100644
--- a/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts
+++ b/ng2-components/ng2-activiti-form/src/components/activiti-start-form.component.spec.ts
@@ -23,6 +23,7 @@ import { ActivitiStartForm } from './activiti-start-form.component';
import { FormFieldComponent } from './form-field/form-field.component';
import { ActivitiContent } from './activiti-content.component';
import { WIDGET_DIRECTIVES } from './widgets/index';
+import { MASK_DIRECTIVE } from './widgets/index';
import { FormService } from './../services/form.service';
import { EcmModelService } from './../services/ecm-model.service';
import { WidgetVisibilityService } from './../services/widget-visibility.service';
@@ -47,7 +48,8 @@ describe('ActivitiStartForm', () => {
ActivitiStartForm,
FormFieldComponent,
ActivitiContent,
- ...WIDGET_DIRECTIVES
+ ...WIDGET_DIRECTIVES,
+ ...MASK_DIRECTIVE
],
providers: [
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
diff --git a/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.spec.ts
index 675f875fd3..2a3df2f17f 100644
--- a/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.spec.ts
+++ b/ng2-components/ng2-activiti-form/src/components/form-field/form-field.component.spec.ts
@@ -21,6 +21,7 @@ import { FormFieldComponent } from './form-field.component';
import { FormRenderingService } from './../../services/form-rendering.service';
import { FormModel, FormFieldModel, FormFieldTypes } from './../widgets/core/index';
import { TextWidget } from './../widgets/text/text.widget';
+import { InputMaskDirective } from './../widgets/text/text-mask.component';
import { CheckboxWidget } from './../widgets/checkbox/checkbox.widget';
import { WidgetVisibilityService } from './../../services/widget-visibility.service';
@@ -36,7 +37,7 @@ describe('FormFieldComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [CoreModule],
- declarations: [FormFieldComponent, TextWidget, CheckboxWidget],
+ declarations: [FormFieldComponent, TextWidget, CheckboxWidget, InputMaskDirective],
providers: [
FormRenderingService,
WidgetVisibilityService
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts
index 130d6d5417..f50f11a51a 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.spec.ts
@@ -23,6 +23,7 @@ import { FormFieldModel } from './../core/form-field.model';
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { CoreModule } from 'ng2-alfresco-core';
import { WIDGET_DIRECTIVES } from '../index';
+import { MASK_DIRECTIVE } from '../index';
import { FormFieldComponent } from './../../form-field/form-field.component';
import { ActivitiContent } from './../../activiti-content.component';
import { fakeFormJson } from '../../../services/assets/widget-visibility.service.mock';
@@ -133,7 +134,7 @@ describe('ContainerWidget', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [CoreModule],
- declarations: [FormFieldComponent, ActivitiContent, WIDGET_DIRECTIVES]
+ declarations: [FormFieldComponent, ActivitiContent, WIDGET_DIRECTIVES, MASK_DIRECTIVE]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(ContainerWidget);
containerWidgetComponent = fixture.componentInstance;
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/index.ts b/ng2-components/ng2-activiti-form/src/components/widgets/index.ts
index fdc59cff0f..d537524388 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/index.ts
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/index.ts
@@ -41,6 +41,7 @@ import { DropdownEditorComponent } from './dynamic-table/editors/dropdown/dropdo
import { BooleanEditorComponent } from './dynamic-table/editors/boolean/boolean.editor';
import { TextEditorComponent } from './dynamic-table/editors/text/text.editor';
import { RowEditorComponent } from './dynamic-table/editors/row.editor';
+import { InputMaskDirective } from './text/text-mask.component';
// core
export * from './widget.component';
@@ -76,6 +77,7 @@ export * from './dynamic-table/editors/date/date.editor';
export * from './dynamic-table/editors/dropdown/dropdown.editor';
export * from './dynamic-table/editors/boolean/boolean.editor';
export * from './dynamic-table/editors/text/text.editor';
+export * from './text/text-mask.component';
export const WIDGET_DIRECTIVES: any[] = [
UnknownWidget,
@@ -105,3 +107,7 @@ export const WIDGET_DIRECTIVES: any[] = [
TextEditorComponent,
RowEditorComponent
];
+
+export const MASK_DIRECTIVE: any[] = [
+ InputMaskDirective
+];
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/tabs/tabs.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/tabs/tabs.widget.spec.ts
index 1ffd67bebf..40d5f9b819 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/tabs/tabs.widget.spec.ts
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/tabs/tabs.widget.spec.ts
@@ -22,6 +22,7 @@ import { fakeFormJson } from '../../../services/assets/widget-visibility.service
import { TabsWidget } from './tabs.widget';
import { TabModel } from '../core/tab.model';
import { WIDGET_DIRECTIVES } from '../index';
+import { MASK_DIRECTIVE } from '../index';
import { FormFieldComponent } from './../../form-field/form-field.component';
import { ActivitiContent } from './../../activiti-content.component';
import { CoreModule } from 'ng2-alfresco-core';
@@ -104,7 +105,7 @@ describe('TabsWidget', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [CoreModule],
- declarations: [FormFieldComponent, ActivitiContent, WIDGET_DIRECTIVES]
+ declarations: [FormFieldComponent, ActivitiContent, WIDGET_DIRECTIVES, MASK_DIRECTIVE]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(TabsWidget);
tabWidgetComponent = fixture.componentInstance;
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/text/text-mask.component.ts b/ng2-components/ng2-activiti-form/src/components/widgets/text/text-mask.component.ts
new file mode 100644
index 0000000000..faf6128b3a
--- /dev/null
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/text/text-mask.component.ts
@@ -0,0 +1,223 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ Directive,
+ ElementRef,
+ Renderer,
+ HostListener,
+ Input,
+ OnChanges,
+ SimpleChanges,
+ forwardRef
+} from '@angular/core';
+import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
+
+export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
+ provide: NG_VALUE_ACCESSOR,
+ useExisting: forwardRef(() => InputMaskDirective),
+ multi: true
+};
+
+@Directive({
+ selector: '[textMask]',
+ providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
+})
+export class InputMaskDirective implements OnChanges, ControlValueAccessor {
+
+ @Input('textMask') inputMask: {
+ mask: '',
+ isReversed: false
+ };
+
+ private translationMask = {
+ '0': { pattern: /\d/ },
+ '9': { pattern: /\d/, optional: true },
+ '#': { pattern: /\d/, recursive: true },
+ 'A': { pattern: /[a-zA-Z0-9]/ },
+ 'S': { pattern: /[a-zA-Z]/ }
+ };
+
+ private byPassKeys = [9, 16, 17, 18, 36, 37, 38, 39, 40, 91];
+ private value;
+ private invalidCharacters = [];
+
+ constructor(private el: ElementRef, private render: Renderer) {
+ }
+
+ _onChange = (_: any) => {
+ }
+
+ _onTouched = () => {
+ }
+
+ @HostListener('input', ['$event'])
+ @HostListener('keyup', ['$event']) onTextInput(event: KeyboardEvent) {
+ if (this.inputMask && this.inputMask.mask) {
+ this.maskValue(this.el.nativeElement.value, this.el.nativeElement.selectionStart,
+ this.inputMask.mask, this.inputMask.isReversed, event.keyCode);
+ }
+ }
+
+ ngOnChanges(changes: SimpleChanges) {
+ if (changes['inputMask'] && changes['inputMask'].currentValue['mask']) {
+ this.inputMask = changes['inputMask'].currentValue;
+ }
+ }
+
+ writeValue(value: any) {
+ this.el.nativeElement.value = value;
+ }
+
+ registerOnChange(fn: any) {
+ this._onChange = fn;
+ }
+
+ registerOnTouched(fn: () => any): void {
+ this._onTouched = fn;
+ }
+
+ private maskValue(actualValue, startCaret, maskToApply, isMaskReversed, keyCode) {
+ if (this.byPassKeys.indexOf(keyCode) === -1) {
+ let value = this.getMasked(false, actualValue, maskToApply, isMaskReversed);
+ let calculatedCaret = this.calculateCaretPosition(startCaret, actualValue, keyCode);
+ this.render.setElementAttribute(this.el.nativeElement, 'value', value);
+ this.el.nativeElement.value = value;
+ this.setValue(value);
+ this._onChange(value);
+ this.setCaretPosition(calculatedCaret);
+ }
+ }
+
+ private setCaretPosition(caretPosition) {
+ this.el.nativeElement.moveStart = caretPosition;
+ this.el.nativeElement.moveEnd = caretPosition;
+ }
+
+ calculateCaretPosition(caretPosition, newValue, keyCode) {
+ let newValueLength = newValue.length;
+ let oldValue = this.getValue() || '';
+ let oldValueLength = oldValue.length;
+
+ if (keyCode === 8 && oldValue !== newValue) {
+ caretPosition = caretPosition - (newValue.slice(0, caretPosition).length - oldValue.slice(0, caretPosition).length);
+ } else if (oldValue !== newValue) {
+ if (caretPosition >= oldValueLength) {
+ caretPosition = newValueLength;
+ } else {
+ caretPosition = caretPosition + (newValue.slice(0, caretPosition).length - oldValue.slice(0, caretPosition).length);
+ }
+ }
+ return caretPosition;
+ }
+
+ getMasked(skipMaskChars, val, mask, isReversed = false) {
+ let buf = [],
+ value = val,
+ maskIndex = 0,
+ maskLen = mask.length,
+ valueIndex = 0,
+ valueLength = value.length,
+ offset = 1,
+ addMethod = 'push',
+ resetPos = -1,
+ lastMaskChar,
+ lastUntranslatedMaskChar,
+ check;
+
+ if (isReversed) {
+ addMethod = 'unshift';
+ offset = -1;
+ lastMaskChar = 0;
+ maskIndex = maskLen - 1;
+ valueIndex = valueLength - 1;
+ } else {
+ lastMaskChar = maskLen - 1;
+ }
+ check = this.isToCheck(isReversed, maskIndex, maskLen, valueIndex, valueLength);
+ while (check) {
+ let maskDigit = mask.charAt(maskIndex),
+ valDigit = value.charAt(valueIndex),
+ translation = this.translationMask[maskDigit];
+
+ if (translation) {
+ if (valDigit.match(translation.pattern)) {
+ buf[addMethod](valDigit);
+ if (translation.recursive) {
+ if (resetPos === -1) {
+ resetPos = maskIndex;
+ } else if (maskIndex === lastMaskChar) {
+ maskIndex = resetPos - offset;
+ }
+ if (lastMaskChar === resetPos) {
+ maskIndex -= offset;
+ }
+ }
+ maskIndex += offset;
+ } else if (valDigit === lastUntranslatedMaskChar) {
+ lastUntranslatedMaskChar = undefined;
+ } else if (translation.optional) {
+ maskIndex += offset;
+ valueIndex -= offset;
+ } else {
+ this.invalidCharacters.push({
+ index: valueIndex,
+ digit: valDigit,
+ translated: translation.pattern
+ });
+ }
+ valueIndex += offset;
+ } else {
+ if (!skipMaskChars) {
+ buf[addMethod](maskDigit);
+ }
+ if (valDigit === maskDigit) {
+ valueIndex += offset;
+ } else {
+ lastUntranslatedMaskChar = maskDigit;
+ }
+ maskIndex += offset;
+ }
+ check = this.isToCheck(isReversed, maskIndex, maskLen, valueIndex, valueLength);
+ }
+
+ let lastMaskCharDigit = mask.charAt(lastMaskChar);
+ if (maskLen === valueLength + 1 && !this.translationMask[lastMaskCharDigit]) {
+ buf.push(lastMaskCharDigit);
+ }
+
+ return buf.join('');
+ }
+
+ private isToCheck(isReversed, maskIndex, maskLen, valueIndex, valueLength) {
+ let check = false;
+ if (isReversed) {
+ check = (maskIndex > -1) && (valueIndex > -1);
+ } else {
+ check = (maskIndex < maskLen) && (valueIndex < valueLength);
+ }
+ return check;
+ }
+
+ private setValue(value) {
+ this.value = value;
+ }
+
+ private getValue() {
+ return this.value;
+ }
+}
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.html
index 7f78f0af84..5efc1d0c0b 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.html
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.html
@@ -9,6 +9,7 @@
[(ngModel)]="field.value"
(ngModelChange)="onFieldChanged(field)"
[disabled]="field.readOnly"
+ [textMask]="{mask: mask, isReversed: isMaskReversed}"
placeholder="{{field.placeholder}}">
{{field.validationSummary}}
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.spec.ts
index 5edea9002c..209f3bffca 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.spec.ts
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.spec.ts
@@ -16,6 +16,12 @@
*/
import { TextWidget } from './text.widget';
+import { ComponentFixture, TestBed, async } from '@angular/core/testing';
+import { CoreModule } from 'ng2-alfresco-core';
+import { InputMaskDirective } from './text-mask.component';
+import { FormFieldModel } from '../core/form-field.model';
+import { FormModel } from '../core/form.model';
+import { FormFieldTypes } from '../core/form-field-types';
describe('TextWidget', () => {
@@ -25,11 +31,167 @@ describe('TextWidget', () => {
beforeEach(() => {
widget = new TextWidget();
- componentHandler = jasmine.createSpyObj('componentHandler', [
+ componentHandler = jasmine.createSpyObj('componentHandler', [
'upgradeAllRegistered'
]);
window['componentHandler'] = componentHandler;
});
+ describe('when template is ready', () => {
+ let textWidget: TextWidget;
+ let fixture: ComponentFixture;
+ let element: HTMLInputElement;
+ let componentHandler;
+
+ beforeEach(async(() => {
+ componentHandler = jasmine.createSpyObj('componentHandler', ['upgradeAllRegistered', 'upgradeElement']);
+ window['componentHandler'] = componentHandler;
+ }));
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [CoreModule],
+ declarations: [TextWidget, InputMaskDirective]
+ }).compileComponents().then(() => {
+ fixture = TestBed.createComponent(TextWidget);
+ textWidget = fixture.componentInstance;
+ element = fixture.nativeElement;
+ });
+ }));
+
+ afterEach(() => {
+ fixture.destroy();
+ TestBed.resetTestingModule();
+ });
+
+ describe('and mask is configured on text element', () => {
+
+ let inputElement: HTMLInputElement;
+
+ beforeEach(() => {
+ textWidget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
+ id: 'text-id',
+ name: 'text-name',
+ value: '',
+ params: { inputMask: '##-##0,00%' },
+ type: FormFieldTypes.TEXT,
+ readOnly: false
+ });
+
+ fixture.detectChanges();
+ inputElement = element.querySelector('#text-id');
+ });
+
+ it('should show text widget', () => {
+ expect(element.querySelector('#text-id')).toBeDefined();
+ expect(element.querySelector('#text-id')).not.toBeNull();
+ });
+
+ it('should prevent text to be written if is not allowed by the mask on keyUp event', async(() => {
+ expect(element.querySelector('#text-id')).not.toBeNull();
+
+ inputElement.value = 'F';
+ textWidget.field.value = 'F';
+ let event: any = new Event('keyup');
+ event.keyCode = '70';
+ inputElement.dispatchEvent(event);
+ fixture.detectChanges();
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ inputElement = element.querySelector('#text-id');
+ expect(inputElement.value).toBe('');
+ });
+ }));
+
+ it('should prevent text to be written if is not allowed by the mask on input event', async(() => {
+ expect(element.querySelector('#text-id')).not.toBeNull();
+
+ inputElement.value = 'F';
+ textWidget.field.value = 'F';
+ inputElement.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ inputElement = element.querySelector('#text-id');
+ expect(inputElement.value).toBe('');
+ });
+ }));
+
+ it('should allow masked configured value on keyUp event', async(() => {
+ expect(element.querySelector('#text-id')).not.toBeNull();
+
+ inputElement.value = '1';
+ textWidget.field.value = '1';
+ let event: any = new Event('keyup');
+ event.keyCode = '49';
+ inputElement.dispatchEvent(event);
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ let inputElement: HTMLInputElement = element.querySelector('#text-id');
+ expect(inputElement.value).toBe('1');
+ });
+ }));
+
+ it('should autofill masked configured value on keyUp event', async(() => {
+ expect(element.querySelector('#text-id')).not.toBeNull();
+
+ inputElement.value = '12345678';
+ textWidget.field.value = '12345678';
+ let event: any = new Event('keyup');
+ event.keyCode = '49';
+ inputElement.dispatchEvent(event);
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ let inputElement: HTMLInputElement = element.querySelector('#text-id');
+ expect(inputElement.value).toBe('12-345,67%');
+ });
+ }));
+ });
+
+ describe('when the mask is reversed ', () => {
+
+ let inputElement: HTMLInputElement;
+
+ beforeEach(() => {
+ textWidget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
+ id: 'text-id',
+ name: 'text-name',
+ value: '',
+ params: { existingColspan: 1, maxColspan: 2, inputMask: "#.##0,00%", inputMaskReversed: true },
+ type: FormFieldTypes.TEXT,
+ readOnly: false
+ });
+
+ fixture.detectChanges();
+ inputElement = element.querySelector('#text-id');
+ });
+
+ afterEach(() => {
+ fixture.destroy();
+ TestBed.resetTestingModule();
+ });
+
+ it('should be able to apply the mask reversed', async(() => {
+ expect(element.querySelector('#text-id')).not.toBeNull();
+
+ inputElement.value = '1234';
+ textWidget.field.value = '1234';
+ let event: any = new Event('keyup');
+ event.keyCode = '49';
+ inputElement.dispatchEvent(event);
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ let inputElement: HTMLInputElement = element.querySelector('#text-id');
+ expect(inputElement.value).toBe('12,34%');
+ });
+ }));
+ });
+ });
+
});
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.ts
index 309ed71135..e093a143b5 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.ts
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
import { WidgetComponent } from './../widget.component';
@Component({
@@ -23,5 +23,15 @@ import { WidgetComponent } from './../widget.component';
templateUrl: './text.widget.html',
styleUrls: ['./text.widget.css']
})
-export class TextWidget extends WidgetComponent {
+export class TextWidget extends WidgetComponent implements OnInit {
+
+ private mask;
+ private isMaskReversed;
+
+ ngOnInit() {
+ if (this.field.params && this.field.params['inputMask']) {
+ this.mask = this.field.params['inputMask'];
+ this.isMaskReversed = this.field.params['inputMaskReversed'] ? this.field.params['inputMaskReversed'] : false;
+ }
+ }
}