POE-XUL

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

lib/POE/XUL/POE.pod
lib/POE/XUL/RDF.pm
lib/POE/XUL/Request.pm
lib/POE/XUL/Session.pm
lib/POE/XUL/State.pm
lib/POE/XUL/Style.pm
lib/POE/XUL/TWindow.pm
lib/POE/XUL/TextNode.pm
lib/POE/XUL/Window.pm
poe-xul/xul/index.html
poe-xul/xul/popup.xul
poe-xul/xul/something.js.build
poe-xul/xul/start.xul
t/00_compile.t
t/01_pod.t
t/10_node.t
t/11_mixedmode.t
t/12_style.t
t/20_changemanager.t
t/21_cm_instructions.t
t/22_cm_leaks.t

javascript/src/Application.js  view on Meta::CPAN

}

_.fireEvent_Command_Select = function ( domEvent ) {
    var target = domEvent.target;

    var realTarget = target;
    fb_log( 'target is %s', target.tagName );
    if( target.tagName == 'menuitem' ) {
        realTarget = target.parentNode;
    }
    // realTarget is the menupopup, search-list or menu

    if (realTarget.tagName == 'search-list') {
        // $debug( 'Select SearchList ' + realTarget.selectedIndex );
        this.fireEvent( 'Select', 
                        { 'target': realTarget },
                        { 'selectedIndex': realTarget.selectedIndex }
                      );
        return;
    } 

    fb_log( 'realTarget is %s', realTarget.tagName );
    if( realTarget.tagName == 'menupopup' )
        realTarget = realTarget.parentNode;
    // realTarget must now be the menulist
    fb_log( 'realTarget is finally %s#%s', realTarget.tagName, realTarget.id );

    fb_dir( { selectedIndex: realTarget.selectedIndex, 
                   realTarget: realTarget } );

    if (realTarget.tagName == 'menu') {
        // fb_log( "menu->Click" );
        this.fireEvent('Click', domEvent, {});

javascript/src/Application.js  view on Meta::CPAN

//      selectedId: itemId
//      checked: source.selected
//    For 'Select':
//      selectedIndex:
//      checked: source.selected
//    Conduit will add :
//      SID: current-SID,
//      reqN: 1++,
//    Added in setupEvent :
//      app: "IGDAIP", (or the application name)
//      window: popup-window-name
//  }

_.runRequest = function (event) {
    this.isNotCrashed();

    event = this.setupEvent( event );

    if( !event.event ) 
        event.event = 'boot';
    fb_log( "app=%s event=%s", event.app, event.event );

javascript/src/Application.js  view on Meta::CPAN

    if( w ) {    
        this.other_windows[ id ] = w;
        var self = this;

        w.addEventListener( 'unload', 
                        function (e) { self.closed( id, e ); return true; }, 
                        false 
                      );
    }
    else {
        alert( "Vous devez permetre des fen\xEAtres 'popup' pour ce site." );
    }
}

// ------------------------------------------------------------------
// Close a sub-window
_.closeWindow = function ( id ) {
    fb_log( id + ".close()" );
    var w = this.other_windows[ id ];

    if( !w ) {
        // either window was already closed, or we are the popup
        if( window.name == id ) {
            w = window;
        }
        else {
            fb_log( "Why don't I have window id", id ); 
            return;
        }
    }

    if( window.name == w.name ) {

javascript/src/Runner.js  view on Meta::CPAN

    }
    else if( methodName == 'ERROR' ) {
        $application.crash( arg1 );
    }
    else if( methodName == 'cdata' ) {
        this.commandCDATA( nodeId, arg1, arg2 );
    }
    else if( methodName == 'style' ) {
        this.commandStyle( nodeId, arg1, arg2 );
    }
    else if( methodName == 'popup_window' ) {
        this.commandPopupWindow( nodeId, arg1 );
    }
    else if( methodName == 'close_window' ) {
        this.commandCloseWindow( nodeId );
    }
    else if( methodName == 'timeslice' ) {
        // fb_log( methodName );
        rv = 2;
    }
    else if( window.name ) {

javascript/src/Runner.js  view on Meta::CPAN

    else if( element[att] ) {
        var code = element[att];
        delete element[att];
        element.removeEventListener( key, code, false );
    }
}

// ------------------------------------------------------------------
_.commandSelectedIndex = function ( element, value, _try ) {

    var doit = 0, popup = 0;
    if( !_try ) {
        doit = 0;
    }
    else if( element.tagName == 'radiogroup' ) {
        if( element.appendItem ) doit = 1;
    }
    else if( element.tagName == 'menulist' ) {
        popup = element.menupopup;
        if( element.menupopup ) doit = 1;
    }
    else {
        fb_log( "how to tell if %s is active?", element.tagName );
        doit = 1;
    }
    if( !doit ) {
        this.deferSelectedIndex( element, value, _try );
        return;
    }

javascript/src/Runner.js  view on Meta::CPAN

    var sel;
    element.setAttribute("suppressonselect", 'true');
    if( value >= 0 ) {
        // This line should be enough... BUT ISN'T!  
        // I hate you, Milkman Random Behaviour
        element.selectedIndex = value;

        // But this is stupid : menulist.xml does all the following (and more)
        // in <property name="selectedItem">
        // We do it anyway, and pray.
        if( popup ) {
            sel = popup.childNodes[value-0];
            if( sel ) {
                element.selectedItem = sel;
                // Setting .value on editable="true" will cause the 
                // item to disapear
                var editable = element.getAttribute( 'editable' );
                if (!editable || editable != 'true' ) {
                    // Next line forces the display to be updated in 
                    // some situations
                    element.value = sel.getAttribute( 'value' );
                }

javascript/src/Runner.js  view on Meta::CPAN

}

// ------------------------------------------------------------------
_.deferSelectedIndex = function ( element, value, _try ) {

    if( !_try ) 
        _try = 0;


    var id = element.getAttribute( 'id' );
    // fb_log( element.id + " has no menupopup try=" + _try );
    var tid = "TID.selectedIndex";
    _try++;
    if( _try < 6 ) {
        //if( _try > 1 )
        //    fb_log( "defering %s.selectedIndex try=%i", id, _try );

        // only the last one will stay in the loop
        if( this.timeouts[tid] ) {
            window.clearTimeout( this.timeouts[ tid ] );
        }

javascript/src/Runner.js  view on Meta::CPAN

    }
    feat += ",location="+( win.location ? 'yes' : 'no' );
    feat += ",menubar="+( win.menubar ? 'yes' : 'no' );
    feat += ",toolbar="+( win.toolbar ? 'yes' : 'no' );
    feat += ",status="+( win.status ? 'yes' : 'no' );
    feat += ",scrollbars="+( win.status ? 'yes' : 'no' );

    if( ! win.url ) {
        win.url = $application.baseURI();
        win.url = win.url.replace( "/xul", 
                         "/popup.xul?SID=" + $application.getSID() +
                         "&app=" + $application.applicationName );
    }
    $application.openWindow( win.url, id, feat );
}

// ------------------------------------------------------------------
_.commandCloseWindow = function (id) {
    fb_log( "Close window "+id );
    $application.closeWindow( id );
}

javascript/src/multikeypress.js  view on Meta::CPAN

// Find the item that best matches the pressed buffer.
_.select_item = function ( shorter ) {

    fb_log( "pressed='" + this.pressed + "'" );

    var menumenulist = this.menulist;
    if( this.pressed == '' ) {
        return;
    }

    var items = menumenulist.menupopup.childNodes;
    this.new_index = -1;
    var maybe = -1;
    var pressed = this.pressed.toLowerCase();
    var w = 1;
    if( shorter ) {
        if( menumenulist.selectedItem.label.substr(0,pressed.length).toLowerCase()
            == pressed ) {
            fb_log( "no change" );
            return;
        }

javascript/src/multikeypress.js  view on Meta::CPAN

// So the selection is done at timeout, when it's time to submit the
// new value
_.select = function ( new_index ) {
    fb_log( "want #" + new_index );
    if( this.menulist.selectedIndex != new_index ) {
        // Get this change to the server fast
        this.changed = 2;
    }
    this.menulist.selectedIndex = new_index;
    fb_log( "selected #" + this.menulist.selectedIndex );
    this.menulist.selectedItem = this.menulist.menupopup.childNodes[new_index];
    fb_log( "select label=" + this.menulist.menupopup.childNodes[new_index].label );

//    this.textbox.value = this.menulist.selectedItem.label.substr( 0, 2 );
}

// ------------------------------------------------------------------
// Wouldn't it be nice to know what element had focus previously? 
// Because we don't, we don't know when to skip this element.  90% of
// users won't know about shift-tab anyway
_.focus_menulist = function (event) {
}

javascript/src/util.js  view on Meta::CPAN


                    fb_log( widget.id + ".onclick=" + 
                            widget.attributes['onclick'] );
                }
            }
        }
    }
}

// ------------------------------------------------------------------
function popup ( id, e ) {
    var el = $( id );
    if( el ) {
        if( Element.visible( el ) ) 
            Element.hide( el );
        else 
            Element.show( el );
    }

    if( e ) {
        e.stopPropagation();

javascript/test/unit/util.html  view on Meta::CPAN

        assert( isalpha( 'a' ) );
        assert( isalpha( 'A' ) );
        assert( isalpha( 'é' ) );
        assert( isalpha( 'É' ) );

        assert( ! isalpha( ':' ) );
        assert( ! isalpha( '!' ) );
        assert( ! isalpha( '~' ) );
    }},

    // popup 
    test_popup: function() { with(this) {
        var something = $( 'something' );
        assert( something );
        assertNotVisible( something );
        
        popup( 'something' );
        assertVisible( something );
        Element.hide( something );
        assertNotVisible( something );
    }},

    // rollup
    test_rollup: function() { 
        var up = $( 'UP_roll' );
        this.assert( up );
        var down = $( 'DOWN_roll' );

lib/POE/XUL/ChangeManager.pm  view on Meta::CPAN

}

##############################################################
sub timeslice
{
    my( $self ) = @_;
    $self->Prepend( [ 'timeslice' ] );
}

##############################################################
sub popup_window
{
    my( $self, $name, $features ) = @_;
    $name     ||= $WIN_NAME++;
    $features ||= {};
    croak "Features must be a hashref" unless 'HASH' eq ref $features;
    $self->Prepend( [ 'popup_window', $name, $features ] );
    return $name;
}

##############################################################
sub close_window
{
    my( $self, $name ) = @_;
    $self->Prepend( [ 'close_window', $name ] );
}

lib/POE/XUL/ChangeManager.pm  view on Meta::CPAN


    if( $op eq 'flush' ) {                  # flush changes to output buffer
        return $self->flush_to_prepend;
    }
    elsif( $op eq 'empty' ) {               # empty all changes
        return $self->flush;
    }
    elsif( $op eq 'timeslice' ) {           # give up a timeslice
        return $self->timeslice;
    }
    elsif( $op eq 'popup_window' ) {
        return $self->popup_window( @param );
    }
    elsif( $op eq 'close_window' ) {
        return $self->close_window( @param );
    }
    else {
        die "Unknown instruction: $op";
    }
}

1;

lib/POE/XUL/ChangeManager.pm  view on Meta::CPAN


=item timeslice

Tells the javascript client library to give up a C<timeslice>.  The idea is
to give the browser time to I<render> any new XBL.  Because it is impossible
to find out when all XBL has finished rendering, the C<timeslice> is handled
by pausing for 5 milliseconds.

To be very useful, you should preceed this with a L</flush>.

=item popup_window

    pxInstruction( [ popup_window => $id, $features ] );

PLEASE USE L<POE::XUL::Window/open> INSTEAD.

Tell the client library to create a new window.  The new window's name will
be C<$id>.  The new window will be created with the features defined in
C<$features>: 
C<width>, 
C<height>, 
C<location>,
C<menubar>,
C<toolbar>,
C<status>,
C<scrollbars>.
The following features are always C<yes>:
C<resizable>,
C<dependent>.
See L<http://developer.mozilla.org/en/docs/DOM:window.open> for an explanation
of what they mean.

Once the window is opened, it will load C</popup.xul?app=$APP&SID=$SID> (where
C<$APP> is the current application and C<$SID> is the session ID of the
current application instance).  C<popup.xul> will then send a C<connect>
event.  See L<POE::XUL/connect>.



=item close_window

    pxInstruction( [ close_window => $id ] );

PLEASE USE L<POE::XUL::Window/close> INSTEAD.

lib/POE/XUL/Event.pm  view on Meta::CPAN

        window->getElementById( 'message' )->textNode( 'Sub-window opened' );
    }

Other applications  will need to create the
L<POE::XUL::Window> themselves.  C<$event->window> will be the window ID
as passed to C<"window->open()">.

    sub connect {
        my( $self, $event ) = @_[ OBJECT, ARG0 ];
        my $winID = $event->window;
        # create and popuplate the sub-window
        my $win = POE::XUL::Window( id=>$win, 
                                    Description( "Hello world!" ) 
                                  );
        $event->handled;
    }

=head2 disconnect

Called when the users closes a sub-window.

lib/POE/XUL/Node.pm  view on Meta::CPAN

=head2 get_child

    my $node = $parent->get_child( $index );

Use <POE::XUL::Window/getElementById> to find a node by its C<id>.

=head2 getItemAtIndex / get_item

    my $node = $menu->getItemAtIndex( $index );

Like L</get_child>, but works for C<menulist> and C<menupopup>.

=head2 lastChild / last_child

    my $node = $parent->lastChild;

=head2 removeChild / remove_child

    $parent->removeChild( $node );
    $parent->removeChild( $index );

lib/POE/XUL/Node.pm  view on Meta::CPAN


Returns this element and all its child elements as an unindented XML string.
Useful for debuging.

=head1 LIMITATIONS

=over 4

=item *

Some elements are not supported yet: tree, popup.

=item *

Some DOM features are not supported yet:

  * multiple selections
  * node disposal
  * color picker will not fire events if type is set to button
  * equalsize attribute will not work
  * menus with no popups may not show

=item *

Some XUL properties are implemented with XBL.  The front-end attempts to
wait for the XBL to be created before setting the property.  If the object
takes too long, the attribute is set instead.

What this means is that you can't reliably set the properties of freshly
created nodes.

lib/POE/XUL/Window.pm  view on Meta::CPAN

}

