');
    });
    describe('explicitly disallow', function() {
      it('should not allow attributes', function() {
        writer.start('div', {id:'a', name:'a', style:'a'});
        expect(html).toEqual('
');
      });
      it('should not allow tags', function() {
        function tag(name) {
          writer.start(name, {});
          writer.end(name);
        }
        tag('frameset');
        tag('frame');
        tag('form');
        tag('param');
        tag('object');
        tag('embed');
        tag('textarea');
        tag('input');
        tag('button');
        tag('option');
        tag('select');
        tag('script');
        tag('style');
        tag('link');
        tag('base');
        tag('basefont');
        expect(html).toEqual('');
      });
    });
    describe('uri validation', function() {
      it('should call the uri validator', function() {
        writer.start('a', {href:'someUrl'}, false);
        expect(uriValidator).toHaveBeenCalledWith('someUrl', false);
        uriValidator.reset();
        writer.start('img', {src:'someImgUrl'}, false);
        expect(uriValidator).toHaveBeenCalledWith('someImgUrl', true);
        uriValidator.reset();
        writer.start('someTag', {src:'someNonUrl'}, false);
        expect(uriValidator).not.toHaveBeenCalled();
      });
      it('should drop non valid uri attributes', function() {
        uriValidator.andReturn(false);
        writer.start('a', {href:'someUrl'}, false);
        expect(html).toEqual('
');
        html = '';
        uriValidator.andReturn(true);
        writer.start('a', {href:'someUrl'}, false);
        expect(html).toEqual('');
      });
    });
  });
  describe('uri checking', function() {
    beforeEach(function() {
      this.addMatchers({
        toBeValidUrl: function() {
          var sanitize;
          inject(function($sanitize) {
            sanitize = $sanitize;
          });
          var input = '';
          return sanitize(input) === input;
        },
        toBeValidImageSrc: function() {
          var sanitize;
          inject(function($sanitize) {
            sanitize = $sanitize;
          });
          var input = '

';
          return sanitize(input) === input;
        }
      });
    });
    it('should use $$sanitizeUri for links', function() {
      var $$sanitizeUri = jasmine.createSpy('$$sanitizeUri');
      module(function($provide) {
        $provide.value('$$sanitizeUri', $$sanitizeUri);
      });
      inject(function() {
        $$sanitizeUri.andReturn('someUri');
        expectHTML('
').toEqual('
');
        expect($$sanitizeUri).toHaveBeenCalledWith('someUri', false);
        $$sanitizeUri.andReturn('unsafe:someUri');
        expectHTML('
').toEqual('
');
      });
    });
    it('should use $$sanitizeUri for links', function() {
      var $$sanitizeUri = jasmine.createSpy('$$sanitizeUri');
      module(function($provide) {
        $provide.value('$$sanitizeUri', $$sanitizeUri);
      });
      inject(function() {
        $$sanitizeUri.andReturn('someUri');
        expectHTML('

').toEqual('

');
        expect($$sanitizeUri).toHaveBeenCalledWith('someUri', true);
        $$sanitizeUri.andReturn('unsafe:someUri');
        expectHTML('

').toEqual('
![]()
');
      });
    });
    it('should be URI', function() {
      expect('').toBeValidUrl();
      expect('http://abc').toBeValidUrl();
      expect('HTTP://abc').toBeValidUrl();
      expect('https://abc').toBeValidUrl();
      expect('HTTPS://abc').toBeValidUrl();
      expect('ftp://abc').toBeValidUrl();
      expect('FTP://abc').toBeValidUrl();
      expect('mailto:me@example.com').toBeValidUrl();
      expect('MAILTO:me@example.com').toBeValidUrl();
      expect('tel:123-123-1234').toBeValidUrl();
      expect('TEL:123-123-1234').toBeValidUrl();
      expect('#anchor').toBeValidUrl();
      expect('/page1.md').toBeValidUrl();
    });
    it('should not be URI', function() {
      expect('javascript:alert').not.toBeValidUrl();
    });
    describe('javascript URLs', function() {
      it('should ignore javascript:', function() {
        expect('JavaScript:abc').not.toBeValidUrl();
        expect(' \n Java\n Script:abc').not.toBeValidUrl();
        expect('http://JavaScript/my.js').toBeValidUrl();
      });
      it('should ignore dec encoded javascript:', function() {
        expect('javascript:').not.toBeValidUrl();
        expect('javascript:').not.toBeValidUrl();
        expect('j avascript:').not.toBeValidUrl();
      });
      it('should ignore decimal with leading 0 encodede javascript:', function() {
        expect('javascript:').not.toBeValidUrl();
        expect('j avascript:').not.toBeValidUrl();
        expect('j avascript:').not.toBeValidUrl();
      });
      it('should ignore hex encoded javascript:', function() {
        expect('javascript:').not.toBeValidUrl();
        expect('javascript:').not.toBeValidUrl();
        expect('j avascript:').not.toBeValidUrl();
      });
      it('should ignore hex encoded whitespace javascript:', function() {
        expect('jav	ascript:alert();').not.toBeValidUrl();
        expect('jav
ascript:alert();').not.toBeValidUrl();
        expect('jav
 ascript:alert();').not.toBeValidUrl();
        expect('jav\u0000ascript:alert();').not.toBeValidUrl();
        expect('java\u0000\u0000script:alert();').not.toBeValidUrl();
        expect('  java\u0000\u0000script:alert();').not.toBeValidUrl();
      });
    });
  });
  describe('sanitizeText', function() {
    it('should escape text', function() {
      expect(sanitizeText('a
&
c')).toEqual('a<div>&</div>c');
    });
  });
});
describe('decodeEntities', function() {
  var handler, text,
      origHiddenPre = window.hiddenPre;
  beforeEach(function() {
    text = '';
    handler = {
      start: function() {},
      chars: function(text_){
        text = text_;
      },
      end: function() {},
      comment: function() {}
    };
    module('ngSanitize');
  });
  afterEach(function() {
    window.hiddenPre = origHiddenPre;
  });
  it('should use innerText if textContent is not available (IE<9)', function() {
    window.hiddenPre = {
      innerText: 'INNER_TEXT'
    };
    inject(function($sanitize) {
      htmlParser('
text', handler);
      expect(text).toEqual('INNER_TEXT');
    });
  });
  it('should use textContent if available', function() {
    window.hiddenPre = {
      textContent: 'TEXT_CONTENT',
      innerText: 'INNER_TEXT'
    };
    inject(function($sanitize) {
      htmlParser('
text', handler);
      expect(text).toEqual('TEXT_CONTENT');
    });
  });
  it('should use textContent even if empty', function() {
    window.hiddenPre = {
      textContent: '',
      innerText: 'INNER_TEXT'
    };
    inject(function($sanitize) {
      htmlParser('
text', handler);
      expect(text).toEqual('');
    });
  });
});