POE-XUL

 view release on metacpan or  search on metacpan

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

// Returning 1 means we want to give up a timeslice
_.runCommand = function (command) {
    var methodName = command['methodName'];
    var nodeId     = command['nodeId'];
    var arg1       = command['arg1'];
    var arg2       = command['arg2'];
    var arg3       = command['arg3'];
    var rv         = 0;
    if (methodName == 'new') {
        if (arg1 == 'window')
            this.commandNewWindow(nodeId);
        else
            this.commandNewElement(nodeId, arg1, arg2, arg3);
    }
    else if (methodName == 'textnode' ) {
        this.commandNewTextNode( nodeId, arg1, arg2 );
    }
    else if (methodName == 'SID') {
        $application.setSID( nodeId );
    }
    else if (methodName == 'boot') {
        if( $status )
            $status.title( nodeId );
        this.booting = true;
        rv = 1;
    }
    else if ( methodName == 'bye' ) {
        this.commandByeElement(nodeId);
    }
    else if ( methodName == 'bye-textnode' ) {
        this.commandByeTextNode( nodeId , arg1 );
    }
    else if( methodName == 'set' ) {
        if ( !this.late && ( POEXUL_Runner.lateAttributes[arg1] || 
                        this.isLateCommand( command ) ) ) {
            // fb_log( 'late = ' + nodeId + "." + arg1 + "=" + arg2 );
            this.lateCommands.push(command);
        }
        else {
            rv = this.commandSetNode(nodeId, arg1, arg2);
        }
    }
    else if( methodName == 'remove' ) {
        this.commandRemoveAttribute(nodeId, arg1);
    }
    else if( methodName == 'method' ) {
        this.commandMethod(nodeId, arg1, arg2);
    }
    else if( methodName == 'javascript' ) {
        this.commandJavascript( arg1 );
    }
    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 ) {
        fb_log( window.name + ": Unknown command '" + methodName + "'" );
    }
    else {
        fb_log( "Unknown command '" + methodName + "'" );
    }
    return rv;
}

// ------------------------------------------------------------------
_.isLateCommand = function ( command ) {
    var nodeId     = command['nodeId'];
    var key        = command['arg1'];
    var element = this.newNodes[nodeId];
    if (!element) element = this.getNode(nodeId, 1);
    if (!element) return true;
    if( key == 'textNode' && element.nodeName == 'script' ) {
        return true;
    }
    if( key == 'value' && element.nodeName == 'search-list' ) {
        // fb_log( 'late value=' + command['arg2'] );
        return true;
    }
    return false;
}

// ------------------------------------------------------------------
_.commandNewWindow = function (nodeId) {
    this.windowId = nodeId;
}

// ------------------------------------------------------------------
_.commandNewElement = function (nodeId, tagName, parentId, index) { 
    try {
        var element = this.createElement(tagName, nodeId);
        element.setAttribute('_addAtIndex', index);
        this.newNodes[nodeId] = element;

        var parent = this.newNodes[parentId];
        if (parent)
            this.addElementAtIndex(parent, element);
        else {
            // New elements are added to existing nodes in one batch
            // in addNewNodes
            if( ! this.newNodeRoots[parentId] )
                this.newNodeRoots[parentId] = [];
            this.newNodeRoots[parentId].push( element );
        }

        if (tagName == 'listbox') {
            // onselect works but addEventListener( 'select' ) doesn't

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

        }
        else if (key == 'callback' ) {
            this.commandCallback( element, value );
            return;
        }
        else {
            element[key] = value;
        }
    }
    catch (e ) {
        Throw( e,
                'Cannot set ' + element.id + '.' + key + '=' + value
             );
    }
}


// ------------------------------------------------------------------
_.commandSetEvent = function ( element, key, value ) {

    // key = clickable
    var event = POEXUL_Runner.activateEvent[ key ];
    // event = click

    var att = key + "-code";
    // att = clickable-code

    // fb_log( { key: key, event: event, att: att, id: element.getAttribute( 'id' ) } );

    if( value && value != "0" ) {
        // Already active?
        if( element[att] )
            return;

        var ev = event.slice( 0, 1 ).toUpperCase() +
                 event.slice( 1 );
        // ev = Click
        element[att] = function (e) { 
                                // make sure clickable is still set
                                var now = element.getAttribute( key );
                                fb_log( { key: key, now: now } );
                                if( now && now != "0" )
                                    $application.fireEvent( ev, 
                                                        { target: element },
                                                        { from: key, 
                                                          now: now } 
                                                      );
                           };
        element.addEventListener( event, element[att], false );
    }
    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;
    }

    var id = element.getAttribute( 'id' );
    var done;
    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' );
                }
            }
        }
        else {
            sel = element.selectedItem;
        }

        if( sel ) {
            sel.setAttribute( 'selected', "true" );
        }
    }
    else {
        element.selectedItem = null;
    }
    element.removeAttribute( "suppressonselect" );
    
    return;
}