##############################################################
## DOM-like window.open( $name, $features );
sub open
{
    my( $self, $winID, $features ) = @_;

    # TODO: make sure $winID doesn't already exist

    # popup_window will allocate a winID if one doesn't exist already
    $winID = $POE::XUL::Node::CM->popup_window( $winID, $features );

    return unless $INC{'POE/XUL/Application.pm'};

    my $server = POE::XUL::Application::server();
    return unless $server;
    
    # Create a temporary window to hold the events until 'connect'
    my $twindow = POE::XUL::TWindow->new( %$features, id => $winID );
    $server->attach_subwindow( $twindow );
    return $twindow;

t/21_cm_instructions.t  view on Meta::CPAN

                [ 'new', 'PXN1', 'label', 'top', 2 ],
                [ 'textnode', 'PXN1', 0, 'honk' ],
                [ 'timeslice' ],
                [ 'for', '' ],
                [ 'new', 'PXN2', 'label', 'top', 3 ],
                [ 'textnode', 'PXN2', 0, 'bonk' ],
            ],  "Instructions: flush + timeslice" )
    or die Dumper $buffer;

#######
pxInstructions( 'popup_window' );
$buffer = $CM->flush;
is_deeply( $buffer, [
                [ 'popup_window', 'POEXUL000', {} ],
            ],  "Instruction: popup_window w/ defaults" )
    or die Dumper $buffer;

