Reveal.add/remveEventListener -> Reveal.on/off
This commit is contained in:
parent
f24620018f
commit
855cc82d76
17 changed files with 113 additions and 91 deletions
22
README.md
22
README.md
|
@ -369,7 +369,7 @@ Reveal.initialize({
|
|||
autoSlideStoppable: true,
|
||||
|
||||
// Use this method for navigation when auto-sliding
|
||||
autoSlideMethod: Reveal.navigateNext,
|
||||
autoSlideMethod: Reveal.next,
|
||||
|
||||
// Specify the average time in seconds that you think you will spend
|
||||
// presenting each slide. This is used to show a pacing timer in the
|
||||
|
@ -531,7 +531,7 @@ You can also include dependencies which are bundled/already present on the page.
|
|||
A `ready` event is fired when reveal.js has loaded all non-async dependencies and is ready to start navigating. To check if reveal.js is already 'ready' you can call `Reveal.isReady()`.
|
||||
|
||||
```javascript
|
||||
Reveal.addEventListener( 'ready', function( event ) {
|
||||
Reveal.on( 'ready', function( event ) {
|
||||
// event.currentSlide, event.indexh, event.indexv
|
||||
} );
|
||||
```
|
||||
|
@ -639,7 +639,7 @@ Each individual element is decorated with a `data-auto-animate-target` attribute
|
|||
|
||||
Each time a presentation navigates between two auto-animated slides it dispatches the `autoanimate` event.
|
||||
```javascript
|
||||
Reveal.addEventListener( 'autoanimate', function( event ) {
|
||||
Reveal.on( 'autoanimate', function( event ) {
|
||||
// event.fromSlide, event.toSlide
|
||||
} );
|
||||
```
|
||||
|
@ -812,7 +812,7 @@ A `slidechanged` event is fired each time the slide is changed (regardless of st
|
|||
Some libraries, like MathJax (see [#226](https://github.com/hakimel/reveal.js/issues/226#issuecomment-10261609)), get confused by the transforms and display states of slides. Often times, this can be fixed by calling their update or render function from this callback.
|
||||
|
||||
```javascript
|
||||
Reveal.addEventListener( 'slidechanged', function( event ) {
|
||||
Reveal.on( 'slidechanged', function( event ) {
|
||||
// event.previousSlide, event.currentSlide, event.indexh, event.indexv
|
||||
} );
|
||||
```
|
||||
|
@ -841,7 +841,7 @@ If you set `data-state="somestate"` on a slide `<section>`, "somestate" will be
|
|||
Furthermore you can also listen to these changes in state via JavaScript:
|
||||
|
||||
```javascript
|
||||
Reveal.addEventListener( 'somestate', function() {
|
||||
Reveal.on( 'somestate', function() {
|
||||
// TODO: Sprinkle magic
|
||||
}, false );
|
||||
```
|
||||
|
@ -1048,10 +1048,10 @@ When a slide fragment is either shown or hidden reveal.js will dispatch an event
|
|||
Some libraries, like MathJax (see #505), get confused by the initially hidden fragment elements. Often times this can be fixed by calling their update or render function from this callback.
|
||||
|
||||
```javascript
|
||||
Reveal.addEventListener( 'fragmentshown', function( event ) {
|
||||
Reveal.on( 'fragmentshown', function( event ) {
|
||||
// event.fragment = the fragment DOM element
|
||||
} );
|
||||
Reveal.addEventListener( 'fragmenthidden', function( event ) {
|
||||
Reveal.on( 'fragmenthidden', function( event ) {
|
||||
// event.fragment = the fragment DOM element
|
||||
} );
|
||||
```
|
||||
|
@ -1148,8 +1148,8 @@ Press »ESC« or »O« keys to toggle the overview mode on and off. While you're
|
|||
as if you were at 1,000 feet above your presentation. The overview mode comes with a few API hooks:
|
||||
|
||||
```javascript
|
||||
Reveal.addEventListener( 'overviewshown', function( event ) { /* ... */ } );
|
||||
Reveal.addEventListener( 'overviewhidden', function( event ) { /* ... */ } );
|
||||
Reveal.on( 'overviewshown', function( event ) { /* ... */ } );
|
||||
Reveal.on( 'overviewhidden', function( event ) { /* ... */ } );
|
||||
|
||||
// Toggle the overview mode programmatically
|
||||
Reveal.toggleOverview();
|
||||
|
@ -1195,7 +1195,7 @@ Limitations:
|
|||
When reveal.js changes the scale of the slides it fires a resize event. You can subscribe to the event to resize your elements accordingly.
|
||||
|
||||
```javascript
|
||||
Reveal.addEventListener( 'resize', function( event ) {
|
||||
Reveal.on( 'resize', function( event ) {
|
||||
// event.scale, event.oldScale, event.size
|
||||
} );
|
||||
```
|
||||
|
@ -1394,7 +1394,7 @@ let MyPlugin = {
|
|||
init: () => new Promise( resolve => setTimeout( resolve, 3000 ) )
|
||||
};
|
||||
Reveal.registerPlugin( 'myPlugin', MyPlugin );
|
||||
Reveal.addEventListener( 'ready', () => console.log( 'Three seconds later...' ) );
|
||||
Reveal.on( 'ready', () => console.log( 'Three seconds later...' ) );
|
||||
Reveal.initialize();
|
||||
```
|
||||
|
||||
|
|
|
@ -374,7 +374,7 @@
|
|||
Additionally custom events can be triggered on a per slide basis by binding to the <code>data-state</code> name.
|
||||
</p>
|
||||
<pre><code class="javascript" data-trim contenteditable style="font-size: 18px;">
|
||||
Reveal.addEventListener( 'customevent', function() {
|
||||
Reveal.on( 'customevent', function() {
|
||||
console.log( '"customevent" has fired' );
|
||||
} );
|
||||
</code></pre>
|
||||
|
|
4
dist/reveal.min.js
vendored
4
dist/reveal.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -73,7 +73,7 @@ gulp.task('test-qunit', function() {
|
|||
runQunitPuppeteer({
|
||||
targetUrl: `file://${path.join(__dirname, filename)}`,
|
||||
timeout: 10000,
|
||||
redirectConsole: true,
|
||||
redirectConsole: false,
|
||||
puppeteerArgs: ['--allow-file-access-from-files']
|
||||
})
|
||||
.then(result => {
|
||||
|
|
|
@ -12,6 +12,8 @@ export default class SlideContent {
|
|||
|
||||
this.Reveal = Reveal;
|
||||
|
||||
this.startEmbeddedIframe = this.startEmbeddedIframe.bind( this );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
52
js/reveal.js
52
js/reveal.js
|
@ -157,7 +157,7 @@ export default function( revealElement, options ) {
|
|||
// Load plugins then move on to #start()
|
||||
plugins.load( config.dependencies ).then( start );
|
||||
|
||||
return new Promise( resolve => Reveal.addEventListener( 'ready', resolve ) );
|
||||
return new Promise( resolve => Reveal.on( 'ready', resolve ) );
|
||||
|
||||
}
|
||||
|
||||
|
@ -548,6 +548,25 @@ export default function( revealElement, options ) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to one of our custom reveal.js events,
|
||||
* like slidechanged.
|
||||
*/
|
||||
function on( type, listener, useCapture ) {
|
||||
|
||||
revealElement.addEventListener( type, listener, useCapture );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribes from a reveal.js event.
|
||||
*/
|
||||
function off( type, listener, useCapture ) {
|
||||
|
||||
revealElement.removeEventListener( type, listener, useCapture );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies CSS transforms to the slides container. The container
|
||||
* is transformed from two separate sources: layout and the overview
|
||||
|
@ -2442,27 +2461,26 @@ export default function( revealElement, options ) {
|
|||
prev: navigatePrev,
|
||||
next: navigateNext,
|
||||
|
||||
// Deprecated aliases
|
||||
navigateTo: slide,
|
||||
navigateLeft: navigateLeft,
|
||||
navigateRight: navigateRight,
|
||||
navigateUp: navigateUp,
|
||||
navigateDown: navigateDown,
|
||||
navigatePrev: navigatePrev,
|
||||
navigateNext: navigateNext,
|
||||
// Navigation aliases
|
||||
navigateLeft,
|
||||
navigateRight,
|
||||
navigateUp,
|
||||
navigateDown,
|
||||
navigatePrev,
|
||||
navigateNext,
|
||||
|
||||
// Fragment methods
|
||||
navigateFragment: fragments.goto.bind( fragments ),
|
||||
prevFragment: fragments.prev.bind( fragments ),
|
||||
nextFragment: fragments.next.bind( fragments ),
|
||||
|
||||
// Forward event binding to the reveal DOM element
|
||||
addEventListener: ( type, listener, useCapture ) => {
|
||||
Reveal.getRevealElement().addEventListener( type, listener, useCapture );
|
||||
},
|
||||
removeEventListener: ( type, listener, useCapture ) => {
|
||||
Reveal.getRevealElement().removeEventListener( type, listener, useCapture );
|
||||
},
|
||||
// Event binding
|
||||
on,
|
||||
off,
|
||||
|
||||
// Legacy event binding methods left in for backwards compatibility
|
||||
addEventListener: on,
|
||||
removeEventListener: off,
|
||||
|
||||
// Forces an update in slide layout
|
||||
layout,
|
||||
|
@ -2588,7 +2606,7 @@ export default function( revealElement, options ) {
|
|||
getQueryHash,
|
||||
|
||||
// Returns reveal.js DOM elements
|
||||
getRevealElement: () => dom.wrapper || document.querySelector( '.reveal' ),
|
||||
getRevealElement: () => revealElement,
|
||||
getSlidesElement: () => dom.slides,
|
||||
getBackgroundsElement: () => backgrounds.element,
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
|
||||
// If we're printing to PDF, scroll the code highlights of
|
||||
// all blocks in the deck into view at once
|
||||
Reveal.addEventListener( 'pdf-ready', function() {
|
||||
Reveal.on( 'pdf-ready', function() {
|
||||
[].slice.call( document.querySelectorAll( '.reveal pre code[data-line-numbers].current-fragment' ) ).forEach( function( block ) {
|
||||
RevealHighlight.scrollHighlightedLineIntoView( block, {}, true );
|
||||
} );
|
||||
|
|
|
@ -76,7 +76,7 @@ var RevealMath = window.RevealMath || (function(){
|
|||
MathJax.Hub.Queue( Reveal.layout );
|
||||
|
||||
// Reprocess equations in slides when they turn visible
|
||||
Reveal.addEventListener( 'slidechanged', function( event ) {
|
||||
Reveal.on( 'slidechanged', function( event ) {
|
||||
|
||||
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
|
||||
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
window.addEventListener( 'load', post );
|
||||
|
||||
// Monitor events that trigger a change in state
|
||||
Reveal.addEventListener( 'slidechanged', post );
|
||||
Reveal.addEventListener( 'fragmentshown', post );
|
||||
Reveal.addEventListener( 'fragmenthidden', post );
|
||||
Reveal.addEventListener( 'overviewhidden', post );
|
||||
Reveal.addEventListener( 'overviewshown', post );
|
||||
Reveal.addEventListener( 'paused', post );
|
||||
Reveal.addEventListener( 'resumed', post );
|
||||
Reveal.on( 'slidechanged', post );
|
||||
Reveal.on( 'fragmentshown', post );
|
||||
Reveal.on( 'fragmenthidden', post );
|
||||
Reveal.on( 'overviewhidden', post );
|
||||
Reveal.on( 'overviewshown', post );
|
||||
Reveal.on( 'paused', post );
|
||||
Reveal.on( 'resumed', post );
|
||||
|
||||
}());
|
||||
|
|
|
@ -51,13 +51,13 @@
|
|||
} );
|
||||
|
||||
// Monitor events that trigger a change in state
|
||||
Reveal.addEventListener( 'slidechanged', post );
|
||||
Reveal.addEventListener( 'fragmentshown', post );
|
||||
Reveal.addEventListener( 'fragmenthidden', post );
|
||||
Reveal.addEventListener( 'overviewhidden', post );
|
||||
Reveal.addEventListener( 'overviewshown', post );
|
||||
Reveal.addEventListener( 'paused', post );
|
||||
Reveal.addEventListener( 'resumed', post );
|
||||
Reveal.on( 'slidechanged', post );
|
||||
Reveal.on( 'fragmentshown', post );
|
||||
Reveal.on( 'fragmenthidden', post );
|
||||
Reveal.on( 'overviewhidden', post );
|
||||
Reveal.on( 'overviewshown', post );
|
||||
Reveal.on( 'paused', post );
|
||||
Reveal.on( 'resumed', post );
|
||||
|
||||
// Post the initial state
|
||||
post();
|
||||
|
|
|
@ -134,13 +134,13 @@ var RevealNotes = (function() {
|
|||
function onConnected() {
|
||||
|
||||
// Monitor events that trigger a change in state
|
||||
Reveal.addEventListener( 'slidechanged', post );
|
||||
Reveal.addEventListener( 'fragmentshown', post );
|
||||
Reveal.addEventListener( 'fragmenthidden', post );
|
||||
Reveal.addEventListener( 'overviewhidden', post );
|
||||
Reveal.addEventListener( 'overviewshown', post );
|
||||
Reveal.addEventListener( 'paused', post );
|
||||
Reveal.addEventListener( 'resumed', post );
|
||||
Reveal.on( 'slidechanged', post );
|
||||
Reveal.on( 'fragmentshown', post );
|
||||
Reveal.on( 'fragmenthidden', post );
|
||||
Reveal.on( 'overviewhidden', post );
|
||||
Reveal.on( 'overviewshown', post );
|
||||
Reveal.on( 'paused', post );
|
||||
Reveal.on( 'resumed', post );
|
||||
|
||||
// Post the initial state
|
||||
post();
|
||||
|
|
|
@ -43,7 +43,7 @@ probePage.open( inputFile, function( status ) {
|
|||
printPage.open( inputFile, function( status ) {
|
||||
console.log( 'Export PDF: Preparing pdf [3/4]')
|
||||
printPage.evaluate( function() {
|
||||
Reveal.isReady() ? window.callPhantom() : Reveal.addEventListener( 'pdf-ready', window.callPhantom );
|
||||
Reveal.isReady() ? window.callPhantom() : Reveal.on( 'pdf-ready', window.callPhantom );
|
||||
} );
|
||||
} );
|
||||
|
||||
|
|
|
@ -37,12 +37,14 @@
|
|||
<script>
|
||||
|
||||
let r1 = new Reveal( document.querySelector( '.deck1' ), {
|
||||
embedded: true
|
||||
embedded: true,
|
||||
keyboard: false
|
||||
} );
|
||||
r1.initialize();
|
||||
|
||||
let r2 = new Reveal( document.querySelector( '.deck2' ), {
|
||||
embedded: true
|
||||
embedded: true,
|
||||
keyboard: false
|
||||
} );
|
||||
r2.initialize();
|
||||
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
|
||||
<div class="slides">
|
||||
|
||||
<section data-background-iframe="#1">1</section>
|
||||
<section data-background-iframe="#2">2</section>
|
||||
<section data-background-iframe="#3" data-preload>3</section>
|
||||
<section data-background-iframe="#4">4</section>
|
||||
<section data-background-iframe="#5">5</section>
|
||||
<section data-background-iframe="#6">6</section>
|
||||
<section data-background-iframe="https://revealjs.com">1</section>
|
||||
<section data-background-iframe="https://revealjs.com">2</section>
|
||||
<section data-background-iframe="https://revealjs.com" data-preload>3</section>
|
||||
<section data-background-iframe="https://revealjs.com">4</section>
|
||||
<section data-background-iframe="https://revealjs.com">5</section>
|
||||
<section data-background-iframe="https://revealjs.com">6</section>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
|
||||
assert.strictEqual( initCounter['PluginC'], 0, 'async plugin not immediately initialized' );
|
||||
|
||||
reveal.addEventListener( 'ready', function() {
|
||||
reveal.on( 'ready', function() {
|
||||
assert.strictEqual( initCounter['PluginC'], 1, 'finsihed initializing when reveal.js dispatches "ready"' );
|
||||
done();
|
||||
|
||||
|
|
|
@ -59,14 +59,14 @@
|
|||
state2();
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'state1', _onState1 );
|
||||
Reveal.addEventListener( 'state2', _onState2 );
|
||||
Reveal.on( 'state1', _onState1 );
|
||||
Reveal.on( 'state2', _onState2 );
|
||||
|
||||
Reveal.slide( 1 );
|
||||
Reveal.slide( 3 );
|
||||
|
||||
Reveal.removeEventListener( 'state1', _onState1 );
|
||||
Reveal.removeEventListener( 'state2', _onState2 );
|
||||
Reveal.off( 'state1', _onState1 );
|
||||
Reveal.off( 'state2', _onState2 );
|
||||
});
|
||||
|
||||
QUnit.test( 'Fire state events for vertical slides', function( assert ) {
|
||||
|
@ -83,15 +83,15 @@
|
|||
done();
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'state1', _onState1 );
|
||||
Reveal.addEventListener( 'state3', _onState3 );
|
||||
Reveal.on( 'state1', _onState1 );
|
||||
Reveal.on( 'state3', _onState3 );
|
||||
|
||||
Reveal.slide( 0 );
|
||||
Reveal.slide( 4, 1 );
|
||||
Reveal.slide( 4, 2 );
|
||||
|
||||
Reveal.removeEventListener( 'state1', _onState1 );
|
||||
Reveal.removeEventListener( 'state3', _onState3 );
|
||||
Reveal.off( 'state1', _onState1 );
|
||||
Reveal.off( 'state3', _onState3 );
|
||||
});
|
||||
|
||||
QUnit.test( 'No events if state remains unchanged', function( assert ) {
|
||||
|
@ -101,7 +101,7 @@
|
|||
stateChanges += 1;
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'state1', _onEvent );
|
||||
Reveal.on( 'state1', _onEvent );
|
||||
|
||||
Reveal.slide( 0 ); // no state
|
||||
Reveal.slide( 1 ); // state1
|
||||
|
@ -111,7 +111,7 @@
|
|||
Reveal.slide( 4, 1 ); // state1
|
||||
Reveal.slide( 0 ); // no state
|
||||
|
||||
Reveal.removeEventListener( 'state1', _onEvent );
|
||||
Reveal.off( 'state1', _onEvent );
|
||||
|
||||
assert.strictEqual( stateChanges, 1, 'no event was fired when going to slide with same state' );
|
||||
});
|
||||
|
@ -121,12 +121,12 @@
|
|||
assert.ok( Reveal.getCurrentSlide() == document.querySelector( '#slide2' ), 'correct current slide immediately after state event' );
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'state1', _onEvent );
|
||||
Reveal.on( 'state1', _onEvent );
|
||||
|
||||
Reveal.slide( 0 );
|
||||
Reveal.slide( 1 );
|
||||
|
||||
Reveal.removeEventListener( 'state1', _onEvent );
|
||||
Reveal.off( 'state1', _onEvent );
|
||||
});
|
||||
|
||||
} );
|
||||
|
|
|
@ -456,7 +456,7 @@
|
|||
done();
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'fragmentshown', _onEvent );
|
||||
Reveal.on( 'fragmentshown', _onEvent );
|
||||
|
||||
Reveal.slide( 2, 0 );
|
||||
Reveal.slide( 2, 0 ); // should do nothing
|
||||
|
@ -465,7 +465,7 @@
|
|||
Reveal.next();
|
||||
Reveal.prev(); // shouldn't fire fragmentshown
|
||||
|
||||
Reveal.removeEventListener( 'fragmentshown', _onEvent );
|
||||
Reveal.off( 'fragmentshown', _onEvent );
|
||||
});
|
||||
|
||||
QUnit.test( 'fragmenthidden event', function( assert ) {
|
||||
|
@ -477,7 +477,7 @@
|
|||
done();
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'fragmenthidden', _onEvent );
|
||||
Reveal.on( 'fragmenthidden', _onEvent );
|
||||
|
||||
Reveal.slide( 2, 0, 2 );
|
||||
Reveal.slide( 2, 0, 2 ); // should do nothing
|
||||
|
@ -485,7 +485,7 @@
|
|||
Reveal.prev();
|
||||
Reveal.next(); // shouldn't fire fragmenthidden
|
||||
|
||||
Reveal.removeEventListener( 'fragmenthidden', _onEvent );
|
||||
Reveal.off( 'fragmenthidden', _onEvent );
|
||||
});
|
||||
|
||||
|
||||
|
@ -524,13 +524,13 @@
|
|||
done();
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'autoslidepaused', _onEvent );
|
||||
Reveal.on( 'autoslidepaused', _onEvent );
|
||||
Reveal.configure({ autoSlide: 10000 });
|
||||
Reveal.toggleAutoSlide();
|
||||
|
||||
// cleanup
|
||||
Reveal.configure({ autoSlide: 0 });
|
||||
Reveal.removeEventListener( 'autoslidepaused', _onEvent );
|
||||
Reveal.off( 'autoslidepaused', _onEvent );
|
||||
});
|
||||
|
||||
QUnit.test( 'autoslideresumed', function( assert ) {
|
||||
|
@ -542,14 +542,14 @@
|
|||
done();
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'autoslideresumed', _onEvent );
|
||||
Reveal.on( 'autoslideresumed', _onEvent );
|
||||
Reveal.configure({ autoSlide: 10000 });
|
||||
Reveal.toggleAutoSlide();
|
||||
Reveal.toggleAutoSlide();
|
||||
|
||||
// cleanup
|
||||
Reveal.configure({ autoSlide: 0 });
|
||||
Reveal.removeEventListener( 'autoslideresumed', _onEvent );
|
||||
Reveal.off( 'autoslideresumed', _onEvent );
|
||||
});
|
||||
|
||||
|
||||
|
@ -643,7 +643,7 @@
|
|||
done();
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'slidechanged', _onEvent );
|
||||
Reveal.on( 'slidechanged', _onEvent );
|
||||
|
||||
Reveal.slide( 1, 0 ); // should trigger
|
||||
Reveal.slide( 1, 0 ); // should do nothing
|
||||
|
@ -651,7 +651,7 @@
|
|||
Reveal.slide( 3, 0 ); // should trigger
|
||||
Reveal.next(); // should do nothing
|
||||
|
||||
Reveal.removeEventListener( 'slidechanged', _onEvent );
|
||||
Reveal.off( 'slidechanged', _onEvent );
|
||||
|
||||
});
|
||||
|
||||
|
@ -664,12 +664,12 @@
|
|||
done();
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'paused', _onEvent );
|
||||
Reveal.on( 'paused', _onEvent );
|
||||
|
||||
Reveal.togglePause();
|
||||
Reveal.togglePause();
|
||||
|
||||
Reveal.removeEventListener( 'paused', _onEvent );
|
||||
Reveal.off( 'paused', _onEvent );
|
||||
});
|
||||
|
||||
QUnit.test( 'resumed', function( assert ) {
|
||||
|
@ -681,12 +681,12 @@
|
|||
done();
|
||||
}
|
||||
|
||||
Reveal.addEventListener( 'resumed', _onEvent );
|
||||
Reveal.on( 'resumed', _onEvent );
|
||||
|
||||
Reveal.togglePause();
|
||||
Reveal.togglePause();
|
||||
|
||||
Reveal.removeEventListener( 'resumed', _onEvent );
|
||||
Reveal.off( 'resumed', _onEvent );
|
||||
});
|
||||
|
||||
} );
|
||||
|
|
Loading…
Reference in a new issue