Merge pull request #962 from NativeScript/nnikolov/Issue597

Fixed issue 597.
This commit is contained in:
Nedyalko Nikolov
2015-10-21 09:51:45 +03:00
9 changed files with 166 additions and 6 deletions

View File

@ -13,6 +13,7 @@ import observable = require("data/observable");
import stackLayoutModule = require("ui/layouts/stack-layout");
import {Label} from "ui/label";
import {Page} from "ui/page";
import {Button} from "ui/button";
import myCustomControlWithoutXml = require("./mymodule/MyControl");
import listViewModule = require("ui/list-view");
import helper = require("../ui/helper");
@ -692,6 +693,91 @@ export function test_parse_NestedRepeaters() {
}
}
export function test_parseSpansDirectlyOnLabel() {
var p = <Page>builder.parse('<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="pageNavigated"><StackLayout><Label id="testLabel"><Span text="We are" fontSize="10"/><Span text="Awesome" fontAttributes="Bold"/></Label></StackLayout></Page>');
function testAction(views: Array<viewModule.View>) {
var page = <Page>views[0];
var testLabel = <Label>page.getViewById("testLabel");
TKUnit.assertEqual(testLabel.formattedText + "", "We areAwesome", "Formatted string should be set");
}
helper.navigate(function () { return p; });
try {
testAction([p]);
}
finally {
helper.goBack();
}
}
export function test_parseSpansDirectlyOnButton() {
var p = <Page>builder.parse('<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="pageNavigated"><StackLayout><Button id="testButton"><Span text="We are" fontSize="10"/><Span text="Awesome" fontAttributes="Bold"/></Button></StackLayout></Page>');
function testAction(views: Array<viewModule.View>) {
var page = <Page>views[0];
var testButton = <Button>page.getViewById("testButton");
TKUnit.assertEqual(testButton.formattedText + "", "We areAwesome", "Formatted string should be set");
}
helper.navigate(function () { return p; });
try {
testAction([p]);
}
finally {
helper.goBack();
}
}
export function test_parseFormattedStringWithoutFormattedText() {
var p = <Page>builder.parse('<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="pageNavigated"><StackLayout><Button id="testButton"><FormattedString><FormattedString.spans><Span text="author"/><Span text=" num_comments"/></FormattedString.spans></FormattedString></Button></StackLayout></Page>');
function testAction(views: Array<viewModule.View>) {
var page = <Page>views[0];
var testButton = <Button>page.getViewById("testButton");
TKUnit.assertEqual(testButton.formattedText + "", "author num_comments", "Formatted string should be set");
}
helper.navigate(function () { return p; });
try {
testAction([p]);
}
finally {
helper.goBack();
}
}
export function test_parseFormattedStringFullSyntax() {
var p = <Page>builder.parse('<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="pageNavigated"><StackLayout><Button id="testButton"><Button.formattedText><FormattedString><FormattedString.spans><Span text="author"/><Span text=" num_comments"/></FormattedString.spans></FormattedString></Button.formattedText></Button></StackLayout></Page>');
function testAction(views: Array<viewModule.View>) {
var page = <Page>views[0];
var testButton = <Button>page.getViewById("testButton");
TKUnit.assertEqual(testButton.formattedText + "", "author num_comments", "Formatted string should be set");
}
helper.navigate(function () { return p; });
try {
testAction([p]);
}
finally {
helper.goBack();
}
}
export function test_parseSpansDirectlyToFormattedString() {
var p = <Page>builder.parse('<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="pageNavigated"><StackLayout><Button id="testButton"><FormattedString><Span text="author"/><Span text=" num_comments"/></FormattedString></Button></StackLayout></Page>');
function testAction(views: Array<viewModule.View>) {
var page = <Page>views[0];
var testButton = <Button>page.getViewById("testButton");
TKUnit.assertEqual(testButton.formattedText + "", "author num_comments", "Formatted string should be set");
}
helper.navigate(function () { return p; });
try {
testAction([p]);
}
finally {
helper.goBack();
}
}
export function test_searchbar_donotcrash_whentext_isempty() {
var p = <Page>builder.parse('<Page><SearchBar text="" hint="Search" /></Page>');
var sb = <searchBarModule.SearchBar>p.content;

View File

@ -10,6 +10,10 @@ export module knownCollections {
export var spans = "spans";
}
var CHILD_SPAN = "Span";
var CHILD_FORMATTED_TEXT = "formattedText";
var CHILD_FORMATTED_STRING = "FormattedString";
export class FormattedString extends observable.Observable implements definition.FormattedString, view.AddArrayFromBuilder {
private _spans: observableArray.ObservableArray<spanModule.Span>;
public _formattedText: any;
@ -212,4 +216,22 @@ export class FormattedString extends observable.Observable implements definition
span.bindingContext = newBindingContext;
}
}
public _addChildFromBuilder(name: string, value: any): void {
if(name === CHILD_SPAN) {
this.spans.push(value);
}
}
public static addFormattedStringToView(view: definition.FormattedStringView, name: string, value: any): void {
if(name === CHILD_SPAN) {
if (!view.formattedText) {
view.formattedText = new definition.FormattedString();
}
view.formattedText.spans.push(value);
}
else if (name === CHILD_FORMATTED_TEXT || name === CHILD_FORMATTED_STRING) {
view.formattedText = value;
}
}
}