#######
pxInstructions( [ 'popup_window', 'honk' ] );
$buffer = $CM->flush;
is_deeply( $buffer, [
                [ 'popup_window', 'honk', {} ],
            ],  "Instruction: popup_window w/ default features" )
    or die Dumper $buffer;

#######
pxInstructions( [ 'popup_window', 'bonk', {width=>128} ] );
$buffer = $CM->flush;
is_deeply( $buffer, [
                [ 'popup_window', 'bonk', {width=>128} ],
            ],  "Instruction: popup_window" )
    or die Dumper $buffer;


#######
pxInstructions( [ 'popup_window', 'bonk', {width=>128} ], 
                'empty', 
                [ 'timeslice' ] 
              );
$buffer = $CM->flush;
is_deeply( $buffer, [ [ 'timeslice' ] ],  
            "Multiple instructions" )
    or die Dumper $buffer;

#######
my $ML = MenuList();

t/21_cm_instructions.t  view on Meta::CPAN



$W->appendChild( $ML );
$buffer = $CM->flush;
$Data::Dumper::Indent = 0;
$Data::Dumper::Terse = 1;
$Data::Dumper::Useqq = 1;
is_deeply( $buffer, [ [ 'for', '' ],
  [ "new", "PXN3", "menulist", "top", 4 ],
  ["set","PXN3","id","CWHat"],
  [ "new", "PXN4", "menupopup", "CWHat", 0 ],
  [ "new", "PXN5", "menuitem", "PXN4", 0 ],
  [ "set", "PXN5", "value", "honk" ],
  [ "textnode", "PXN5", 0, "Honking" ],
  [ "new", "PXN6", "menuitem", "PXN4", 1 ],
  [ "set", "PXN6", "value", "PTA" ],
  [ "set", "PXN6", "selected", "true" ],
  [ "textnode", "PXN6", 0, "Harper Value PTA" ],
  [ "set", "CWHat", "selectedIndex", 1 ],
],  
            "selectedIndex comes last" )

