8000 Merge pull request #525 from sveltejs/gh-7 · sveltejs/svelte@1078bae · GitHub
[go: up one dir, main page]

Skip to content

Commit 1078bae

Browse files
authored
Merge pull request #525 from sveltejs/gh-7
Transitions
2 parents 8ff66f3 + 90adb3b commit 1078bae

File tree

54 files changed

+4318
-155
lines changed
  • use-elements-as-anchors
  • parser/samples
  • runtime
  • server-side-rendering/samples/comment
  • Some content is hidden

    Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

    54 files changed

    +4318
    -155
    lines changed

    package.json

    Lines changed: 5 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -17,11 +17,13 @@
    1717
    "precodecov": "npm run coverage",
    1818
    "lint": "eslint src test/*.js",
    1919
    "build": "npm run build:main && npm run build:shared && npm run build:ssr",
    20-
    "build:main": "rollup -c rollup/rollup.config.main.js",
    20+
    "build:main": "node src/shared/_build.js && rollup -c rollup/rollup.config.main.js",
    2121
    "build:shared": "rollup -c rollup/rollup.config.shared.js",
    2222
    "build:ssr": "rollup -c rollup/rollup.config.ssr.js",
    23+
    "dev": "node src/shared/_build.js && rollup -c rollup/rollup.config.main.js -w",
    24+
    "dev:shared": "rollup -c rollup/rollup.config.shared.js -w",
    2325
    "pretest": "npm run build",
    24-
    "prepublish": "npm run lint && npm run build"
    26+
    "prepublish": "npm run build && npm run lint"
    2527
    },
    2628
    "repository": {
    2729
    "type": "git",
    @@ -72,6 +74,7 @@
    7274
    "rollup-plugin-commonjs": "^7.0.0",
    7375
    "rollup-plugin-json": "^2.1.0",
    7476
    "rollup-plugin-node-resolve": "^2.0.0",
    77+
    "rollup-watch": "^3.2.2",
    7578
    "source-map": "^0.5.6",
    7679
    "source-map-support": "^0.4.8"
    7780
    },

    src/generators/Generator.js

    Lines changed: 2 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -24,6 +24,7 @@ export default class Generator {
    2424
    this.helpers = new Set();
    2525
    this.components = new Set();
    2626
    this.events = new Set();
    27+
    this.transitions = new Set();
    2728
    this.importedComponents = new Map();
    2829

    2930
    this.bindingGroups = [];
    @@ -328,7 +329,7 @@ export default class Generator {
    328329
    });
    329330
    }
    330331

    331-
    [ 'helpers', 'events', 'components' ].forEach( key => {
    332+
    [ 'helpers', 'events', 'components', 'transitions' ].forEach( key => {
    332333
    if ( templateProperties[ key ] ) {
    333334
    templateProperties[ key ].value.properties.forEach( prop => {
    334335
    this[ key ].add( prop.key.name );

    src/generators/dom/Block.js

    Lines changed: 64 additions & 0 deletions
    10000
    Original file line numberDiff line numberDiff line change
    @@ -24,11 +24,17 @@ export default class Block {
    2424
    create: new CodeBuilder(),
    2525
    mount: new CodeBuilder(),
    2626
    update: new CodeBuilder(),
    27+
    intro: new CodeBuilder(),
    28+
    outro: new CodeBuilder(),
    2729
    detach: new CodeBuilder(),
    2830
    detachRaw: new CodeBuilder(),
    2931
    destroy: new CodeBuilder()
    3032
    };
    3133

    34+
    this.hasIntroMethod = false; // a block could have an intro method but not intro transitions, e.g. if a sibling block has intros
    35+
    this.hasOutroMethod = false;
    36+
    this.outros = 0;
    37+
    3238
    this.aliases = new Map();
    3339
    this.variables = new Map();
    3440
    this.getUniqueName = this.generator.getUniqueNameMaker( options.params );
    @@ -100,6 +106,20 @@ export default class Block {
    100106
    }
    101107

    102108
    render () {
    109+
    let introing;
    110+
    const hasIntros = !this.builders.intro.isEmpty();
    111+
    if ( hasIntros ) {
    112+
    introing = this.getUniqueName( 'introing' );
    113+
    this.addVariable( introing );
    114+
    }
    115+
    116+
    let outroing;
    117+
    const hasOutros = !this.builders.outro.isEmpty();
    118+
    if ( hasOutros ) {
    119+
    outroing = this.getUniqueName( 'outroing' );
    120+
    this.addVariable( outroing );
    121+
    }
    122+
    103123
    if ( this.variables.size ) {
    104124
    const variables = Array.from( this.variables.keys() )
    105125
    .map( key => {
    @@ -157,6 +177,50 @@ export default class Block {
    157177
    }
    158178
    }
    159179

    180+
    if ( this.hasIntroMethod ) {
    181+
    if ( hasIntros ) {
    182+
    properties.addBlock( deindent`
    183+
    intro: function ( ${this.target}, anchor ) {
    184+
    if ( ${introing} ) return;
    185+
    ${introing} = true;
    186+
    ${hasOutros && `${outroing} = false;`}
    187+
    188+
    ${this.builders.intro}
    189+
    190+
    this.mount( ${this.target}, anchor );
    191+
    },
    192+
    ` );
    193+
    } else {
    194+
    properties.addBlock( deindent`
    195+
    intro: function ( ${this.target}, anchor ) {
    196+
    this.mount( ${this.target}, anchor );
    197+
    },
    198+
    ` );
    199+
    }
    200+
    }
    201+
    202+
    if ( this.hasOutroMethod ) {
    203+
    if ( hasOutros ) {
    204+
    properties.addBlock( deindent`
    205+
    outro: function ( ${this.alias( 'outrocallback' )} ) {
    206+
    if ( ${outroing} ) return;
    207+
    ${outroing} = true;
    208+
    ${hasIntros && `${introing} = false;`}
    209+
    210+
    var ${this.alias( 'outros' )} = ${this.outros};
    211+
    212+
    ${this.builders.outro}
    213+
    },
    214+
    ` );
    215+
    } else {
    216+
    properties.addBlock( deindent`
    217+
    outro: function ( outrocallback ) {
    218+
    outrocallback();
    219+
    },
    220+
    ` );
    221+
    }
    222+
    }
    223+
    160224
    if ( this.builders.destroy.isEmpty() ) {
    161225
    properties.addBlock( `destroy: ${this.generator.helper( 'noop' )}` );
    162226
    } else {

    src/generators/dom/index.js

    Lines changed: 24 additions & 16 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1,12 +1,12 @@
    11
    import MagicString from 'magic-string';
    2-
    import { parse } from 'acorn';
    2+
    import { parseExpressionAt } from 'acorn';
    33
    import annotateWithScopes from '../../utils/annotateWithScopes.js';
    44
    import isReference from '../../utils/isReference.js';
    55
    import { walk } from 'estree-walker';
    66
    import deindent from '../../utils/deindent.js';
    77
    import CodeBuilder from '../../utils/CodeBuilder.js';
    88
    import visit from './visit.js';
    9-
    import { nameMap, sharedMap } from './sharedNames.js';
    9+
    import shared from './shared.js';
    1010
    import Generator from '../Generator.js';
    1111
    import preprocess from './preprocess.js';
    1212

    @@ -25,7 +25,7 @@ class DomGenerator extends Generator {
    2525
    }
    2626

    2727
    helper ( name ) {
    28-
    if ( this.options.dev && sharedMap.has( `${name}Dev` ) ) {
    28+
    if ( this.options.dev && `${name}Dev` in shared ) {
    2929
    name = `${name}Dev`;
    3030
    }
    3131

    @@ -138,7 +138,7 @@ export default function dom ( parsed, source, options ) {
    138138
    builders.init.addLine( `if ( !${generator.alias( 'added_css' )} ) ${generator.alias( 'add_css' )}();` );
    139139
    }
    140140

    141-
    if ( generator.hasComponents ) {
    141+
    if ( generator.hasComponents || generator.hasIntroTransitions ) {
    142142
    builders.init.addLine( `this._renderHooks = [];` );
    143143
    }
    144144

    @@ -158,7 +158,7 @@ export default function dom ( parsed, source, options ) {
    158158
    ` );
    159159
    }
    160160

    161-
    if ( generator.hasComponents ) {
    161+
    if ( generator.hasComponents || generator.hasIntroTransitions ) {
    162162
    const statement = `this._flush();`;
    163163

    164164
    builders.init.addBlock( statement );
    @@ -168,7 +168,7 @@ export default function dom ( parsed, source, options ) {
    168168
    if ( templateProperties.oncreate ) {
    169169
    builders.init.addBlock( deindent`
    170170
    if ( options._root ) {
    171-
    options._root._renderHooks.push({ fn: ${generator.alias( 'template' )}.oncreate, context: this });
    171+
    options._root._renderHooks.push( ${generator.alias( 'template' )}.oncreate.bind( this ) );
    172172
    } else {
    173173
    ${generator.alias( 'template' )}.oncreate.call( this );
    174174
    }
    @@ -218,7 +218,7 @@ export default function dom ( parsed, source, options ) {
    218218
    219219
    this._handlers = Object.create( null );
    220220
    221-
    this._root = options._root;
    221+
    this._root = options._root || this;
    222222
    this._yield = options._yield;
    223223
    224224
    ${builders.init}
    @@ -275,20 +275,20 @@ export default function dom ( parsed, source, options ) {
    275275
    );
    276276
    } else {
    277277
    generator.uses.forEach( key => {
    278-
    const str = sharedMap.get( key );
    278+
    const str = shared[ key ];
    279279
    const code = new MagicString( str );
    280-
    const fn = parse( str ).body[0];
    280+
    const expression = parseExpressionAt( str, 0 );
    281281

    282-
    let scope = annotateWithScopes( fn );
    282+
    let scope = annotateWithScopes( expression );
    283283

    284-
    walk( fn, {
    284+
    walk( expression, {
    285285
    enter ( node, parent ) {
    286286
    if ( node._scope ) scope = node._scope;
    287287

    288288
    if ( node.type === 'Identifier' && isReference( node, parent ) && !scope.has( node.name ) ) {
    289-
    if ( nameMap.has( node.name ) ) {
    289+
    if ( node.name in shared ) {
    290290
    // this helper function depends on another one
    291-
    const dependency = nameMap.get( node.name );
    291+
    const dependency = node.name;
    292292
    generator.uses.add( dependency );
    293293

    294294
    const alias = generator.alias( dependency );
    @@ -302,10 +302,18 @@ export default function dom ( parsed, source, options ) {
    302302
    }
    303303
    });
    304304

    305-
    const alias = generator.alias( key );
    306-
    if ( alias !== fn.id.name ) code.overwrite( fn.id.start, fn.id.end, alias );
    305+
    if ( key === 'transitionManager' ) { // special case
    306+
    const global = `_svelteTransitionManager`;
    307307

    308-
    builders.main.addBlock( code.toString() );
    308+
    builders.main.addBlock(
    309+
    `var ${generator.alias( 'transitionManager' )} = window.${global} || ( window.${global} = ${code});`
    310+
    );
    311+
    } else {
    312+
    const alias = generator.alias( expression.id.name );
    313+
    if ( alias !== expression.id.name ) code.overwrite( expression.id.start, expression.id.end, alias );
    314+
    315+
    builders.main.addBlock( code.toString() );
    316+
    }
    309317
    });
    310318
    }
    311319

    src/generators/dom/preprocess.js

    Lines changed: 15 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -59,6 +59,8 @@ const preprocessors = {
    5959
    IfBlock: ( generator, block, state, node ) => {
    6060
    const blocks = [];
    6161
    let dynamic = false;
    62+
    let hasIntros = false;
    63+
    let hasOutros = false;
    6264

    6365
    function attachBlocks ( node ) {
    6466
    const dependencies = block.findDependencies( node.expression );
    @@ -78,6 +80,9 @@ const preprocessors = {
    7880
    block.addDependencies( node._block.dependencies );
    7981
    }
    8082

    83+
    if ( node._block.hasIntroMethod ) hasIntros = true;
    84+
    if ( node._block.hasOutroMethod ) hasOutros = true;
    85+
    8186
    if ( isElseIf( node.else ) ) {
    8287
    attachBlocks( node.else.children[0] );
    8388
    } else if ( node.else ) {
    @@ -101,6 +106,8 @@ const preprocessors = {
    101106

    102107
    blocks.forEach( block => {
    103108
    block.hasUpdateMethod = dynamic;
    109+
    block.hasIntroMethod = hasIntros;
    110+
    block.hasOutroMethod = hasOutros;
    104111
    });
    105112

    106113
    generator.blocks.push( ...blocks );
    @@ -200,6 +207,14 @@ const preprocessors = {
    200207
    const dependencies = block.findDependencies( attribute.value );
    201208
    block.addDependencies( dependencies );
    202209
    }
    210+
    211+
    else if ( attribute.type === 'Transition' ) {
    212+
    if ( attribute.intro ) generator.hasIntroTransitions = block.hasIntroMethod = true;
    213+
    if ( attribute.outro ) {
    214+
    generator.hasOutroTransitions = block.hasOutroMethod = true;
    215+
    block.outros += 1;
    216+
    }
    217+
    }
    203218
    });
    204219

    205220
    if ( node.children.length ) {

    src/generators/dom/sharedNames.js

    Lines changed: 0 additions & 12 deletions
    This file was deleted.

    src/generators/dom/visitors/Component/Component.js

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -92,7 +92,7 @@ export default function visitComponent ( generator, block, state, node ) {
    9292

    9393
    const componentInitProperties = [
    9494
    `target: ${!isToplevel ? state.parentNode: 'null'}`,
    95-
    `_root: ${block.component}._root || ${block.component}`
    95+
    `_root: ${block.component}._root`
    9696
    ];
    9797

    9898
    // Component has children, put them in a separate {{yield}} block

    0 commit comments

    Comments
     (0)
    0