Implement onmatch in the Observer API

Closes #2648
Closes #2017