anchor.diff:      // Register event handler for source text.
       _aceEditorSession.callMethod(
           'on', ['change', _onSourceTextChange]);
  +    _aceEditorSession.callMethod(
  +        'on', ['changeScrollTop',
  +               (e, t) => _setOutputScrollRatio(_sourceScrollRatio)]);
       // Set focus on editor now.
       _aceEditor.callMethod('focus');
  +    // Register event handler for output.
  +    _outputNode.onScroll.listen(
  +        (e) => _setSourceScrollRatio(_outputScrollRatio));
   
       // Construct node validator for output HTML.
       NodeValidatorBuilder builder = new NodeValidatorBuilder.common();
  
positive.code: import 'dart:convert';
  import 'dart:html';
  import 'dart:js';
  import 'package:crypto/crypto.dart';
  import 'package:utf/utf.dart';
  
  
negative.code:   bool allowsUri(String uri) => true;
  }
  
  // A struct holding data used for scroll ratio/position computation for an
  // element.
  class _ScrollSize {
    // Height of the viewport, i.e., the visible portion of the element.
    num viewportHeight;
    // Height of the content in the element, i.e. the scrollHeight.
    num contentHeight;
  
    // The maximum possible scrollTop value for this element.
    num get maxScrollTop => max(0, contentHeight - viewportHeight);
    // Converts a scrollTop value to a scroll position ratio (between 0 and 1).
    num toScrollRatio(num scrollTop) =>
        maxScrollTop > 0 ?
        scrollTop / maxScrollTop :
        1.0;
    // Converts a scroll position ration to a concrete scrollTop value.
    num toScrollTop(num scrollRatio) => scrollRatio * maxScrollTop;
  
    // Constructor.
    _ScrollSize(this.viewportHeight, this.contentHeight);
  }
  
  
  void main() {
    AsciiDocEditor editor = new AsciiDocEditor();
  