fix refresh
[roojs1] / roojs-bootstrap-debug.js
index e47a90a..8efcc75 100644 (file)
@@ -580,7 +580,7 @@ Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent,  {
         if (!skip_children) {    
             for(var i =0;i < items.length;i++) {
               //  Roo.log(['add child', items[i]]);
-                nitems.push(cn.addxtype(Roo.apply({}, items[i])));
+                nitems.push(cn.addxtype(items[i].xns == false ? items[i] : Roo.apply({}, items[i])));
             }
         }
         
@@ -3095,7 +3095,7 @@ Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component,  {
     
     imgResponsive: true,
     border: '',
-    src: 'about:blank',
+    src: 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=',
     href: false,
     target: false,
     xsUrl: '',
@@ -12200,7 +12200,8 @@ Roo.form.VTypes = function(){
     var alpha = /^[a-zA-Z_]+$/;
     var alphanum = /^[a-zA-Z0-9_]+$/;
     var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,24}$/;
-    var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
+    var url = /^(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
+    var urlWeb = /^((https?):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
 
     // All these messages and functions are configurable
     return {
@@ -12229,6 +12230,13 @@ Roo.form.VTypes = function(){
         url : function(v){
             return url.test(v);
         },
+        /**
+         * The funciton used to validate URLs (only allow schemes 'https' and 'http')
+         * @param {String} v The URL
+         */
+        urlWeb : function(v) {
+            return urlWeb.test(v);
+        },
         /**
          * The error text to display when the url validation function returns false
          * @type String
@@ -12614,7 +12622,7 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
             cls: 'glyphicon form-control-feedback'
         };
             
-        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+        if(this.hasFeedback && this.inputType != 'hidden'){
             
             inputblock = {
                 cls : 'has-feedback',
@@ -12669,7 +12677,7 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
                 });
             }
             
-            if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+            if(this.hasFeedback && this.inputType != 'hidden'){
                 inputblock.cls += ' has-feedback';
                 inputblock.cn.push(feedback);
             }
@@ -12941,6 +12949,15 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
         }
         
         this.inputEl().on('change', this.onChange, this);
+
+        if(this.hasFeedback && this.inputType != 'hidden'){
+            
+            var feedback = this.el.select('.form-control-feedback', true).first();
+
+            if(feedback) {
+                feedback.hide();
+            }
+        }
         
     },
     filterValidation : function(e){
@@ -13074,7 +13091,21 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
      */
     reset : function(){
         this.setValue(this.originalValue);
-        this.validate();
+        // this.validate();
+        this.el.removeClass([this.invalidClass, this.validClass]);
+        this.inputEl().removeClass(['is-valid', 'is-invalid']);
+
+        if(this.hasFeedback && this.inputType != 'hidden'){
+            
+            var feedback = this.el.select('.form-control-feedback', true).first();
+            
+            if(feedback){
+                this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+                feedback.update('');
+                feedback.hide();
+            }
+            
+        }
     },
      /**
      * Returns the name of the field
@@ -13088,9 +13119,7 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
      * @return {Mixed} value The field value
      */
     getValue : function(){
-        
         var v = this.inputEl().getValue();
-        
         return v;
     },
     /**
@@ -13183,12 +13212,15 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
         
         this.el.removeClass([this.invalidClass, 'is-invalid']);
         
-        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+        if(this.hasFeedback && this.inputType != 'hidden'){
             
             var feedback = this.el.select('.form-control-feedback', true).first();
             
             if(feedback){
                 this.el.select('.form-control-feedback', true).first().removeClass(this.invalidFeedbackClass);
+
+                feedback.update('');
+                feedback.hide();
             }
             
         }
@@ -13205,7 +13237,7 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
      * Mark this field as valid
      */
     markValid : function()
-    {
+    {   
         if(!this.el  || this.preventMark){ // not rendered...
             return;
         }
@@ -13217,6 +13249,8 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
             
         if(feedback){
             this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+            feedback.update('');
+            feedback.hide();
         }
         
         if(this.indicator){
@@ -13238,7 +13272,7 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
             this.inputEl().addClass('is-valid');
         }
 
-        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank && (this.getValue().length || this.forceFeedback)){
+        if(this.hasFeedback && this.inputType != 'hidden'){
             
             var feedback = this.el.select('.form-control-feedback', true).first();
             
@@ -13270,6 +13304,8 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
         if(feedback){
             this.el.select('.form-control-feedback', true).first().removeClass(
                     [this.invalidFeedbackClass, this.validFeedbackClass]);
+            feedback.update('');
+            feedback.hide();
         }
 
         if(this.disabled){
@@ -13292,15 +13328,23 @@ Roo.extend(Roo.bootstrap.form.Input, Roo.bootstrap.Component,  {
         
         
         
-        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+        if(this.hasFeedback && this.inputType != 'hidden'){
             
             var feedback = this.el.select('.form-control-feedback', true).first();
             
             if(feedback){
                 this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
                 
-                if(this.getValue().length || this.forceFeedback){
-                    this.el.select('.form-control-feedback', true).first().addClass([this.invalidFeedbackClass]);
+                this.el.select('.form-control-feedback', true).first().addClass([this.invalidFeedbackClass]);
+
+                feedback.update(typeof(msg) == 'undefined' ? this.invalidText : msg);
+
+                if(!this.allowBlank && !this.getRawValue().length){
+                    feedback.update(this.blankText);
+                }
+
+                if(feedback.dom.innerHTML) {
+                    feedback.show();
                 }
                 
             }
@@ -13489,7 +13533,7 @@ Roo.extend(Roo.bootstrap.form.TextArea, Roo.bootstrap.form.Input,  {
         
         var inputblock = input;
         
-        if(this.hasFeedback && !this.allowBlank){
+        if(this.hasFeedback){
             
             var feedback = {
                 tag: 'span',
@@ -13522,7 +13566,7 @@ Roo.extend(Roo.bootstrap.form.TextArea, Roo.bootstrap.form.Input,  {
             
             inputblock.cn.push(input);
             
-            if(this.hasFeedback && !this.allowBlank){
+            if(this.hasFeedback){
                 inputblock.cls += ' has-feedback';
                 inputblock.cn.push(feedback);
             }
@@ -13576,12 +13620,15 @@ Roo.extend(Roo.bootstrap.form.TextArea, Roo.bootstrap.form.Input,  {
         this.el.removeClass( this.validClass);
         this.inputEl().removeClass('is-invalid');
          
-        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+        if(this.hasFeedback && this.inputType != 'hidden'){
             
             var feedback = this.el.select('.form-control-feedback', true).first();
             
             if(feedback){
                 this.el.select('.form-control-feedback', true).first().removeClass(this.invalidFeedbackClass);
+
+                feedback.update('');
+                feedback.hide();
             }
             
         }
@@ -13605,6 +13652,8 @@ Roo.extend(Roo.bootstrap.form.TextArea, Roo.bootstrap.form.Input,  {
             
         if(feedback){
             this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+            feedback.update('');
+            feedback.hide();
         }
 
         if(this.disabled || this.allowBlank){
@@ -13624,7 +13673,7 @@ Roo.extend(Roo.bootstrap.form.TextArea, Roo.bootstrap.form.Input,  {
         }
         
         
-        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank && (this.getValue().length || this.forceFeedback)){
+        if(this.hasFeedback && this.inputType != 'hidden'){
             
             var feedback = this.el.select('.form-control-feedback', true).first();
             
@@ -13655,9 +13704,11 @@ Roo.extend(Roo.bootstrap.form.TextArea, Roo.bootstrap.form.Input,  {
             
         if(feedback){
             this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+            feedback.update('');
+            feedback.hide();
         }
 
-        if(this.disabled || this.allowBlank){
+        if(this.disabled){
             return;
         }
         
@@ -13681,15 +13732,23 @@ Roo.extend(Roo.bootstrap.form.TextArea, Roo.bootstrap.form.Input,  {
         }
         
         // fixme ... this may be depricated need to test..
-        if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+        if(this.hasFeedback && this.inputType != 'hidden'){
             
             var feedback = this.el.select('.form-control-feedback', true).first();
             
             if(feedback){
                 this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
                 
-                if(this.getValue().length || this.forceFeedback){
-                    this.el.select('.form-control-feedback', true).first().addClass([this.invalidFeedbackClass]);
+                this.el.select('.form-control-feedback', true).first().addClass([this.invalidFeedbackClass]);
+
+                feedback.update(this.invalidText);
+
+                if(!this.allowBlank && !this.getRawValue().length){
+                    feedback.update(this.blankText);
+                }
+
+                if(feedback.dom.innerHTML) {
+                    feedback.show();
                 }
                 
             }
@@ -22814,7 +22873,7 @@ Roo.extend(Roo.bootstrap.TabPanel, Roo.bootstrap.Component,  {
  * Create a new DateField
  * @param {Object} config The config object
  */
-
 Roo.bootstrap.form.DateField = function(config){
     Roo.bootstrap.form.DateField.superclass.constructor.call(this, config);
      this.addEvents({
@@ -22857,12 +22916,6 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
      * valid according to {@link Date#parseDate} (defaults to 'm/d/y').
      */
     format : "m/d/y",
-    /**
-     * @cfg {String} altFormats
-     * Multiple date formats separated by "|" to try when parsing a user input value and it doesn't match the defined
-     * format (defaults to 'm/d/Y|m-d-y|m-d-Y|m/d|m-d|d').
-     */
-    altFormats : "m/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d",
     
     weekStart : 0,
     
@@ -22889,6 +22942,8 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     _events: [],
     
     singleMode : false,
+
+    hiddenField : false,
     
     UTCDate: function()
     {
@@ -22916,17 +22971,77 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     
     setUTCDate: function(d) {
             this.date = d;
-            this.setValue(this.formatDate(this.date));
+            this.setValue(this.date);
+    },
+
+    translateDates: function(lang) 
+    {
+        var translation = Roo.bootstrap.form.DateField.dates[lang] = {
+            days: [],
+            daysShort: [],
+            daysMin: [],
+            months: [],
+            monthsShort: []
+        };
+
+        var locale = lang.replace('_', '-');
+
+        var is_latin = [ 'zh-hk', 'zh-cn', 'jp', 'ko' ].indexOf(locale.toLowerCase()) < 0; 
+                
+
+        // fill days
+        for(var i = 0; i < 7; i++) {
+            var date = new Date(2020, 0, 5 + i);
+
+            var day = new Intl.DateTimeFormat(locale, {
+                weekday : 'long'
+            }).format(date);
+
+            var dayShort = new Intl.DateTimeFormat(locale, {
+                weekday : 'short'
+            }).format(date);
+
+            var dayMin = new Intl.DateTimeFormat(locale, {
+                weekday : 'narrow'
+            }).format(date);
+
+            if(is_latin) {
+                dayShort = day.substring(0, 3);
+                dayMin = day.substring(0, 2);
+            }
+            
+            translation.days.push(day);
+            translation.daysShort.push(dayShort);
+            translation.daysMin.push(dayMin);
+        }
+
+        // fill months
+        for(var i = 0; i < 12; i++) {
+            var date = new Date(2020, i);
+
+            var month = new Intl.DateTimeFormat(locale, {
+                month : 'long'
+            }).format(date);
+
+            var monthShort = new Intl.DateTimeFormat(locale, {
+                month : 'short'
+            }).format(date);
+
+            if(is_latin) {
+                monthShort = month.substring(0, 3);
+            }
+
+            translation.months.push(month);
+            translation.monthsShort.push(monthShort);
+        }
     },
         
     onRender: function(ct, position)
     {
         
         Roo.bootstrap.form.DateField.superclass.onRender.call(this, ct, position);
-        
-        this.language = this.language || 'en';
-        this.language = this.language in Roo.bootstrap.form.DateField.dates ? this.language : this.language.split('-')[0];
-        this.language = this.language in Roo.bootstrap.form.DateField.dates ? this.language : "en";
+
+        this.translateDates(this.language);
         
         this.isRTL = Roo.bootstrap.form.DateField.dates[this.language].rtl || false;
         this.format = this.format || 'm/d/y';
@@ -22989,15 +23104,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
         }
         
         Roo.each(this.picker().select('tfoot th.today', true).elements, function(v){
-            if(!this.calendarWeeks){
-                v.remove();
-                return;
-            }
-            
-            v.dom.innerHTML = Roo.bootstrap.form.DateField.dates[this.language].today;
-            v.attr('colspan', function(i, val){
-                return parseInt(val) + 1;
-            });
+            v.dom.innerHTML = Roo.bootstrap.form.DateField.todayText;
         });
                        
         
@@ -23016,6 +23123,14 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
         if(this.isInline) {
             this.showPopup();
         }
+
+        this.hiddenField = this.inputEl().insertSibling(
+            {tag : 'input', type : 'hidden', name : this.name},
+            'before',
+            true
+        );
+        this.inputEl().dom.setAttribute('name', this.name + '____hidden___');
+
     },
     
     picker : function()
@@ -23035,14 +23150,6 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
             ]
         };
         
-        if(this.calendarWeeks){
-            dow.cn.push({
-                tag: 'th',
-                cls: 'cw',
-                html: '&nbsp;'
-            })
-        }
-        
         while (dowCnt < this.weekStart + 7) {
             dow.cn.push({
                 tag: 'th',
@@ -23101,12 +23208,6 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                 today = this.UTCToday();
         
         this.picker().select('>.datepicker-days thead th.switch', true).first().dom.innerHTML = Roo.bootstrap.form.DateField.dates[this.language].months[month]+' '+year;
-        
-//        this.picker().select('>tfoot th.today', true).first().dom.innerHTML = Roo.bootstrap.form.DateField.dates[this.language].today;
-        
-//        this.picker.select('>tfoot th.today').
-//                                             .text(dates[this.language].today)
-//                                             .toggle(this.todayBtn !== false);
     
         this.updateNavArrows();
         this.fillMonths();
@@ -23141,26 +23242,6 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                     tag: 'tr',
                     cn: []
                 };
-                
-                if(this.calendarWeeks){
-                    // ISO 8601: First week contains first thursday.
-                    // ISO also states week starts on Monday, but we can be more abstract here.
-                    var
-                    // Start of current week: based on weekstart/current date
-                    ws = new Date(+prevMonth + (this.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
-                    // Thursday of this week
-                    th = new Date(+ws + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
-                    // First Thursday of year, year from thursday
-                    yth = new Date(+(yth = this.UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
-                    // Calendar week: ms between thursdays, div ms per day, div 7 days
-                    calWeek =  (th - yth) / 864e5 / 7 + 1;
-                    
-                    fillMonths.cn.push({
-                        tag: 'td',
-                        cls: 'cw',
-                        html: calWeek
-                    });
-                }
             }
             
             if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month)) {
@@ -23268,24 +23349,18 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
         this.picker().setTop(this.inputEl().getBottom()).setLeft(this.inputEl().getLeft());
     },
     
+    // return false when it fails
     parseDate : function(value)
     {
-        if(!value || value instanceof Date){
-            return value;
-        }
-        var v = Date.parseDate(value, this.format);
-        if (!v && (this.useIso || value.match(/^(\d{4})-0?(\d+)-0?(\d+)/))) {
-            v = Date.parseDate(value, 'Y-m-d');
+        if(!value) {
+            return false;
         }
-        if(!v && this.altFormats){
-            if(!this.altFormatsArray){
-                this.altFormatsArray = this.altFormats.split("|");
-            }
-            for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
-                v = Date.parseDate(value, this.altFormatsArray[i]);
-            }
+        if(value instanceof Date){
+            return value;
         }
-        return v;
+        var v = Date.parseDate(value, 'Y-m-d');
+
+        return (typeof(v) == 'undefined') ? false : v;
     },
     
     formatDate : function(date, fmt)
@@ -23293,6 +23368,20 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
         return (!date || !(date instanceof Date)) ?
         date : date.dateFormat(fmt || this.format);
     },
+
+    translateDate : function(date)
+    {
+        switch(this.language) {
+            case 'zh_CN':
+                return new Intl.DateTimeFormat('zh-CN', {
+                    year : 'numeric',
+                    month : 'long',
+                    day : 'numeric'
+                }).format(date);
+            default :
+                return this.formatDate(date);
+        }
+    },
     
     onFocus : function()
     {
@@ -23303,10 +23392,17 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     onBlur : function()
     {
         Roo.bootstrap.form.DateField.superclass.onBlur.call(this);
-        
-        var d = this.inputEl().getValue();
-        
-        this.setValue(d);
+
+        if(!this.readOnly) {
+            var d = this.inputEl().getValue();
+            var date = this.parseDate(d);
+            if(date) {
+                this.setValue(date);
+            }
+            else {
+                this.setValue(this.getValue());
+            }
+        }
                 
         this.hidePopup();
     },
@@ -23348,17 +23444,56 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     setValue: function(v)
     {
         if(this.fireEvent('beforeselect', this, v) !== false){
-            var d = new Date(this.parseDate(v) ).clearTime();
-        
-            if(isNaN(d.getTime())){
-                this.date = this.viewDate = '';
-                Roo.bootstrap.form.DateField.superclass.setValue.call(this, '');
+            var d = this.parseDate(v);
+
+            if(!d) {
+                this.date = this.viewDate = this.value = this.hiddenField.value =  '';
+                if(this.rendered){
+                    this.inputEl().dom.value = '';
+                    this.validate();
+                }
+                return;
+            }
+
+            d = new Date(d).clearTime();
+
+            this.value = this.hiddenField.value = d.dateFormat('Y-m-d');
+
+            v = this.translateDate(d);
+            if(this.rendered){
+                this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+                this.validate();
+            }
+
+            this.date = new Date(d.getTime() - d.getTimezoneOffset()*60000);
+
+            this.update();
+
+            this.fireEvent('select', this, this.date);
+        }
+    },
+
+    // bypass validation
+    setRawValue : function(v){
+        if(this.fireEvent('beforeselect', this, v) !== false){
+            var d = this.parseDate(v);
+
+            if(!d) {
+                this.date = this.viewDate = this.value = this.hiddenField.value =  '';
+                if(this.rendered){
+                    this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+                }
                 return;
             }
 
-            v = this.formatDate(d);
+            d = new Date(d).clearTime();
+
+            this.value = this.hiddenField.value = d.dateFormat('Y-m-d');
 
-            Roo.bootstrap.form.DateField.superclass.setValue.call(this, v);
+            v = this.translateDate(d);
+            if(this.rendered){
+                this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+            }
 
             this.date = new Date(d.getTime() - d.getTimezoneOffset()*60000);
 
@@ -23370,7 +23505,11 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     
     getValue: function()
     {
-        return this.formatDate(this.date);
+        return this.value;
+    },
+
+    getRawValue : function(){
+        return this.getValue();
     },
     
     fireKey: function(e)
@@ -23413,7 +23552,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                 if (this.dateWithinRange(newDate)){
                     this.date = newDate;
                     this.viewDate = newViewDate;
-                    this.setValue(this.formatDate(this.date));
+                    this.setValue(this.date);
 //                    this.update();
                     e.preventDefault();
                     dateChanged = true;
@@ -23440,19 +23579,19 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                 if (this.dateWithinRange(newDate)){
                     this.date = newDate;
                     this.viewDate = newViewDate;
-                    this.setValue(this.formatDate(this.date));
+                    this.setValue(this.date);
 //                    this.update();
                     e.preventDefault();
                     dateChanged = true;
                 }
                 break;
             case 13: // enter
-                this.setValue(this.formatDate(this.date));
+                this.setValue(this.date);
                 this.hidePopup();
                 e.preventDefault();
                 break;
             case 9: // tab
-                this.setValue(this.formatDate(this.date));
+                this.setValue(this.date);
                 this.hidePopup();
                 break;
             case 16: // shift
@@ -23506,7 +23645,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                         var date = new Date();
                         this.date = this.UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
 //                        this.fill()
-                        this.setValue(this.formatDate(this.date));
+                        this.setValue(this.date);
                         
                         this.hidePopup();
                         break;
@@ -23527,7 +23666,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                     }
                     
                     if(this.singleMode){
-                        this.setValue(this.formatDate(this.viewDate));
+                        this.setValue(this.viewDate);
                         this.hidePopup();
                         return;
                     }
@@ -23563,8 +23702,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
                     this.date = this.UTCDate(year, month, day,0,0,0,0);
                     this.viewDate = this.UTCDate(year, month, Math.min(28, day),0,0,0,0);
 //                    this.fill();
-                    //Roo.log(this.formatDate(this.date));
-                    this.setValue(this.formatDate(this.date));
+                    this.setValue(this.date);
                     this.hidePopup();
                 }
                 break;
@@ -23575,7 +23713,8 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     {
         this.startDate = startDate || -Infinity;
         if (this.startDate !== -Infinity) {
-            this.startDate = this.parseDate(this.startDate);
+            var date = this.parseDate(this.startDate);
+            this.startDate = date ? date : -Infinity;
         }
         this.update();
         this.updateNavArrows();
@@ -23585,7 +23724,8 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
     {
         this.endDate = endDate || Infinity;
         if (this.endDate !== Infinity) {
-            this.endDate = this.parseDate(this.endDate);
+            var date = this.parseDate(this.endDate);
+            this.endDate = date ? date : Infinity;
         }
         this.update();
         this.updateNavArrows();
@@ -23754,7 +23894,7 @@ Roo.extend(Roo.bootstrap.form.DateField, Roo.bootstrap.form.Input,  {
             return false;
         }
         
-        if(typeof(this.parseDate(value)) == 'undefined'){
+        if(!this.parseDate(value)){
             return false;
         }
         
@@ -23840,16 +23980,9 @@ Roo.apply(Roo.bootstrap.form.DateField,  {
         ]
     },
     
-    dates:{
-        en: {
-            days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
-            daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
-            daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
-            months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
-            monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
-            today: "Today"
-        }
-    },
+    dates : {},
+
+    todayText : "Today",
     
     modes: [
     {
@@ -23983,7 +24116,8 @@ Roo.extend(Roo.bootstrap.form.TimeField, Roo.bootstrap.form.Input,  {
      */
     format : "H:i",
     minuteStep : 1,
-
+    language : 'en',
+    hiddenField : false,
     getAutoCreate : function()
     {
         this.after = '<i class="fa far fa-clock"></i>';
@@ -23995,6 +24129,8 @@ Roo.extend(Roo.bootstrap.form.TimeField, Roo.bootstrap.form.Input,  {
     {
         
         Roo.bootstrap.form.TimeField.superclass.onRender.call(this, ct, position);
+
+        this.language = this.language in Roo.bootstrap.form.TimeField.periodText ? this.language : "en";
                 
         this.pickerEl = Roo.get(document.body).createChild(Roo.bootstrap.form.TimeField.template);
         
@@ -24017,6 +24153,14 @@ Roo.extend(Roo.bootstrap.form.TimeField, Roo.bootstrap.form.Input,  {
         this.pop.select('.minutes-down', true).first().on('click', this.onDecrementMinutes, this);
         this.pop.select('button.period', true).first().on('click', this.onTogglePeriod, this);
         this.pop.select('button.ok', true).first().on('click', this.setTime, this);
+        this.pop.select('button.ok', true).first().dom.innerHTML = Roo.bootstrap.form.TimeField.okText;
+
+        this.hiddenField = this.inputEl().insertSibling(
+            {tag : 'input', type : 'hidden', name : this.name},
+            'before',
+            true
+        );
+        this.inputEl().dom.setAttribute('name', this.name + '____hidden___');
 
     },
     
@@ -24210,8 +24354,12 @@ Roo.extend(Roo.bootstrap.form.TimeField, Roo.bootstrap.form.Input,  {
     
     update: function()
     {
-        
-        this.time = (typeof(this.time) === 'undefined') ? new Date() : this.time;
+        // default minute is a multiple of minuteStep
+        if(typeof(this.time) === 'undefined' || this.time.length == 0) {
+            this.time = new Date();
+            this.time = this.time.add(Date.MINUTE, Math.round(parseInt(this.time.format('i')) / this.minuteStep) * this.minuteStep - parseInt(this.time.format('i')));
+        }
+        this.time = (typeof(this.time) === 'undefined' || this.time.length == 0) ? new Date() : this.time;
         
         this.fill();
     },
@@ -24220,10 +24368,10 @@ Roo.extend(Roo.bootstrap.form.TimeField, Roo.bootstrap.form.Input,  {
     {
         var hours = this.time.getHours();
         var minutes = this.time.getMinutes();
-        var period = 'AM';
+        var period = Roo.bootstrap.form.TimeField.periodText[this.language]['am'];
         
         if(hours > 11){
-            period = 'PM';
+            period = Roo.bootstrap.form.TimeField.periodText[this.language]['pm'];
         }
         
         if(hours == 0){
@@ -24319,7 +24467,7 @@ Roo.extend(Roo.bootstrap.form.TimeField, Roo.bootstrap.form.Input,  {
         this.update();
         this.place();
         
-        this.fireEvent('show', this, this.date);
+        this.fireEvent('show', this, this.time);
     },
     
     hide : function()
@@ -24327,18 +24475,107 @@ Roo.extend(Roo.bootstrap.form.TimeField, Roo.bootstrap.form.Input,  {
         this.picker().hide();
         this.pop.hide();
         
-        this.fireEvent('hide', this, this.date);
+        this.fireEvent('hide', this, this.time);
     },
     
     setTime : function()
     {
         this.hide();
-        this.setValue(this.time.format(this.format));
+        this.setValue(this.time);
         
-        this.fireEvent('select', this, this.date);
+        this.fireEvent('select', this, this.time);
         
         
     },
+
+    // return false when it fails
+    parseTime : function(value)
+    {
+        if(!value) {
+            return false;
+        }
+        if(value instanceof Date){
+            return value;
+        }
+        var v = Date.parseDate(value, 'H:i:s');
+
+        return (typeof(v) == 'undefined') ? false : v;
+    },
+
+    translateTime : function(time)
+    {
+        switch(this.language) {
+            case 'zh_CN':
+                return new Intl.DateTimeFormat('zh-CN', {
+                    hour : 'numeric',
+                    minute : 'numeric',
+                    hour12 : true
+                }).format(time);
+            default :
+                return time.format(this.format);
+        }
+    },
+
+    setValue: function(v)
+    {
+        var t = this.parseTime(v);
+
+        if(!t) {
+            this.time = this.value = this.hiddenField.value =  '';
+            if(this.rendered){
+                this.inputEl().dom.value = '';
+                this.validate();
+            }
+            return;
+        }
+
+        this.value = this.hiddenField.value = t.dateFormat('H:i:s');
+
+        v = this.translateTime(t);
+
+        if(this.rendered){
+            this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+            this.validate();
+        }
+
+        this.time = t;
+
+        this.update();
+    },
+
+    setRawValue: function(v)
+    {
+        var t = this.parseTime(v);
+
+        if(!t) {
+            this.time = this.value = this.hiddenField.value =  '';
+            if(this.rendered){
+                this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+            }
+            return;
+        }
+
+        this.value = this.hiddenField.value = t.dateFormat('H:i:s');
+
+        v = this.translateTime(t);
+
+        if(this.rendered){
+            this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+        }
+
+        this.time = t;
+
+        this.update();
+    },
+
+    getValue: function()
+    {
+        return this.value;
+    },
+
+    getRawValue : function(){
+        return this.getValue();
+    },
     
     onMousedown: function(e){
         e.stopPropagation();
@@ -24385,10 +24622,21 @@ Roo.extend(Roo.bootstrap.form.TimeField, Roo.bootstrap.form.Input,  {
     
    
 });
+Roo.apply(Roo.bootstrap.form.TimeField,  {
+    okText : 'OK',
+    periodText : {
+        en : {
+            am : 'AM',
+            pm : 'PM'
+        },
+        zh_CN : {
+            am : '上午',
+            pm : '下午'
+        }
+    }
+});
 
 Roo.apply(Roo.bootstrap.form.TimeField,  {
-  
     template : {
         tag: 'div',
         cls: 'datepicker dropdown-menu',
@@ -24429,7 +24677,7 @@ Roo.apply(Roo.bootstrap.form.TimeField,  {
                                             {
                                                 tag: 'button',
                                                 cls: 'btn btn-info ok',
-                                                html: 'OK'
+                                                html: "OK" // this is overridden on construciton
                                             }
                                         ]
                                     }
@@ -25658,6 +25906,7 @@ Roo.extend(Roo.bootstrap.form.Radio, Roo.bootstrap.Component, {
  * @class Roo.bootstrap.form.SecurePass
  * @extends Roo.bootstrap.form.Input
  * Bootstrap SecurePass class
+ * @cfg {Number} minimumStrength invalid if the strength of the password input is less than the minimum strength (from 0 to 3) (default 2)
  *
  * 
  * @constructor
@@ -25666,63 +25915,15 @@ Roo.extend(Roo.bootstrap.form.Radio, Roo.bootstrap.Component, {
  */
  
 Roo.bootstrap.form.SecurePass = function (config) {
-    // these go here, so the translation tool can replace them..
-    this.errors = {
-        PwdEmpty: "Please type a password, and then retype it to confirm.",
-        PwdShort: "Your password must be at least 6 characters long. Please type a different password.",
-        PwdLong: "Your password can't contain more than 16 characters. Please type a different password.",
-        PwdBadChar: "The password contains characters that aren't allowed. Please type a different password.",
-        IDInPwd: "Your password can't include the part of your ID. Please type a different password.",
-        FNInPwd: "Your password can't contain your first name. Please type a different password.",
-        LNInPwd: "Your password can't contain your last name. Please type a different password.",
-        TooWeak: "Your password is Too Weak."
-    },
-    this.meterLabel = "Password strength:";
-    this.pwdStrengths = ["Too Weak", "Weak", "Medium", "Strong"];
-    this.meterClass = [
-        "roo-password-meter-tooweak", 
-        "roo-password-meter-weak", 
-        "roo-password-meter-medium", 
-        "roo-password-meter-strong", 
-        "roo-password-meter-grey"
-    ];
-    
-    this.errors = {};
     
     Roo.bootstrap.form.SecurePass.superclass.constructor.call(this, config);
 }
 
 Roo.extend(Roo.bootstrap.form.SecurePass, Roo.bootstrap.form.Input, {
-    /**
-     * @cfg {String/Object} errors A Error spec, or true for a default spec (defaults to
-     * {
-     *  PwdEmpty: "Please type a password, and then retype it to confirm.",
-     *  PwdShort: "Your password must be at least 6 characters long. Please type a different password.",
-     *  PwdLong: "Your password can't contain more than 16 characters. Please type a different password.",
-     *  PwdBadChar: "The password contains characters that aren't allowed. Please type a different password.",
-     *  IDInPwd: "Your password can't include the part of your ID. Please type a different password.",
-     *  FNInPwd: "Your password can't contain your first name. Please type a different password.",
-     *  LNInPwd: "Your password can't contain your last name. Please type a different password."
-     * })
-     */
-    // private
-    
-    meterWidth: 300,
-    errorMsg :'',    
-    errors: false,
-    imageRoot: '/',
-    /**
-     * @cfg {String/Object} Label for the strength meter (defaults to
-     * 'Password strength:')
-     */
+    minimumStrength : 2,
     // private
-    meterLabel: '',
-    /**
-     * @cfg {String/Object} pwdStrengths A pwdStrengths spec, or true for a default spec (defaults to
-     * ['Weak', 'Medium', 'Strong'])
-     */
-    // private    
-    pwdStrengths: false,    
+    meterWidth: 300, 
+    imageRoot: '/',  
     // private
     strength: 0,
     // private
@@ -25810,13 +26011,13 @@ Roo.extend(Roo.bootstrap.form.SecurePass, Roo.bootstrap.form.Input, {
         
         //var pm = this.trigger.child('div/div/div').dom;
         var pm = this.trigger.child('div/div');
-        pm.removeClass(this.meterClass);
-        pm.addClass(this.meterClass[strength]);
+        pm.removeClass(Roo.bootstrap.form.SecurePass.meterClass);
+        pm.addClass(Roo.bootstrap.form.SecurePass.meterClass[strength]);
                 
         
         var pt = this.trigger.child('/div').child('>*[class=roo-password-meter-text]').dom;        
                 
-        pt.innerHTML = this.meterLabel + '&nbsp;' + this.pwdStrengths[strength];
+        pt.innerHTML = Roo.bootstrap.form.SecurePass.meterLabel + '&nbsp;' + Roo.bootstrap.form.SecurePass.pwdStrengths[strength];
         
         this._lastPwd = pwd;
     },
@@ -25827,7 +26028,7 @@ Roo.extend(Roo.bootstrap.form.SecurePass, Roo.bootstrap.form.Input, {
         this._lastPwd = '';
         
         var pm = this.trigger.child('div/div');
-        pm.removeClass(this.meterClass);
+        pm.removeClass(Roo.bootstrap.form.SecurePass.meterClass);
         pm.addClass('roo-password-meter-grey');        
         
         
@@ -25848,8 +26049,7 @@ Roo.extend(Roo.bootstrap.form.SecurePass, Roo.bootstrap.form.Input, {
                 return true;
             }
 
-            this.markInvalid(this.errors.PwdEmpty);
-            this.errorMsg = this.errors.PwdEmpty;
+            this.invalidText = Roo.bootstrap.form.SecurePass.errors.PwdEmpty;
             return false;
         }
         
@@ -25858,18 +26058,15 @@ Roo.extend(Roo.bootstrap.form.SecurePass, Roo.bootstrap.form.Input, {
         }
         
         if (!value.match(/[\x21-\x7e]+/)) {
-            this.markInvalid(this.errors.PwdBadChar);
-            this.errorMsg = this.errors.PwdBadChar;
+            this.invalidText = Roo.bootstrap.form.SecurePass.errors.PwdBadChar;
             return false;
         }
         if (value.length < 6) {
-            this.markInvalid(this.errors.PwdShort);
-            this.errorMsg = this.errors.PwdShort;
+            this.invalidText = Roo.bootstrap.form.SecurePass.errors.PwdShort;
             return false;
         }
         if (value.length > 16) {
-            this.markInvalid(this.errors.PwdLong);
-            this.errorMsg = this.errors.PwdLong;
+            this.invalidText = Roo.bootstrap.form.SecurePass.errors.PwdLong;
             return false;
         }
         var strength;
@@ -25884,10 +26081,9 @@ Roo.extend(Roo.bootstrap.form.SecurePass, Roo.bootstrap.form.Input, {
         }
 
         
-        if (strength < 2) {
-            //this.markInvalid(this.errors.TooWeak);
-            this.errorMsg = this.errors.TooWeak;
-            //return false;
+        if (strength < this.minimumStrength) {
+            this.invalidText = Roo.bootstrap.form.SecurePass.errors.TooWeak;
+            return false;
         }
         
         
@@ -25896,14 +26092,13 @@ Roo.extend(Roo.bootstrap.form.SecurePass, Roo.bootstrap.form.Input, {
         //var pm = this.trigger.child('div/div/div').dom;
         
         var pm = this.trigger.child('div/div');
-        pm.removeClass(this.meterClass);
-        pm.addClass(this.meterClass[strength]);
+        pm.removeClass(Roo.bootstrap.form.SecurePass.meterClass);
+        pm.addClass(Roo.bootstrap.form.SecurePass.meterClass[strength]);
                 
         var pt = this.trigger.child('/div').child('>*[class=roo-password-meter-text]').dom;        
                 
-        pt.innerHTML = this.meterLabel + '&nbsp;' + this.pwdStrengths[strength];
-        
-        this.errorMsg = ''; 
+        pt.innerHTML = Roo.bootstrap.form.SecurePass.meterLabel + '&nbsp;' + Roo.bootstrap.form.SecurePass.pwdStrengths[strength];
+
         return true;
     },
     // private
@@ -26000,6 +26195,90 @@ Roo.extend(Roo.bootstrap.form.SecurePass, Roo.bootstrap.form.Input, {
         return this.IsLongEnough(pwd, 6) || !this.IsLongEnough(pwd, 0);
     }
           
+});
+
+Roo.bootstrap.form.SecurePass.errors = {
+    PwdEmpty: "Please type a password, and then retype it to confirm.",
+    PwdShort: "Your password must be at least 6 characters long. Please type a different password.",
+    PwdLong: "Your password can't contain more than 16 characters. Please type a different password.",
+    PwdBadChar: "The password contains characters that aren't allowed. Please type a different password.",
+    IDInPwd: "Your password can't include the part of your ID. Please type a different password.",
+    FNInPwd: "Your password can't contain your first name. Please type a different password.",
+    LNInPwd: "Your password can't contain your last name. Please type a different password.",
+    TooWeak: "Your password is Too Weak."
+};
+
+Roo.bootstrap.form.SecurePass.meterLabel = "Password strength:";
+Roo.bootstrap.form.SecurePass.pwdStrengths = ["Too Weak", "Weak", "Medium", "Strong"];
+Roo.bootstrap.form.SecurePass.meterClass = [
+    "roo-password-meter-tooweak", 
+    "roo-password-meter-weak", 
+    "roo-password-meter-medium", 
+    "roo-password-meter-strong", 
+    "roo-password-meter-grey"
+];/**
+ * @class Roo.bootstrap.form.Password
+ * @extends Roo.bootstrap.form.Input
+ * Bootstrap Password class
+ * 
+ * 
+ * 
+ * 
+ * @constructor
+ * Create a new Password
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.form.Password = function(config){
+    Roo.bootstrap.form.Password.superclass.constructor.call(this, config);
+
+    this.inputType = 'password';
+};
+
+Roo.extend(Roo.bootstrap.form.Password, Roo.bootstrap.form.Input, {
+
+    onRender : function(ct, position)
+    {
+        Roo.bootstrap.form.SecurePass.superclass.onRender.call(this, ct, position);
+
+        this.el.addClass('form-password');
+
+        this.wrap = this.inputEl().wrap({
+            cls : 'password-wrap'
+        });
+
+        this.toggle = this.wrap.createChild({
+            tag : 'Button',
+            cls : 'password-toggle'
+        });
+
+
+        this.toggleEl().addClass('password-hidden');
+
+        this.toggleEl().on('click', this.onToggleClick, this);;
+    },
+
+    toggleEl: function()
+    {
+        return this.el.select('button.password-toggle',true).first();
+    },
+
+    onToggleClick : function(e) 
+    {
+        var input = this.inputEl();
+        var toggle = this.toggleEl();
+
+        toggle.removeClass(['password-visible', 'password-hidden']);
+
+        if(input.attr('type') == 'password') {
+            input.attr('type', 'text');
+            toggle.addClass('password-visible');
+        }
+        else {
+            input.attr('type', 'password');
+            toggle.addClass('password-hidden');
+        }
+    }
 });Roo.rtf = {}; // namespace
 Roo.rtf.Hex = function(hex)
 {
@@ -29425,7 +29704,8 @@ Roo.extend(Roo.htmleditor.BlockFigure, Roo.htmleditor.Block, {
         var ret =   {
             tag: 'figure',
             'data-block' : 'Figure',
-            'data-width' : this.width, 
+            'data-width' : this.width,
+            'data-caption' : this.caption, 
             contenteditable : 'false',
             
             style : {
@@ -29498,6 +29778,8 @@ Roo.extend(Roo.htmleditor.BlockFigure, Roo.htmleditor.Block, {
         this.image_src = this.getVal(node, 'img', 'src');
          
         this.align = this.getVal(node, 'figure', 'align');
+        
+        /// not really used - as hidden captions do not store the content here..
         var figcaption = this.getVal(node, 'figcaption', false);
         if (figcaption !== '') {
             this.caption = this.getVal(figcaption, 'i', 'html');
@@ -29505,6 +29787,10 @@ Roo.extend(Roo.htmleditor.BlockFigure, Roo.htmleditor.Block, {
         
 
         this.caption_display = this.getVal(node, 'figcaption', 'data-display');
+        var dc = this.getVal(node, true, 'data-caption');
+        if (dc && dc.length) {
+            this.caption = dc;
+        }
         //this.text_align = this.getVal(node, 'figcaption', 'style','text-align');
         this.width = this.getVal(node, true, 'data-width');
         //this.margin = this.getVal(node, 'figure', 'style', 'margin');
@@ -31168,6 +31454,7 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
                             'rowspan',
                             'data-display',
                             'data-width',
+                            'data-caption',
                             'start' ,
                             'style',
                             // youtube embed.
@@ -31374,8 +31661,8 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         var cd = (e.browserEvent.clipboardData || window.clipboardData);
         
         // check what type of paste - if it's an image, then handle it differently.
-        if (cd.files && cd.files.length > 0) {
-            // pasting images?
+        if (cd.files && cd.files.length > 0 && cd.types.indexOf('text/html') < 0) {
+            // pasting images? 
             var urlAPI = (window.createObjectURL && window) || 
                 (window.URL && URL.revokeObjectURL && URL) || 
                 (window.webkitURL && webkitURL);
@@ -31418,8 +31705,8 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
             var parser = new Roo.rtf.Parser(cd.getData('text/rtf'));
             images = parser.doc ? parser.doc.getElementsByType('pict') : [];
         }
-        //Roo.log(images);
-        //Roo.log(imgs);
+        // Roo.log(images);
+        // Roo.log(imgs);
         // fixme..
         images = images.filter(function(g) { return !g.path.match(/^rtf\/(head|pgdsctbl|listtable|footerf)/); }) // ignore headers/footers etc.
                        .map(function(g) { return g.toDataURL(); })
@@ -32571,6 +32858,7 @@ Roo.bootstrap.form.HtmlEditor = function(config){
             * Fires when on any editor when an image is deleted
             * @param {Roo.bootstrap.form.HtmlEditor} this
             * @param {HTMLElement} img could also be a figure if blocks are enabled
+            * @param {HTMLElement} oldSrc source of image being replaced
             */
            imagedelete: true  
     });
@@ -32632,6 +32920,8 @@ Roo.extend(Roo.bootstrap.form.HtmlEditor, Roo.bootstrap.form.TextArea,  {
     tbContainer : false,
     
     bodyCls : '',
+
+    linkDialogCls : '',
     
     toolbarContainer :function() {
         return this.wrap.select('.x-html-editor-tb',true).first();
@@ -33156,12 +33446,13 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp
         var reader = new FileReader();
         reader.addEventListener('load', (function() {
             if (bl) {
+                var oldSrc = bl.image_src;
                 bl.image_src = reader.result;
                 //bl.caption = f.name;
                 bl.updateElement(sn);
                 this.editor.syncValue();
                 editor.owner.fireEvent('editorevent', editor.owner, false);
-                editor.owner.fireEvent('imageupdate', editor.owner, sn);
+                editor.owner.fireEvent('imageupdate', editor.owner, sn, oldSrc);
                 // we only do the first file!! and replace.
                 return;
             }
@@ -33177,10 +33468,11 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp
             }
             // just a standard img..
             if (sn && sn.tagName.toUpperCase() == 'IMG') {
+                var oldSrc = sn.src;
                 sn.src = reader.result;
                 this.editor.syncValue();
                 editor.owner.fireEvent('editorevent', editor.owner, false);
-                editor.owner.fireEvent('imageupdate', editor.owner, sn);
+                editor.owner.fireEvent('imageupdate', editor.owner, sn, oldSrc);
                 return;
             }
             editor.insertAtCursor('<img src="' + reader.result +'">');
@@ -33220,13 +33512,15 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp
                 }
                 if (url != '') {
                     this.selectedNode.setAttribute('href', newurl);
+                    this.editor.syncValue();
                     return;
                 }
                 if(newurl && newurl .match(/http(s):\/\/.+/)) {
                     this.editorcore.relayCmd('createlink', newurl);
                 }
                 this.editorcore.focus();
-            }
+            },
+            cls : this.editorcore.linkDialogCls
         });
     },
     /**
@@ -45301,7 +45595,7 @@ Roo.bootstrap.panel.Content = function( config){
                     {
                         tag : 'iframe',
                         style : 'border: 0px',
-                        src : 'about:blank'
+                        src : 'data:text/html,%3Cbody%3E%3C%2Fbody%3E'
                     }
                 ];
             }