// ------------------------------------------------------------------
_.commandCallback = function ( element, value ) {
    
    var req = { attribute: value,
                source_id: element.id,
                event: 'Callback'
              };

    if( 'object' == typeof value ) {
        req.attribute = value.attribute;
        req.extra = value.extra;
    }

    var uri = $application.buildURI( req );
    var att = req.attribute.replace( "hidden-", "" );
    element.setAttribute( att, uri );
}

// ------------------------------------------------------------------
_.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 ] );
        }

        // Do the commands as one batch, all together, after they
        // have all been added to the 'deferred' array
        var self = this;
        this.timeouts[tid] = window.setTimeout( function () {
                        delete self.timeouts[ tid ];
                        self.doDeferredSelectedIndex( tid );
                     }, this.BLIP * 20 );
        // Add the command to the batch
        if( ! this.deferredSelectedIndex ) 
            this.deferredSelectedIndex = [];
        this.deferredSelectedIndex.push( [ element, value, _try ] );
    }
    else {
        element.selectedIndex = value;
        element.setAttribute( 'selectedIndex', value );
        fb_log( 'Giving up on %s.selectedIndex=%i', id, value );
    }
}

// ------------------------------------------------------------------
// Do all the commands in the deferred batch
_.doDeferredSelectedIndex = function (tid) {
    var todo = this.deferredSelectedIndex;
    this.deferredSelectedIndex = [];

    var l = todo.length;
    for( var q=0; q<l; q++ ) {
        // fb_log( q, todo[q] );
        this.commandSelectedIndex( todo[q][0], todo[q][1], todo[q][2] );
    }
}

// ------------------------------------------------------------------
_.commandRemoveAttribute = function (nodeId, key, value) { 
    try {
        var element = this.newNodes[nodeId];

        if (!element) element = this.getNode(nodeId);
        element.removeAttribute( key );
        if( key in element && element.__lookupSetter__( key ) ) {
            fb_log( "remove %s.%s", element.id, key );
            element[key] = '';          // also clear the property
        }
    } catch (e) {
        Throw(e,
            'Cannot remove attribute from node: [' + nodeId + ', ' + key + ']'
        );
    }
}

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

    try {
        eval( value );
    } catch( e ) {
        Throw(e, 'Cannot evaluate javascript: ['+ value + ']' );
    }
}

// ------------------------------------------------------------------
// Delete an element
_.commandByeElement = function (nodeId) {
    // fb_log( 'bye ' + nodeId );

    var node = this.newNodes[nodeId];
    if( node ) {
        delete this.newNodes[nodeId];
        // fb_log( 'bye new node %s', nodeId );
        // above is probably enough... but one can never be too paranoid
    }
    else {
        node = this.getNode( nodeId, 1 );
        if( !node ) {
            // fb_log( 'Attempt to remove unknown node ' + nodeId );
            return;
        }
    }

    // Remove from DOM
    var p = node.parentNode;
    if( p ) 
        p.removeChild( node );

    // work around the fact XBL doesn't always call destuctor
    if( node.dispose )
        node.dispose();
}

// ------------------------------------------------------------------
_.commandFramify = function (nodeId) {
    $application.framify( nodeId );
}

// ------------------------------------------------------------------
_.commandPopupWindow = function (id, win) {
    // fb_log( "Open window "+id );
    var feat = "resizable=yes,dependent=yes";
    if( win.width ) {
        feat += ",width="+win.width;
    }
    if( win.height ) {
        feat += ",height="+win.height;
    }
    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 );
}

// private --------------------------------------------------------------------

_.getNode = function (nodeId, safe) {
    var node = this._getNode(nodeId);
    if ( !node && !safe ) Throw("Cannot find node by Id: " + nodeId);
    return node;
}

_._getNode = function (nodeId) {
    if( this.windowId == nodeId ) {
        return this.windowEl;
    }
    else {
        return this.document.getElementById(nodeId);
    }
}   

_.createElement = function (tagName, nodeId) {
    var NS = $application.xulNS;
    if( tagName.match(/^html_/) ) {
        NS = $application.htmlNS;
        tagName = tagName.replace(/^html_/, '');
    }

    var element = this.document.createElementNS( NS, tagName );
    element.id = nodeId;
    return element;
}

_.addElementAtIndex = function ( parent, child ) {

    var index = child.getAttribute('_addAtIndex');
    child.removeAttribute('_addAtIndex');
    
    var count = parent.childNodes.length;
    if (index == null || index < 0 || count == 0 || index >= count ) {
        parent.appendChild(child);
        return;
    }
    else {
        parent.insertBefore( child, parent.childNodes[ index ] );
    }
}

// Node is being hidden, we clear its content
// This is a work around for Mozilla keeping old values in XBL nodes.
// This technique sucks, because our node is now out of sync with the 
// POE::XUL::Node.  This should propably be implemented in the widgets, but...
_.clearGroupbox = function ( node ) {



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