@@ -495,6 +495,148 @@ Code.discard = function () {
495495 }
496496} ;
497497
498+ Code . promisifyBlock = function ( block , code ) {
499+ var prev = block . getParent ( ) ,
500+ next = block . getNextBlock ( ) ,
501+ type , ocurr , count ;
502+
503+ if ( block . promise && block . type !== 'controls_if' && block . type !== 'procedures_callnoreturn' ) {
504+ code = 'return ' + code ;
505+ }
506+
507+ if ( prev !== null && prev . promise && prev . getNextBlock ( ) === block ) {
508+ count = 0 ;
509+ ocurr = code . match ( / \n / g) . length ;
510+ code = code . replace ( / \n / g, function ( ) {
511+ count ++ ;
512+ if ( count < ocurr ) {
513+ return '\n ' ;
514+ }
515+ return '\n' ;
516+ } ) ;
517+ code = '.then(function () {\n ' + ( block . type === 'procedures_callnoreturn' ? 'return ' : '' ) + code + '})' ;
518+ block . promise = true ;
519+ type = 1 ;
520+ } else {
521+ if ( block . promise && code . endsWith ( ';\n' ) && next !== null ) {
522+ code = code . substr ( 0 , code . length - 2 ) ;
523+ type = 2 ;
524+ }
525+ }
526+
527+ if ( block . promise && next === null ) {
528+ if ( type ) {
529+ code += ';\n' ;
530+ }
531+ }
532+
533+ return code ;
534+ } ;
535+
536+ Code . debug = function ( ) {
537+ var space = '' ;
538+ for ( var i = 0 ; i < Blockly . JavaScript . depth ; i ++ ) {
539+ space += ' ' ;
540+ }
541+ console . log . apply ( console , [ space ] . concat ( Array . prototype . slice . apply ( arguments ) ) ) ;
542+ } ;
543+
544+ Blockly . JavaScript . blockToCode = function ( block ) {
545+ if ( ! block ) {
546+ return '' ;
547+ }
548+ if ( block . disabled ) {
549+ // Skip past this block if it is disabled.
550+ return this . blockToCode ( block . getNextBlock ( ) ) ;
551+ }
552+
553+ var func = this [ block . type ] ;
554+ goog . asserts . assertFunction ( func ,
555+ 'Language "%s" does not know how to generate code for block type "%s".' ,
556+ this . name_ , block . type ) ;
557+
558+ delete block . promise ;
559+
560+ // First argument to func.call is the value of 'this' in the generator.
561+ // Prior to 24 September 2013 'this' was the only way to access the block.
562+ // The current prefered method of accessing the block is through the second
563+ // argument to func.call, which becomes the first parameter to the generator.
564+ var code = func . call ( block , block ) ;
565+ if ( goog . isArray ( code ) ) {
566+ // Value blocks return tuples of code and operator order.
567+
568+ // Code.debug('CODE', code[0]);
569+ Blockly . JavaScript . depth ++ ;
570+ var scrub = this . scrub_ ( block , code [ 0 ] ) ;
571+ Blockly . JavaScript . depth -- ;
572+ // Code.debug('<- ' + scrub);
573+
574+ return [ scrub , code [ 1 ] ] ;
575+ } else if ( goog . isString ( code ) ) {
576+ if ( this . STATEMENT_PREFIX ) {
577+ code = this . STATEMENT_PREFIX . replace ( / % 1 / g, '\'' + block . id + '\'' ) +
578+ code ;
579+ }
580+
581+ // var prev = block.getParent();
582+ // Code.debug({
583+ // type: block.type,
584+ // depth: Blockly.JavaScript.depth,
585+ // promise: block.promise,
586+ // prev: prev ? prev.type : null
587+ // });
588+ code = Code . promisifyBlock ( block , code ) ;
589+
590+ // Code.debug('CODE', code);
591+ Blockly . JavaScript . depth ++ ;
592+ var scrub = this . scrub_ ( block , code ) ;
593+ Blockly . JavaScript . depth -- ;
594+ // Code.debug('<- ' + scrub);
595+
596+ return scrub ;
597+ } else if ( code === null ) {
598+ // Block has handled code generation itself.
599+ return '' ;
600+ } else {
601+ goog . asserts . fail ( 'Invalid code generated: %s' , code ) ;
602+ }
603+ } ;
604+
605+ Blockly . Block . prototype . setPromise = function ( isPromise ) {
606+ var block = this ;
607+ this . promise = isPromise ;
608+ if ( isPromise ) {
609+ while ( ( block = block . getSurroundParent ( ) ) !== null ) {
610+ if ( block . type . indexOf ( 'procedures_def' ) === 0 ) {
611+ block . promise = true ;
612+ return ;
613+ }
614+ }
615+ }
616+ } ;
617+
618+ Blockly . JavaScript [ '_procedures_callnoreturn' ] = Blockly . JavaScript [ 'procedures_callnoreturn' ] ;
619+
620+ Blockly . JavaScript [ 'procedures_callnoreturn' ] = function ( block ) {
621+ var funcName = Blockly . JavaScript . variableDB_ . getName (
622+ block . getFieldValue ( 'NAME' ) , Blockly . Procedures . NAME_TYPE ) ;
623+ var code = Blockly . JavaScript [ '_procedures_callnoreturn' ] . call ( Blockly . JavaScript , block ) ;
624+ var blocks = Code . workspace . getTopBlocks ( ) ;
625+ var blk ;
626+ for ( var i = 0 ; i < blocks . length ; i ++ ) {
627+ blk = blocks [ i ] ;
628+ if ( blk . type . indexOf ( 'procedures_def' ) === 0 && blk . getProcedureDef ( ) [ 0 ] === funcName ) {
629+ if ( blk . promise ) {
630+ block . promise = true ;
631+ }
632+ break ;
633+ }
634+ }
635+ return code ;
636+ } ;
637+
638+ Blockly . JavaScript . depth = 0 ;
639+
498640// Load the Code demo's language strings.
499641document . write ( '<script src="' + baseUrl + '/msg/' + Code . LANG + '.js"></script>\n' ) ;
500642// Load Blockly's language strings.
0 commit comments