View File

@ -8,10 +8,17 @@ declare module "text/formatted-string" {
import colorModule = require("color");
import view = require("ui/core/view");
/**
* Interface that specifies View that have formattedText property (like TextBase and Button).
*/
export interface FormattedStringView {
formattedText: FormattedString;
}
/**
* A class used to create a formatted (rich text) string.
*/
class FormattedString extends observable.Observable {
class FormattedString extends observable.Observable implements view.AddArrayFromBuilder, view.AddChildFromBuilder {
/**
* An observable collection of Span objects used to define common text properties.
*/
@ -72,5 +79,24 @@ declare module "text/formatted-string" {
* Gets the parent view of the formatted string.
*/
public parent: view.View;
/**
* A function that is called when an array declaration is found in xml.
* @param name - Name of the array.
* @param value - The actual value of the array.
*/
public _addArrayFromBuilder(name: string, value: Array<any>): void;
/**
* Called for every child element declared in xml.
* @param name - Name of the element.
* @param value - Value of the element.
*/
public _addChildFromBuilder(name: string, value: any): void;
/**
* A static method used to add child elements of the FormattedString class to a View declared in xml.
*/
public static addFormattedStringToView(view: FormattedStringView, name: string, value: any): void;
}
}

View File

@ -136,6 +136,8 @@ function parseInternal(value: string, context: any): componentBuilder.ComponentM
} else if (complexProperty) {
// Add component to complex property of parent component.
addToComplexProperty(parent, complexProperty, componentModule);
} else if ((<any>parent.component)._addChildFromBuilder) {
(<any>parent.component)._addChildFromBuilder(args.elementName, componentModule.component);
}
} else if (parents.length === 0) {
// Set root component.
@ -300,7 +302,7 @@ function addToComplexProperty(parent: componentBuilder.ComponentModule, complexP
if (isKnownCollection(complexProperty.name, parent.exports)) {
complexProperty.items.push(elementModule.component);
} else if (parentComponent._addChildFromBuilder) {
parentComponent._addChildFromBuilder("", elementModule.component);
parentComponent._addChildFromBuilder(complexProperty.name, elementModule.component);
} else {
// Or simply assign the value;
parentComponent[complexProperty.name] = elementModule.component;

View File

@ -104,4 +104,8 @@ export class Button extends view.View implements definition.Button {
}
this.setFormattedTextPropertyToNative(data.newValue);
}
public _addChildFromBuilder(name: string, value: any): void {
formattedString.FormattedString.addFormattedStringToView(this, name, value);
}
}

10
ui/button/button.d.ts vendored
View File

@ -10,7 +10,7 @@ declare module "ui/button" {
/**
* Represents a standard Button widget.
*/
export class Button extends view.View {
export class Button extends view.View implements formattedString.FormattedStringView, view.AddChildFromBuilder {
/**
* Represents the observable property backing the text property of each Button instance.
*/
@ -53,5 +53,13 @@ declare module "ui/button" {
* Raised when a tap event occurs.
*/
on(event: "tap", callback: (args: observable.EventData) => void, thisArg?: any);
/**
* Called for every child element declared in xml.
* This method will add a child element (value) to current element.
* @param name - Name of the element.
* @param value - Value of the element.
*/
_addChildFromBuilder(name: string, value: any): void;
}
}

2
ui/core/view.d.ts vendored
View File

@ -536,7 +536,7 @@ declare module "ui/core/view" {
interface AddChildFromBuilder {
/**
* Called for every child element declared in xml.
* This function will create an instance of declared child element.
* This method will add a child element (value) to current element.
* @param name - Name of the element.
* @param value - Value of the element.
*/

View File

@ -6,7 +6,7 @@
/**
* Represents the base class for all text views.
*/
export class TextBase extends view.View {
export class TextBase extends view.View implements view.AddChildFromBuilder, formattedString.FormattedStringView {
/**
* Dependency property used to support binding operations for the text of the current text-base instance.
@ -41,6 +41,14 @@
formattedText: formattedString.FormattedString;
_onTextPropertyChanged(data: dependencyObservable.PropertyChangeData);
/**
* Called for every child element declared in xml.
* This method will add a child element (value) to current element.
* @param name - Name of the element.
* @param value - Value of the element.
*/
_addChildFromBuilder(name: string, value: any): void;
}
/**

View File

@ -32,7 +32,7 @@ function onFormattedTextPropertyChanged(data: dependencyObservable.PropertyChang
(<proxy.PropertyMetadata>formattedTextProperty.metadata).onSetNativeValue = onFormattedTextPropertyChanged;
export class TextBase extends view.View implements definition.TextBase {
export class TextBase extends view.View implements definition.TextBase, formattedString.FormattedStringView {
public static textProperty = textProperty;
public static formattedTextProperty = formattedTextProperty;
@ -113,4 +113,8 @@ export class TextBase extends view.View implements definition.TextBase {
}
this.setFormattedTextPropertyToNative(data.newValue);
}
public _addChildFromBuilder(name: string, value: any): void {
formattedString.FormattedString.addFormattedStringToView(this, name, value);
}
}