464 строки
19 KiB
TypeScript
464 строки
19 KiB
TypeScript
///<reference path='refs.ts'/>
|
|
module TDev { export module RT {
|
|
|
|
//? Current box element in the page.
|
|
//@ skill(2)
|
|
export module Box
|
|
{
|
|
var R = HTML;
|
|
|
|
// Start new definition of a box
|
|
export function push_box(s:IStackFrame) : void
|
|
{
|
|
if (!LayoutMgr.RenderExecutionMode())
|
|
Util.userError(lf("boxes can only be created in page display code"));
|
|
var parent = LayoutMgr.getCurrentRenderBox();
|
|
Util.assert(parent != null);
|
|
|
|
LayoutMgr.createOrRecycleContainerBoxDelayed(s.rt, parent);
|
|
|
|
// var w:WallBox = WallBox.CreateOrRecycleContainerBox(s.rt, parent);
|
|
// LayoutMgr.setCurrentRenderBox(w);
|
|
}
|
|
|
|
// Finish the box definition
|
|
export function pop_box(s:IStackFrame) : void
|
|
{
|
|
Util.assert(LayoutMgr.RenderExecutionMode());
|
|
var box = LayoutMgr.getCurrentRenderBox();
|
|
//Util.log("pop box " + box.depth + " " + box.id);
|
|
var parent = box.parent;
|
|
Util.assert(parent != null);
|
|
LayoutMgr.setCurrentRenderBox(box.parent);
|
|
}
|
|
|
|
|
|
//? Sets the foreground color of elements.
|
|
//@ [color].deflExpr('colors->random')
|
|
export function set_foreground(color:Color, s:IStackFrame) : void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setForeground(color.toHtml(), s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Sets the background color.
|
|
//@ [color].deflExpr('colors->random')
|
|
export function set_background(color:Color, s:IStackFrame) : void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setBackground(color.toHtml(), s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Sets the background picture. The picture must be a resource or from the web. The size of the picture does not impact the size of the box.
|
|
//@ [position].deflStrings('center center', 'left top', 'left center', 'left bottom', 'right top', 'right center','right bottom','center top','center bottom')
|
|
//@ [size].deflStrings('cover', 'contain', 'auto')
|
|
//@ [repeat].deflStrings('no-repeat', 'repeat', 'repeat-x', 'repeat-y')
|
|
//@ [attachment].deflStrings('scroll', 'fixed', 'local')
|
|
export function add_background_picture(pic: Picture, position : string, size : string, repeat : string, attachment : string, s: IStackFrame) {
|
|
var url = pic.getReadonlyUrlSync();
|
|
function validate(str: string): string {
|
|
var r = str.toLowerCase().trim();
|
|
if (!/^[a-z %0-9\-]*$/.test(r)) {
|
|
App.log('invalid box background value: ' + r);
|
|
return '';
|
|
}
|
|
return r;
|
|
}
|
|
if (url) {
|
|
var box = s.rt.getCurrentBox();
|
|
box.addBackgroundImage({
|
|
url: url,
|
|
position:validate(position),
|
|
size: validate(size),
|
|
repeat: validate(repeat),
|
|
attachment:validate(attachment)
|
|
}, s.rt.getTopScriptPc());
|
|
}
|
|
}
|
|
|
|
//? Arrange boxes inside this box from top to bottom.
|
|
export function use_vertical_layout(s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setFlow(WallBox.FLOW_VERTICAL, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Arrange boxes inside this box from left to right.
|
|
export function use_horizontal_layout(s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setFlow(WallBox.FLOW_HORIZONTAL, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Arrange boxes inside this box as layers on top of each other.
|
|
export function use_overlay_layout(s:IStackFrame): void {
|
|
var box = s.rt.getCurrentBox();
|
|
box.setFlow(WallBox.FLOW_OVERLAY, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
//? Set the width of this box.
|
|
export function set_width(width:number, s:IStackFrame) : void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setEmWidth(width, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Set the height of this box.
|
|
export function set_height(height:number, s:IStackFrame) : void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setEmHeight(height, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Set lower and upper limits on the width of this box.
|
|
export function set_width_range(min_width: number, max_width: number, s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setEmWidthRange(min_width, max_width, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Set lower and upper limits on the height of this box.
|
|
export function set_height_range(min_height: number, max_height: number, s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setEmHeightRange(min_height, max_height, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Specify how to compute box width (0 = shrink to fit content, 1 = stretch to fit frame, , 0.5 = stretch to half width)
|
|
//@ [elasticity].defl(1)
|
|
export function set_horizontal_stretch(elasticity: number, s: IStackFrame): void {
|
|
var n = elasticity;
|
|
var box = s.rt.getCurrentBox();
|
|
if (n < 0 || n > 1) {
|
|
Util.userError(lf("invalid argument: elasticity must be a number between 0 and 1"));
|
|
n = 0;
|
|
}
|
|
box.setHorizontalStretch(n, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Specify how to compute box height (0 = shrink to fit content, 1 = stretch to fit frame, 0.5 = stretch to half height)
|
|
//@ [elasticity].defl(1)
|
|
export function set_vertical_stretch(elasticity: number, s: IStackFrame): void {
|
|
var n = elasticity;
|
|
var box = s.rt.getCurrentBox();
|
|
if (n < 0 || n > 1) {
|
|
Util.userError(lf("invalid argument: elasticity must be a number between 0 and 1"));
|
|
n = 0;
|
|
}
|
|
box.setVerticalStretch(n, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Set the color and width of the border.
|
|
//@ [color].deflExpr('colors->foreground') [width].defl(0.1)
|
|
export function set_border(color: Color, width: number, s:IStackFrame): void {
|
|
var box = s.rt.getCurrentBox();
|
|
box.setEmBorder(color.toHtml(), width, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
//? Set the width of each border.
|
|
export function set_border_widths(top:number, right:number, bottom:number, left:number, s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setEmBorderWidth(top, right, bottom, left, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Set the margins of this box (to leave space around the outside of this box).
|
|
//@ [left].defl(0.5) [top].defl(0.5)
|
|
export function set_margins(top: number, right: number, bottom: number, left: number, s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setAllEmMargins(top, right, bottom, left, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
//? Set the padding of this box (to leave space around the contents of this box).
|
|
export function set_padding(top: number, right: number, bottom: number, left: number, s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setEmPadding(top, right, bottom, left, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set the weights for extending the margins of this box.
|
|
//export function stretch_margins(top:number, right:number, bottom:number, left:number, s:IStackFrame) : void
|
|
//{
|
|
// var box = s.rt.getCurrentBox();
|
|
// box.stretchAllMargins(top, right, bottom, left, s.rt.getTopScriptPc());
|
|
//}
|
|
// Set the weight for extending the width of this box.
|
|
//export function stretch_width(weight:number, s:IStackFrame) : void
|
|
//{
|
|
// var box = s.rt.getCurrentBox();
|
|
// box.setWidthStretch(weight, s.rt.getTopScriptPc());
|
|
//}
|
|
// Set the weight for extending the height of this box.
|
|
//export function stretch_height(weight:number, s:IStackFrame) : void
|
|
//{
|
|
// var box = s.rt.getCurrentBox();
|
|
// box.setHeightStretch(weight, s.rt.getTopScriptPc());
|
|
//}
|
|
|
|
//? align (0,0)=center (1,0)=left, (0,1)=right, (1,1)=stretch
|
|
//@ obsolete
|
|
export function set_horizontal_alignment(left: number, right: number, s: IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setHorizontalAlignment(left, right, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? align (0,0)=center (1,0)=top, (0,1)=bottom, (1,1)=stretch
|
|
//@ obsolete
|
|
export function set_vertical_alignment(top:number, bottom:number, s: IStackFrame) : void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setVerticalAlignment(top, bottom, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Specify how to arrange the content of this box
|
|
//@ [arrange].defl("left") [arrange].deflStrings("center", "left", "right", "justify", "spread")
|
|
export function set_horizontal_align(arrange:string, s: IStackFrame): void {
|
|
var box = s.rt.getCurrentBox();
|
|
var a = WallBox.ARRANGE_LEFT;
|
|
var what = arrange;
|
|
if (what === "left")
|
|
a = WallBox.ARRANGE_LEFT;
|
|
else if (what === "right")
|
|
a = WallBox.ARRANGE_RIGHT;
|
|
else if (what === "center")
|
|
a = WallBox.ARRANGE_CENTER;
|
|
else if (what === "justify")
|
|
a = WallBox.ARRANGE_JUSTIFY;
|
|
else if (what === "spread")
|
|
a = WallBox.ARRANGE_SPREAD;
|
|
else
|
|
Util.userError(lf("horizontal align must be one of {left, right, center, justify, spread}"));
|
|
box.setHorizontalArrangement(a, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Specify how to arrange the content of this box
|
|
//@ [arrange].defl("baseline") [arrange].deflStrings("baseline", "top", "bottom", "center", "justify", "spread")
|
|
export function set_vertical_align(arrange:string, s: IStackFrame): void {
|
|
var box = s.rt.getCurrentBox();
|
|
var a = WallBox.ARRANGE_TOP;
|
|
var what = arrange;
|
|
if (what === "top")
|
|
a = WallBox.ARRANGE_TOP;
|
|
else if (what === "bottom")
|
|
a = WallBox.ARRANGE_BOTTOM;
|
|
else if (what === "center")
|
|
a = WallBox.ARRANGE_CENTER;
|
|
else if (what === "justify")
|
|
a = WallBox.ARRANGE_JUSTIFY;
|
|
else if(what === "baseline")
|
|
a = WallBox.ARRANGE_BASELINE;
|
|
else if (what === "spread")
|
|
a = WallBox.ARRANGE_SPREAD;
|
|
else
|
|
Util.userError(lf("vertical align must be one of {baseline, top, bottom, center, justify, spread}"));
|
|
box.setVerticalArrangement(a, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
|
|
//? Set font size in this box and contained boxes.
|
|
//@ [font_size].defl(1)
|
|
export function set_font_size(font_size: number, s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setEmFontSize(font_size, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
//? Set font weight in this box and contained boxes.
|
|
//@ [font_weight].defl("bold") [font_weight].deflStrings("normal", "bold", "lighter", "bolder")
|
|
export function set_font_weight(font_weight: string, s: IStackFrame): void {
|
|
var box = s.rt.getCurrentBox();
|
|
box.setFontWeight(font_weight, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
//? Set font family in this box and contained boxes.
|
|
//@ [family].defl("Default") [family].deflStrings("Default", "Arial, Helvetica, sans-serif", "Courier New, Courier, monospace", "Georgia, serif", "Lucida Console, Monaco, monospace", "Lucida Sans Unicode, Lucida Grande, sans - serif", "Palatino Linotype, Book Antiqua, Palatino, serif", "Tahoma, Geneva, sans - serif", "Times New Roman, Times, serif", "Trebuchet MS, sans-serif", "Verdana, Geneva, sans-serif", "Comic Sans MS, cursive")
|
|
//@ dbgOnly
|
|
export function set_font_family(family: string, s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setFontFamily(family, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Specify whether to use scrollbars on overflow.
|
|
//@ [horizontal_scrolling].defl(true) [vertical_scrolling].defl(true)
|
|
export function set_scrolling(horizontal_scrolling: boolean, vertical_scrolling: boolean, s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setScrolling(horizontal_scrolling, vertical_scrolling, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
//? Set what happens when the box is tapped.
|
|
export function on_tapped(handler:Action, s:IStackFrame) : void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.attributes.tappedEvent.addHandler(handler);
|
|
}
|
|
|
|
// //? Set what happens when the box is tapped.
|
|
// export function on_edit(handler: Action, s: IStackFrame): void {
|
|
// var box = s.rt.getCurrentBox();
|
|
// box.attributes.editEvent.addHandler(handler);
|
|
// }
|
|
|
|
|
|
//? Set what happens whenever the text in the box is being edited.
|
|
//@ obsolete
|
|
export function on_text_editing(handler:TextAction, s:IStackFrame) : void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.attributes.textEditingEvent.addHandler(handler);
|
|
}
|
|
|
|
|
|
//? Set what happens when the user has finished editing the text in the box.
|
|
//@ obsolete
|
|
export function on_text_edited(handler:TextAction, s:IStackFrame): void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.attributes.textEditedEvent.addHandler(handler);
|
|
}
|
|
|
|
//? Display editable text.
|
|
//@ obsolete
|
|
//@ [text].defl("") [multiline].defl(true)
|
|
export function edit_text(text: string, multiline: boolean, s: IStackFrame): void {
|
|
s.rt.postEditableText(multiline ? "textarea" : "textline", text, null, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
|
|
//? Display editable text, for the given content and change handler.
|
|
//@ [style].defl("textline") [style].deflStrings("textline", "textarea", "number", "password")
|
|
export function edit(style: string, value: string, changehandler:TextAction, s: IStackFrame): void {
|
|
s.rt.postEditableText(style, value, changehandler, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Display editable text, bound to the given string reference.
|
|
//@ [style].defl("textline") [style].deflStrings("textline", "textarea", "number", "password")
|
|
export function edit_ref(style: string, ref:Ref<string>, s: IStackFrame): void {
|
|
s.rt.postEditableText(style, ref._get(s), ref, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
//?
|
|
//@ hidden
|
|
export function is_init(s:IStackFrame): boolean
|
|
{
|
|
return s.rt.getCurrentPage().renderCount == 0;
|
|
}
|
|
|
|
//? Get the total width of the page.
|
|
export function page_width(s:IStackFrame) : number
|
|
{
|
|
// must leave room for scrollbar, otherwise we get double scroll bars
|
|
return (s.rt.host.fullWallWidth() - LayoutMgr.instance.scrollbarWidth) / SizeMgr.topFontSize;
|
|
}
|
|
|
|
//? Get the total height of the page.
|
|
export function page_height(s:IStackFrame) : number
|
|
{
|
|
return s.rt.host.userWallHeight() / SizeMgr.topFontSize;
|
|
}
|
|
|
|
//? Get the number of pixels in an em
|
|
export function pixels_per_em(): number {
|
|
return SizeMgr.topFontSize;
|
|
}
|
|
|
|
//? Set whether to break long lines, and specify what length is too short for breaking
|
|
//@ [wrap].readsMutable
|
|
//@ [wrap].defl(true) [minimumwidth].defl(15)
|
|
export function set_text_wrapping(wrap:boolean, minimumwidth:number, s:IStackFrame) : void
|
|
{
|
|
var box = s.rt.getCurrentBox();
|
|
box.setWrap(wrap, minimumwidth, s.rt.getTopScriptPc());
|
|
}
|
|
}
|
|
|
|
//? Current html element in the page.
|
|
//@ betaOnly skill(2)
|
|
export module Dom {
|
|
//? Use CSS for layout and import additional CSS stylesheets. Use string art resource to import urls.
|
|
//@ betaOnly
|
|
export function use_css(stylesheet: string, s: IStackFrame): void {
|
|
s.rt.forceNonRender(lf("cannot change css while displaying page"));
|
|
s.rt.getCurrentPage().csslayout = true;
|
|
s.rt.applyPageAttributes(true);
|
|
if (stylesheet)
|
|
(<any>s.rt.host).importCss(stylesheet)
|
|
}
|
|
|
|
//? Specify the tagname for this element
|
|
//@ betaOnly
|
|
export function set_tag_name(name: string, s: IStackFrame): void {
|
|
if (!name) return;
|
|
if (!HTML.allowedTagName(name))
|
|
Util.userError(lf("tag not allowed"), s.pc);
|
|
LayoutMgr.setHtmlTagName(name);
|
|
}
|
|
|
|
//? Add a CSS class name to the current element.
|
|
//@ betaOnly
|
|
export function add_css_class(name: string, s: IStackFrame): void {
|
|
if (!name) return;
|
|
|
|
var box = s.rt.getCurrentHtmlBox();
|
|
box.addClassName(name, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Specify an attribute for the current element.
|
|
//@ betaOnly
|
|
export function set_attribute(name: string, value: string, s: IStackFrame): void {
|
|
if (!name) return;
|
|
if (!HTML.allowedAttribute(name, value))
|
|
Util.userError(lf("attribute not allowed"), s.pc);
|
|
var box = s.rt.getCurrentHtmlBox();
|
|
box.setAttribute(name, value, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Specify a style attribute for the current element.
|
|
//@ betaOnly
|
|
export function set_style(property: string, value: string, s: IStackFrame): void {
|
|
if (!property) return;
|
|
|
|
var box = s.rt.getCurrentHtmlBox();
|
|
box.setStyle(property,value, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Bind editable text, by giving current text and change handler.
|
|
//@ betaOnly
|
|
export function bind_value_with_handler(value: string, changehandler: TextAction, s: IStackFrame): void {
|
|
var box = s.rt.getCurrentHtmlBox();
|
|
box.bindEditableText(value, changehandler, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
//? Bind editable text, using a string reference.
|
|
//@ betaOnly
|
|
export function bind_value_to_ref(ref: Ref<string>, s: IStackFrame): void {
|
|
var box = s.rt.getCurrentHtmlBox();
|
|
box.bindEditableText(ref._get(s), ref, s.rt.getTopScriptPc());
|
|
}
|
|
|
|
|
|
//? Set what happens when this element is clicked.
|
|
//@ betaOnly
|
|
export function add_on_click(body: Action, s: IStackFrame): void {
|
|
var box = s.rt.getCurrentHtmlBox();
|
|
box.attributes.tappedEvent.addHandler(body);
|
|
}
|
|
|
|
}
|
|
} }
|