t/Client.pm  view on Meta::CPAN

        ok( !$self->{NODES}->{$new->{id}}, " ... never been framified" );
        $self->{NODES}->{$new->{id}} = $new;

        my $node = splice @{ $parent->{zC} }, $index, 1, $new;
        is( $old, $node, " ... it's right node" );
        $self->drop_node( $node );
    }
    elsif( $op eq 'timeslice' ) {
        # ignore
    }
    elsif( $op eq 'popup_window' ) {
        $self->popup_window( $id, @args );
    }
    elsif( $op eq 'close_window' ) {
        push @{ $self->{close_window} }, $id;
    }
    elsif( $op eq 'timeslice' ) {
        # ignore it
    }
    elsif( $op eq 'style' ) {
        ok( 2==@args, "Going to set style $args[0]" );
        ok( $self->{NODES}->{$id}, " ... on an existing node" )

t/Client.pm  view on Meta::CPAN

            printf "%d,%dc%d,%d\n",
               $diff->Get(qw( Min1 Max1 Min2 Max2 ));
        }
        print "- $_\n"   for  $diff->Items(1);
        # print $sep;
        print "+ $_\n"   for  $diff->Items(2);
    }
}

############################################################
sub popup_window
{
    my( $self, $id, @args ) = @_;
    
    ok( !$self->{windows}{$id}, "Popup window $id" )
            or die "Pain follows";

    push @{ $self->{new_windows} }, $id;
    $self->{windows}{ $id } = { id => $id };
}

t/test-app.pl  view on Meta::CPAN

{
    my( $self, $kernel, $event ) = @_[ OBJECT, KERNEL, ARG0 ];

    DEBUG and warn "# MenuSelect event=$event";

    my $menulist = $event->source;

    my $index = $menulist->selectedIndex;
    DEBUG and warn "# Selected index=$index";

    my $popup = $menulist->firstChild;
    my $item  = $popup->get_item( $index );

    $self->message( "You chose ".$item->label );
}


###############################################################
sub ListSelect
{
    my( $self, $kernel, $event ) = @_[ OBJECT, KERNEL, ARG0 ];



( run in 2.625 seconds using v1.01-cache-2.11-cpan-364913b4093 )