Skip to content

fix(android): expose missing UI properties/constants, defaults, and parent setter (needed for other PR's because of 'setParentInternal' method) - #14524

Open
mbender74 wants to merge 1 commit into
tidev:mainfrom
mbender74:android-ui-properties-defaults
Open

fix(android): expose missing UI properties/constants, defaults, and parent setter (needed for other PR's because of 'setParentInternal' method)#14524
mbender74 wants to merge 1 commit into
tidev:mainfrom
mbender74:android-ui-properties-defaults

Conversation

@mbender74

@mbender74 mbender74 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

This two PR's need this PR to be merged first:
#14523 and #14522

  • Exposes missing properties and constants across TableView, TableViewRow, TableViewSection, TiTableView, ListView, ListSection, ListItem, TiListView, TiUITab, and UIModule for cross-platform parity.
  • Registers documented defaults for AlertDialog and OptionDialog.
  • Adds the parent setter on TiViewProxy so proxy parenting works.

@mbender74 mbender74 changed the title fix(android): expose missing UI properties/constants, defaults, and parent setter fix(android): expose missing UI properties/constants, defaults, and parent setter (needed for other PR's because of 'setParentInternal' method) Jul 16, 2026
@mbender74

Copy link
Copy Markdown
Contributor Author

Test:

// app.js — Test for PR #14524 (android-ui-properties-defaults)
 // Run against main (broken/missing) and the PR branch (fixed/exposed) and compare.
 // ES5 only.

 var TEXT_STYLES = [
     ['TEXT_STYLE_HEADLINE',     'UIFontTextStyleHeadline'],
     ['TEXT_STYLE_SUBHEADLINE',  'UIFontTextStyleSubheadline'],
     ['TEXT_STYLE_BODY',         'UIFontTextStyleBody'],
     ['TEXT_STYLE_FOOTNOTE',     'UIFontTextStyleFootnote'],
     ['TEXT_STYLE_CAPTION1',     'UIFontTextStyleCaption1'],
     ['TEXT_STYLE_CAPTION2',     'UIFontTextStyleCaption2'],
     ['TEXT_STYLE_CALLOUT',      'UIFontTextStyleCallout'],
     ['TEXT_STYLE_TITLE1',       'UIFontTextStyleTitle1'],
     ['TEXT_STYLE_TITLE2',       'UIFontTextStyleTitle2'],
     ['TEXT_STYLE_TITLE3',       'UIFontTextStyleTitle3'],
     ['TEXT_STYLE_LARGE_TITLE',  'UIFontTextStyleLargeTitle']
 ];

 function isArr(v) {
     return Object.prototype.toString.call(v) === '[object Array]';
 }

 function runTest() {
     var lines = [];
     function log(msg) { Ti.API.info(msg); lines.push(msg); }

     log('--- PR #14524 test: UI properties/defaults/parent setter ---');
     log('Titanium SDK: ' + Ti.version);
     log('Platform: ' + Ti.Platform.osname + ' ' + Ti.Platform.version);
     log('');

     var pass = 0, fail = 0;

     // 1. TEXT_STYLE_* constants
     log('=== 1. Ti.UI.TEXT_STYLE_* constants ===');
     for (var i = 0; i < TEXT_STYLES.length; i++) {
         var name = TEXT_STYLES[i][0];
         var expected = TEXT_STYLES[i][1];
         var actual = Ti.UI[name];
         if (actual === expected) {
             log('  PASS  Ti.UI.' + name + ' = ' + actual);
             pass++;
         } else {
             log('  FAIL  Ti.UI.' + name + ' = ' + actual + ' (expected "' + expected + '")');
             fail++;
         }
     }
     log('');

     // 2. AlertDialog defaults
     log('=== 2. AlertDialog defaults ===');
     var alert = Ti.UI.createAlertDialog();
     var aButtonNames = alert.buttonNames;
     var aCancel = alert.cancel;
     if (isArr(aButtonNames) && aButtonNames.length === 0) {
         log('  PASS  AlertDialog.buttonNames = [] (length ' + aButtonNames.length + ')');
         pass++;
     } else {
         log('  FAIL  AlertDialog.buttonNames = ' + aButtonNames + ' (expected empty array)');
         fail++;
     }
     if (aCancel === -1) {
         log('  PASS  AlertDialog.cancel = -1');
         pass++;
     } else {
         log('  FAIL  AlertDialog.cancel = ' + aCancel + ' (expected -1)');
         fail++;
     }
     log('');

     // 3. OptionDialog defaults
     log('=== 3. OptionDialog defaults ===');
     var opt = Ti.UI.createOptionDialog();
     var oPersistent = opt.persistent;
     var oButtonNames = opt.buttonNames;
     var oCancel = opt.cancel;
     var oSelectedIndex = opt.selectedIndex;
     if (oPersistent === true) {
         log('  PASS  OptionDialog.persistent = true');
         pass++;
     } else {
         log('  FAIL  OptionDialog.persistent = ' + oPersistent + ' (expected true)');
         fail++;
     }
     if (isArr(oButtonNames) && oButtonNames.length === 0) {
         log('  PASS  OptionDialog.buttonNames = [] (length ' + oButtonNames.length + ')');
         pass++;
     } else {
         log('  FAIL  OptionDialog.buttonNames = ' + oButtonNames + ' (expected empty array)');
         fail++;
     }
     if (oCancel === -1) {
         log('  PASS  OptionDialog.cancel = -1');
         pass++;
     } else {
         log('  FAIL  OptionDialog.cancel = ' + oCancel + ' (expected -1)');
         fail++;
     }
     if (oSelectedIndex === -1) {
         log('  PASS  OptionDialog.selectedIndex = -1');
         pass++;
     } else {
         log('  FAIL  OptionDialog.selectedIndex = ' + oSelectedIndex + ' (expected -1)');
         fail++;
     }
     log('');

     // 4. setParent / parent setter (best-effort, internal behavior)
     log('=== 4. setParent / parent setter ===');
     var parent1 = Ti.UI.createView();
     var child = Ti.UI.createView();
     parent1.add(child);
     // child.parent should be parent1 after add
     var childParentBefore = child.parent;
     log('  child.parent after add = ' + (childParentBefore === parent1 ? 'parent1 (correct)' : String(childParentBefore)));
     // set parent to null via JS (PR: triggers setParent(null) -> detach; main: just dict write)
     try {
         child.parent = null;
         log('  child.parent = null -> executed without error');
         pass++;
     } catch (e) {
         log('  FAIL  child.parent = null threw: ' + e);
         fail++;
     }
     var childParentAfter = child.parent;
     log('  child.parent after =null = ' + String(childParentAfter));
     log('  (note: setParentInternal is internal; the dependent PRs #14523/#14522 exercise it via TableView/ListView/TabGroup)');
     log('');

     // Verdict
     log('=== Verdict ===');
     log('  PASS: ' + pass + '  FAIL: ' + fail);
     if (fail === 0) {
         log('  RESULT: PR applied — all TEXT_STYLE_* constants, AlertDialog/OptionDialog defaults present');
     } else {
         log('  RESULT: main behavior — ' + fail + ' check(s) missing (constants undefined / defaults unset)');
     }

     return lines.join('\n');
 }

 var win = Ti.UI.createWindow({
     backgroundColor: '#ffffff',
     layout: 'vertical',
     exitOnClose: true
 });

 var title = Ti.UI.createLabel({
     top: 30, left: 20, right: 20, height: Ti.UI.SIZE,
     text: 'PR #14524 test',
     color: '#000000',
     font: { fontSize: 18, fontWeight: 'bold' }
 });
 win.add(title);

 var result = Ti.UI.createLabel({
     top: 20, left: 20, right: 20, height: Ti.UI.SIZE,
     color: '#000000',
     font: { fontSize: 11, fontFamily: 'monospace' },
     text: 'Press "Run test" to start.'
 });
 win.add(result);

 var button = Ti.UI.createButton({
     top: 20, left: 20, right: 20, height: Ti.UI.SIZE,
     title: 'Run test'
 });
 button.addEventListener('click', function () {
     result.text = runTest();
 });
 win.add(button);

 win.open();

Result current Main (13.3.1.GA):

[INFO]  --- PR #14524 test: UI properties/defaults/parent setter ---
[INFO]  Titanium SDK: 13.2.0
[INFO]  Platform: android 16
[INFO]  
[INFO]  === 1. Ti.UI.TEXT_STYLE_* constants ===
[INFO]    FAIL  Ti.UI.TEXT_STYLE_HEADLINE = undefined (expected "UIFontTextStyleHeadline")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_SUBHEADLINE = undefined (expected "UIFontTextStyleSubheadline")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_BODY = undefined (expected "UIFontTextStyleBody")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_FOOTNOTE = undefined (expected "UIFontTextStyleFootnote")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_CAPTION1 = undefined (expected "UIFontTextStyleCaption1")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_CAPTION2 = undefined (expected "UIFontTextStyleCaption2")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_CALLOUT = undefined (expected "UIFontTextStyleCallout")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_TITLE1 = undefined (expected "UIFontTextStyleTitle1")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_TITLE2 = undefined (expected "UIFontTextStyleTitle2")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_TITLE3 = undefined (expected "UIFontTextStyleTitle3")
[INFO]    FAIL  Ti.UI.TEXT_STYLE_LARGE_TITLE = undefined (expected "UIFontTextStyleLargeTitle")
[INFO]  
[INFO]  === 2. AlertDialog defaults ===
[INFO]    FAIL  AlertDialog.buttonNames = undefined (expected empty array)
[INFO]    FAIL  AlertDialog.cancel = undefined (expected -1)
[INFO]  
[INFO]  === 3. OptionDialog defaults ===
[INFO]    FAIL  OptionDialog.persistent = undefined (expected true)
[INFO]    FAIL  OptionDialog.buttonNames = undefined (expected empty array)
[INFO]    FAIL  OptionDialog.cancel = undefined (expected -1)
[INFO]    FAIL  OptionDialog.selectedIndex = undefined (expected -1)
[INFO]  
[INFO]  === 4. setParent / parent setter ===
[INFO]    child.parent after add = parent1 (correct)
[INFO]    child.parent = null -> executed without error
[INFO]    child.parent after =null = [object Object]
[INFO]    (note: setParentInternal is internal; the dependent PRs #14523/#14522 exercise it via TableView/ListView/TabGroup)
[INFO]  
[INFO]  === Verdict ===
[INFO]    PASS: 1  FAIL: 17
[INFO]    RESULT: main behavior — 17 check(s) missing (constants undefined / defaults unset)

Result with this PR:

[INFO]  --- PR #14524 test: UI properties/defaults/parent setter ---
[INFO]  Titanium SDK: 14.0.0
[INFO]  Platform: android 16
[INFO]  
[INFO]  === 1. Ti.UI.TEXT_STYLE_* constants ===
[INFO]    PASS  Ti.UI.TEXT_STYLE_HEADLINE = UIFontTextStyleHeadline
[INFO]    PASS  Ti.UI.TEXT_STYLE_SUBHEADLINE = UIFontTextStyleSubheadline
[INFO]    PASS  Ti.UI.TEXT_STYLE_BODY = UIFontTextStyleBody
[INFO]    PASS  Ti.UI.TEXT_STYLE_FOOTNOTE = UIFontTextStyleFootnote
[INFO]    PASS  Ti.UI.TEXT_STYLE_CAPTION1 = UIFontTextStyleCaption1
[INFO]    PASS  Ti.UI.TEXT_STYLE_CAPTION2 = UIFontTextStyleCaption2
[INFO]    PASS  Ti.UI.TEXT_STYLE_CALLOUT = UIFontTextStyleCallout
[INFO]    PASS  Ti.UI.TEXT_STYLE_TITLE1 = UIFontTextStyleTitle1
[INFO]    PASS  Ti.UI.TEXT_STYLE_TITLE2 = UIFontTextStyleTitle2
[INFO]    PASS  Ti.UI.TEXT_STYLE_TITLE3 = UIFontTextStyleTitle3
[INFO]    PASS  Ti.UI.TEXT_STYLE_LARGE_TITLE = UIFontTextStyleLargeTitle
[INFO]  
[INFO]  === 2. AlertDialog defaults ===
[INFO]    PASS  AlertDialog.buttonNames = [] (length 0)
[INFO]    PASS  AlertDialog.cancel = -1
[INFO]  
[INFO]  === 3. OptionDialog defaults ===
[INFO]    PASS  OptionDialog.persistent = true
[INFO]    PASS  OptionDialog.buttonNames = [] (length 0)
[INFO]    PASS  OptionDialog.cancel = -1
[INFO]    PASS  OptionDialog.selectedIndex = -1
[INFO]  
[INFO]  === 4. setParent / parent setter ===
[INFO]    child.parent after add = parent1 (correct)
[INFO]    child.parent = null -> executed without error
[INFO]    child.parent after =null = null
[INFO]    (note: setParentInternal is internal; the dependent PRs #14523/#14522 exercise it via TableView/ListView/TabGroup)
[INFO]  
[INFO]  === Verdict ===
[INFO]    PASS: 18  FAIL: 0
[INFO]    RESULT: PR applied — all TEXT_STYLE_* constants, AlertDialog/OptionDialog defaults present

@hansemannn hansemannn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned earlier, adding stubs like TEXT_STYLE_HEADLINE is not real cross-platform parity, so we're trying to prevent that. also, a new setParentInternal is not encouraged and should instead be handled as part of the existing API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants