fit-ui 2.8.2 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Controls/Input/maximize-highres.png +0 -0
- package/dist/Controls/Input/maximize.png +0 -0
- package/dist/Documentation.html +3 -3
- package/dist/Fit.UI.css +71 -6
- package/dist/Fit.UI.js +1017 -114
- package/dist/Fit.UI.min.css +2 -2
- package/dist/Fit.UI.min.js +1 -1
- package/dist/Resources/CKEditor/plugins/custombuttons/plugin.js +34 -0
- package/dist/Resources/CKEditor-with-maximize-button/CHANGES.md +2148 -0
- package/dist/Resources/CKEditor-with-maximize-button/LICENSE.md +1436 -0
- package/dist/Resources/CKEditor-with-maximize-button/README-FitUiChanges.txt +8 -0
- package/dist/Resources/CKEditor-with-maximize-button/README.md +39 -0
- package/dist/Resources/CKEditor-with-maximize-button/adapters/jquery.js +10 -0
- package/dist/Resources/CKEditor-with-maximize-button/build-config.js +79 -0
- package/dist/Resources/CKEditor-with-maximize-button/ckeditor.js +987 -0
- package/dist/Resources/CKEditor-with-maximize-button/config.js +34 -0
- package/dist/Resources/CKEditor-with-maximize-button/contents.css +208 -0
- package/dist/Resources/CKEditor-with-maximize-button/lang/da.js +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/lang/de.js +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/lang/en.js +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/autocomplete/skins/default.css +38 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/LICENSE.md +1244 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/README.md +21 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/dialogs/base64image.js +766 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/dialogs/base64image.original.js +503 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/icons/base64image.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/icons/hidpi/base64image.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/lang/da.js +12 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/lang/de.js +12 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/lang/en.js +12 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64image/plugin.js +58 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/base64imagepaste/plugin.js +91 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/clipboard/dialogs/paste.js +11 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/custombuttons/icons/custombuttons.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/custombuttons/plugin.js +99 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/dialog/dialogDefinition.js +4 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/dialog/styles/dialog.css +18 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/dragresize/LICENSE +19 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/dragresize/_source.css +85 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/dragresize/package.json +19 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/dragresize/plugin.js +395 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/dragresize/readme.md +35 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/emoji/assets/iconsall.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/emoji/assets/iconsall.svg +58 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/emoji/emoji.json +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/emoji/skins/default.css +237 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/icons.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/icons_hidpi.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/link/dialogs/anchor.js +8 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/link/dialogs/link.js +30 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/link/images/anchor.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/link/images/hidpi/anchor.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/pastefromword/filter/default.js +42 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/pastetools/filter/common.js +24 -0
- package/dist/Resources/CKEditor-with-maximize-button/plugins/pastetools/filter/image.js +12 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/dialog.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/dialog_ie.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/dialog_ie7.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/dialog_ie8.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/dialog_iequirks.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/dialog_opera.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/editor.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/editor_gecko.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/editor_ie.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/editor_ie7.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/editor_ie8.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/editor_iequirks.css +1 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/icons.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/icons_hidpi.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/images/arrow.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/images/close.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/images/hidpi/close.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/images/hidpi/lock-open.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/images/hidpi/lock.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/images/hidpi/refresh.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/images/lock-open.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/images/lock.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/images/refresh.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/readme.md +35 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/bootstrapck/skin.js +10 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/dialog.css +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/dialog_ie.css +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/dialog_ie8.css +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/dialog_iequirks.css +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/editor.css +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/editor_gecko.css +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/editor_ie.css +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/editor_ie8.css +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/editor_iequirks.css +5 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/icons.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/icons_hidpi.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/arrow.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/close.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/hidpi/close.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/hidpi/lock-open.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/hidpi/lock.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/hidpi/refresh.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/lock-open.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/lock.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/refresh.png +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/images/spinner.gif +0 -0
- package/dist/Resources/CKEditor-with-maximize-button/skins/moono-lisa/readme.md +46 -0
- package/dist/Resources/CKEditor-with-maximize-button/styles.js +137 -0
- package/dist/Resources/CKEditor-with-maximize-button/vendor/promise.js +13 -0
- package/package.json +1 -1
- package/types/index.d.ts +266 -113
- package/dist/Resources/ckeditor_4.17.2_6f06412961d8.zip +0 -0
package/dist/Fit.UI.js
CHANGED
|
@@ -451,6 +451,29 @@ Fit.Core.IsEqual = function(jsObj1, jsObj2)
|
|
|
451
451
|
return false;
|
|
452
452
|
}
|
|
453
453
|
|
|
454
|
+
/// <container name="Fit.Core.MergeOverwriteBehaviour">
|
|
455
|
+
/// Merge behaviour
|
|
456
|
+
/// </container>
|
|
457
|
+
Fit.Core.MergeOverwriteBehaviour = // Enums must exist runtime
|
|
458
|
+
{
|
|
459
|
+
/// <member container="Fit.Core.MergeOverwriteBehaviour" name="Always" access="public" static="true" type="string" default="Always">
|
|
460
|
+
/// <description> Always overwrite property values from target object with property values from merge object (default behaviour) </description>
|
|
461
|
+
/// </member>
|
|
462
|
+
Always: "Always",
|
|
463
|
+
|
|
464
|
+
/// <member container="Fit.Core.MergeOverwriteBehaviour" name="SkipNullAndUndefined" access="public" static="true" type="string" default="SkipNullAndUndefined">
|
|
465
|
+
/// <description> Always overwrite property values from target object with property values from merge object, except values from merge object that are Null or Undefined </description>
|
|
466
|
+
/// </member>
|
|
467
|
+
SkipNullAndUndefined: "SkipNullAndUndefined",
|
|
468
|
+
|
|
469
|
+
/// <member container="Fit.Core.MergeOverwriteBehaviour" name="Never" access="public" static="true" type="string" default="Never">
|
|
470
|
+
/// <description>
|
|
471
|
+
/// Never overwrite property values from target object - only add missing property values from merge object
|
|
472
|
+
/// </description>
|
|
473
|
+
/// </member>
|
|
474
|
+
Never: "Never"
|
|
475
|
+
};
|
|
476
|
+
|
|
454
477
|
/// <function container="Fit.Core" name="Merge" access="public" static="true" returns="$ObjectTypeA + $ObjectTypeB">
|
|
455
478
|
/// <description>
|
|
456
479
|
/// Deep merges two objects and returns the resulting object.
|
|
@@ -462,11 +485,13 @@ Fit.Core.IsEqual = function(jsObj1, jsObj2)
|
|
|
462
485
|
/// </description>
|
|
463
486
|
/// <param name="targetObject" type="$ObjectTypeA"> Target object </param>
|
|
464
487
|
/// <param name="mergeObject" type="$ObjectTypeB"> Merge object </param>
|
|
488
|
+
/// <param name="mergeObjectOverwriteBehaviour" type="Fit.Core.MergeOverwriteBehaviour" default="undefined"> Overwrite behaviour for merge object </param>
|
|
465
489
|
/// </function>
|
|
466
|
-
Fit.Core.Merge = function(targetObject, mergeObject)
|
|
490
|
+
Fit.Core.Merge = function(targetObject, mergeObject, mergeObjectOverwriteBehaviour)
|
|
467
491
|
{
|
|
468
492
|
Fit.Validation.ExpectObject(targetObject);
|
|
469
493
|
Fit.Validation.ExpectObject(mergeObject);
|
|
494
|
+
Fit.Validation.ExpectStringValue(mergeObjectOverwriteBehaviour, true);
|
|
470
495
|
|
|
471
496
|
/* // Test data
|
|
472
497
|
f1 = function() { alert("Hello"); };
|
|
@@ -524,10 +549,19 @@ Fit.Core.Merge = function(targetObject, mergeObject)
|
|
|
524
549
|
{
|
|
525
550
|
if (isObject(newObject[prop]) && isObject(mergeObject[prop]))
|
|
526
551
|
{
|
|
527
|
-
newObject[prop] = Fit.Core.Merge(newObject[prop], mergeObject[prop]);
|
|
552
|
+
newObject[prop] = Fit.Core.Merge(newObject[prop], mergeObject[prop], mergeObjectOverwriteBehaviour);
|
|
528
553
|
}
|
|
529
554
|
else
|
|
530
555
|
{
|
|
556
|
+
if (mergeObjectOverwriteBehaviour === Fit.Core.MergeOverwriteBehaviour.SkipNullAndUndefined && (mergeObject[prop] === null || mergeObject[prop] === undefined))
|
|
557
|
+
{
|
|
558
|
+
return; // Skip - ignore values of Null and Undefined from merge object
|
|
559
|
+
}
|
|
560
|
+
else if (mergeObjectOverwriteBehaviour === Fit.Core.MergeOverwriteBehaviour.Never && prop in newObject)
|
|
561
|
+
{
|
|
562
|
+
return; // Skip - never update values from target object, only add missing values
|
|
563
|
+
}
|
|
564
|
+
|
|
531
565
|
newObject[prop] = mergeObject[prop];
|
|
532
566
|
}
|
|
533
567
|
});
|
|
@@ -648,7 +682,7 @@ Fit._internal =
|
|
|
648
682
|
{
|
|
649
683
|
Core:
|
|
650
684
|
{
|
|
651
|
-
VersionInfo: { Major: 2, Minor:
|
|
685
|
+
VersionInfo: { Major: 2, Minor: 9, Patch: 0 } // Do NOT modify format - version numbers are programmatically changed when releasing new versions - MUST be on a separate line!
|
|
652
686
|
}
|
|
653
687
|
};
|
|
654
688
|
|
|
@@ -2875,7 +2909,7 @@ Fit.Browser.GetScreenDimensions = function(onlyAvailable)
|
|
|
2875
2909
|
}
|
|
2876
2910
|
|
|
2877
2911
|
/// <function container="Fit.Browser" name="IsMobile" access="public" static="true" returns="boolean">
|
|
2878
|
-
/// <description> Returns value indicating whether
|
|
2912
|
+
/// <description> Returns value indicating whether device is a mobile device or not </description>
|
|
2879
2913
|
/// <param name="includeTablets" type="boolean" default="true"> Value indicating whether tablets are considered mobile devices or not </param>
|
|
2880
2914
|
/// </function>
|
|
2881
2915
|
Fit.Browser.IsMobile = function(includeTablets)
|
|
@@ -2893,6 +2927,14 @@ Fit.Browser.IsMobile = function(includeTablets)
|
|
|
2893
2927
|
return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(nav) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(nav.substr(0,4)));
|
|
2894
2928
|
}
|
|
2895
2929
|
|
|
2930
|
+
/// <function container="Fit.Browser" name="IsTouchEnabled" access="public" static="true" returns="boolean">
|
|
2931
|
+
/// <description> Returns value indicating whether device is touch enabled or not </description>
|
|
2932
|
+
/// </function>
|
|
2933
|
+
Fit.Browser.IsTouchEnabled = function()
|
|
2934
|
+
{
|
|
2935
|
+
return ("ontouchstart" in window);
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2896
2938
|
|
|
2897
2939
|
/// <function container="Fit.Browser" name="Log" access="public" static="true">
|
|
2898
2940
|
/// <description> Log message or object </description>
|
|
@@ -2934,6 +2976,7 @@ Fit.Browser.LogDeprecated = function(msg)
|
|
|
2934
2976
|
/// <member name="IsMobile" type="boolean"> Boolean indicating whether this is a mobile device (tablet or phone) </member>
|
|
2935
2977
|
/// <member name="IsPhone" type="boolean"> Boolean indicating whether this is a phone </member>
|
|
2936
2978
|
/// <member name="IsTablet" type="boolean"> Boolean indicating whether this is a tablet device </member>
|
|
2979
|
+
/// <member name="IsTouchEnabled" type="boolean"> Boolean indicating whether this is a touch enabled device </member>
|
|
2937
2980
|
/// </container>
|
|
2938
2981
|
|
|
2939
2982
|
/// <container name="Fit.BrowserTypeDefs.BrowserInfo" extends="Fit.BrowserTypeDefs.BrowserDetails">
|
|
@@ -2980,6 +3023,7 @@ Fit.Browser.GetInfo = function(returnAppInfo)
|
|
|
2980
3023
|
Fit._internal.Browser.Info.IsMobile = Fit.Browser.IsMobile();
|
|
2981
3024
|
Fit._internal.Browser.Info.IsPhone = Fit.Browser.IsMobile(false); // Phone only
|
|
2982
3025
|
Fit._internal.Browser.Info.IsTablet = (Fit.Browser.IsMobile() === true && Fit.Browser.IsMobile(false) === false); // Tablet only
|
|
3026
|
+
Fit._internal.Browser.Info.IsTouchEnabled = Fit.Browser.IsTouchEnabled();
|
|
2983
3027
|
}
|
|
2984
3028
|
|
|
2985
3029
|
return Fit.Core.Clone(Fit._internal.Browser.Info); // Clone to ensure values are not shared and potentially changed
|
|
@@ -5153,6 +5197,28 @@ Fit.String.DecodeHtml = function(str)
|
|
|
5153
5197
|
return str.replace(/"/g, "\"").replace(/'/g, "'").replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&");
|
|
5154
5198
|
}
|
|
5155
5199
|
|
|
5200
|
+
/// <function container="Fit.String" name="ParseImageBlobUrls" access="public" static="true" returns="string[]">
|
|
5201
|
+
/// <description> Parse and return image blob URLs from image tags </description>
|
|
5202
|
+
/// <param name="str" type="string"> String to parse </param>
|
|
5203
|
+
/// </function>
|
|
5204
|
+
Fit.String.ParseImageBlobUrls = function(str)
|
|
5205
|
+
{
|
|
5206
|
+
var imageBlobUrls = [];
|
|
5207
|
+
var blobImages = str.match(/<img .*?src=(["'])blob:.+?\1.*?>/gi) || [];
|
|
5208
|
+
|
|
5209
|
+
Fit.Array.ForEach(blobImages, function(img)
|
|
5210
|
+
{
|
|
5211
|
+
var blobUrl = img.match(/src=(["'])(blob:.*?)\1/i)[2]; // 0 = Full match, 1 = double quote or ping character, 2 = blob URL
|
|
5212
|
+
|
|
5213
|
+
if (Fit.Array.Contains(imageBlobUrls, blobUrl) === false)
|
|
5214
|
+
{
|
|
5215
|
+
Fit.Array.Add(imageBlobUrls, blobUrl);
|
|
5216
|
+
}
|
|
5217
|
+
});
|
|
5218
|
+
|
|
5219
|
+
return imageBlobUrls;
|
|
5220
|
+
}
|
|
5221
|
+
|
|
5156
5222
|
/// <function container="Fit.String" name="Hash" access="public" static="true" returns="integer">
|
|
5157
5223
|
/// <description> Get Java compatible Hash Code from string </description>
|
|
5158
5224
|
/// <param name="str" type="string"> String to get hash code from </param>
|
|
@@ -6707,15 +6773,17 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6707
6773
|
|
|
6708
6774
|
// Private properties
|
|
6709
6775
|
|
|
6776
|
+
var me = this;
|
|
6710
6777
|
var elm = domElm;
|
|
6711
6778
|
var posState = null; // { position: "", left: "", top: "" };
|
|
6712
6779
|
var trgElm = (domTriggerElm ? domTriggerElm : null);
|
|
6713
|
-
var
|
|
6780
|
+
var bringToFrontOnActivation = false;
|
|
6714
6781
|
|
|
6715
6782
|
var onDragStart = null;
|
|
6716
6783
|
var onDragging = null;
|
|
6717
6784
|
var onDragStop = null;
|
|
6718
6785
|
|
|
6786
|
+
var activationEventId = -1;
|
|
6719
6787
|
var mouseDownEventId = -1;
|
|
6720
6788
|
|
|
6721
6789
|
// Construct
|
|
@@ -6727,15 +6795,33 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6727
6795
|
Fit.Dom.AddClass(elm, "FitDragDropDraggable");
|
|
6728
6796
|
Fit.Dom.AddClass((trgElm !== null ? trgElm : elm), "FitDragDropDraggableHandle");
|
|
6729
6797
|
|
|
6730
|
-
//
|
|
6798
|
+
// Bring to front on activation
|
|
6731
6799
|
|
|
6732
|
-
|
|
6800
|
+
activationEventId = Fit.Events.AddHandler(elm, (Fit.Browser.IsTouchEnabled() === true ? "touchstart" : "mousedown"), function(e)
|
|
6733
6801
|
{
|
|
6734
|
-
|
|
6802
|
+
if (bringToFrontOnActivation === true)
|
|
6803
|
+
{
|
|
6804
|
+
me.BringToFront();
|
|
6805
|
+
}
|
|
6806
|
+
});
|
|
6735
6807
|
|
|
6808
|
+
// Mouse down
|
|
6809
|
+
|
|
6810
|
+
mouseDownEventId = Fit.Events.AddHandler(((trgElm !== null) ? trgElm : elm), (Fit.Browser.IsTouchEnabled() === true ? "touchstart" : "mousedown"), function(e)
|
|
6811
|
+
{
|
|
6736
6812
|
if (Fit.DragDrop.Draggable._internal.active !== null)
|
|
6737
6813
|
return; // Skip - current element is a draggable parent to which event propagated
|
|
6738
6814
|
|
|
6815
|
+
var ev = Fit.Events.GetEvent(e);
|
|
6816
|
+
|
|
6817
|
+
if (onDragStart)
|
|
6818
|
+
{
|
|
6819
|
+
if (onDragStart(elm) === false)
|
|
6820
|
+
{
|
|
6821
|
+
return;
|
|
6822
|
+
}
|
|
6823
|
+
}
|
|
6824
|
+
|
|
6739
6825
|
Fit.Dom.AddClass(elm, "FitDragDropDragging");
|
|
6740
6826
|
|
|
6741
6827
|
// Initial positioning (used by Reset())
|
|
@@ -6758,12 +6844,9 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6758
6844
|
}
|
|
6759
6845
|
|
|
6760
6846
|
// Mouse position in viewport
|
|
6761
|
-
var
|
|
6762
|
-
var
|
|
6763
|
-
|
|
6764
|
-
// Make sure element being dragged is on top of every other draggable element
|
|
6765
|
-
Fit.DragDrop.Draggable._internal.zIndex++;
|
|
6766
|
-
elm.style.zIndex = Fit.DragDrop.Draggable._internal.zIndex;
|
|
6847
|
+
var pp = Fit.Events.GetPointerState().Coordinates.ViewPort;
|
|
6848
|
+
var mouseXviewport = pp.X;
|
|
6849
|
+
var mouseYviewport = pp.Y;
|
|
6767
6850
|
|
|
6768
6851
|
// Create state information object for draggable currently being dragged
|
|
6769
6852
|
var state =
|
|
@@ -6772,8 +6855,8 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6772
6855
|
Positioning: "relative",
|
|
6773
6856
|
Mouse: {Viewport: {X: -1, Y: -1}, Document: {X: -1, Y: -1}},
|
|
6774
6857
|
Position: {Viewport: {X: -1, Y: -1}, Document: {X: -1, Y: -1}, Offset: {X: -1, Y: -1}},
|
|
6775
|
-
Events: { OnDragStart: onDragStart, OnDragging: onDragging, OnDragStop: onDragStop }
|
|
6776
|
-
OnSelectStart : document.onselectstart
|
|
6858
|
+
Events: { OnDragStart: onDragStart, OnDragging: onDragging, OnDragStop: onDragStop }/*,
|
|
6859
|
+
OnSelectStart : document.onselectstart*/
|
|
6777
6860
|
};
|
|
6778
6861
|
|
|
6779
6862
|
var positioning = Fit.Dom.GetComputedStyle(elm, "position");
|
|
@@ -6782,8 +6865,9 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6782
6865
|
state.Positioning = positioning;
|
|
6783
6866
|
}
|
|
6784
6867
|
|
|
6785
|
-
// Disable text selection for legacy browsers
|
|
6786
|
-
|
|
6868
|
+
// Disable text selection for legacy browsers.
|
|
6869
|
+
// DISABLED: Now handled using Fit.Events.PreventDefault(ev).
|
|
6870
|
+
//document.onselectstart = function() { return false; }
|
|
6787
6871
|
|
|
6788
6872
|
// Find mouse position in viewport
|
|
6789
6873
|
state.Mouse.Viewport.X = mouseXviewport;
|
|
@@ -6833,12 +6917,10 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6833
6917
|
Fit.Array.Add(Fit.DragDrop.DropZone._internal.dropzones, draggableDropZone);
|
|
6834
6918
|
}
|
|
6835
6919
|
|
|
6836
|
-
if (
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
ev.preventDefault();
|
|
6841
|
-
ev.cancelBubble = true;*/
|
|
6920
|
+
if (ev.type === "touchstart")
|
|
6921
|
+
{
|
|
6922
|
+
Fit.Events.PreventDefault(ev); // Stop page scrolling on iOS (required in both ontouchstart and ontouchmove handlers)
|
|
6923
|
+
}
|
|
6842
6924
|
});
|
|
6843
6925
|
|
|
6844
6926
|
// Mouse Up
|
|
@@ -6847,13 +6929,11 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6847
6929
|
{
|
|
6848
6930
|
Fit.DragDrop.Draggable._internal.mouseUpRegistered = true;
|
|
6849
6931
|
|
|
6850
|
-
Fit.Events.AddHandler(document, "mouseup", function(e)
|
|
6932
|
+
Fit.Events.AddHandler(document, (Fit.Browser.IsTouchEnabled() === true ? "touchend" : "mouseup"), function(e)
|
|
6851
6933
|
{
|
|
6852
6934
|
if (Fit.DragDrop.Draggable._internal.active === null)
|
|
6853
6935
|
return;
|
|
6854
6936
|
|
|
6855
|
-
var ev = e || window.event;
|
|
6856
|
-
|
|
6857
6937
|
var draggableState = Fit.DragDrop.Draggable._internal.active;
|
|
6858
6938
|
var draggable = Fit.DragDrop.Draggable._internal.active.Draggable;
|
|
6859
6939
|
|
|
@@ -6886,7 +6966,7 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6886
6966
|
draggableState.Events.OnDragStop(draggable);
|
|
6887
6967
|
|
|
6888
6968
|
// Restore OnSelectStart event
|
|
6889
|
-
document.onselectstart = draggableState.OnSelectStart;
|
|
6969
|
+
//document.onselectstart = draggableState.OnSelectStart;
|
|
6890
6970
|
});
|
|
6891
6971
|
}
|
|
6892
6972
|
|
|
@@ -6896,12 +6976,12 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6896
6976
|
{
|
|
6897
6977
|
Fit.DragDrop.Draggable._internal.mouseMoveRegistered = true;
|
|
6898
6978
|
|
|
6899
|
-
Fit.Events.AddHandler(document, "mousemove", function(e)
|
|
6979
|
+
Fit.Events.AddHandler(document, (Fit.Browser.IsTouchEnabled() === true ? "touchmove" : "mousemove"), { passive: false /* https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener */ }, function(e)
|
|
6900
6980
|
{
|
|
6901
6981
|
if (Fit.DragDrop.Draggable._internal.active === null)
|
|
6902
6982
|
return;
|
|
6903
6983
|
|
|
6904
|
-
var ev = e
|
|
6984
|
+
var ev = Fit.Events.GetEvent(e);
|
|
6905
6985
|
|
|
6906
6986
|
// Handle draggable
|
|
6907
6987
|
|
|
@@ -6910,8 +6990,16 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
6910
6990
|
var elm = draggable.GetElement();
|
|
6911
6991
|
|
|
6912
6992
|
// Mouse position in viewport
|
|
6913
|
-
var
|
|
6914
|
-
var
|
|
6993
|
+
var pp = Fit.Events.GetPointerState().Coordinates.ViewPort;
|
|
6994
|
+
var mouseXviewport = pp.X;
|
|
6995
|
+
var mouseYviewport = pp.Y;
|
|
6996
|
+
|
|
6997
|
+
// Prevent user from moving object out of viewport
|
|
6998
|
+
var vpDim = Fit.Browser.GetViewPortDimensions();
|
|
6999
|
+
mouseXviewport = mouseXviewport >= 0 ? mouseXviewport : 0;
|
|
7000
|
+
mouseXviewport = mouseXviewport <= vpDim.Width ? mouseXviewport : vpDim.Width;
|
|
7001
|
+
mouseYviewport = mouseYviewport >= 0 ? mouseYviewport : 0;
|
|
7002
|
+
mouseYviewport = mouseYviewport <= vpDim.Height ? mouseYviewport : vpDim.Height;
|
|
6915
7003
|
|
|
6916
7004
|
// Positioning (fixed, absolute, or relative)
|
|
6917
7005
|
var positioning = Fit.DragDrop.Draggable._internal.active.Positioning;
|
|
@@ -7011,12 +7099,55 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
7011
7099
|
if (dropzoneActive.OnEnter)
|
|
7012
7100
|
dropzoneActive.OnEnter(dropzoneActive.DropZone);
|
|
7013
7101
|
}
|
|
7102
|
+
|
|
7103
|
+
// Stop page scrolling on iOS (required in both ontouchstart and ontouchmove handlers).
|
|
7104
|
+
// Ontouchmove must be registered with { passive: false } for this to work in browsers
|
|
7105
|
+
// which defaults to passive:true. This also prevents text selection on older browsers
|
|
7106
|
+
// not supporting user-select:none.
|
|
7107
|
+
|
|
7108
|
+
Fit.Events.PreventDefault(ev);
|
|
7014
7109
|
});
|
|
7015
7110
|
}
|
|
7016
7111
|
}
|
|
7017
7112
|
|
|
7018
7113
|
// Public
|
|
7019
7114
|
|
|
7115
|
+
/// <function container="Fit.DragDrop.Draggable" name="BringToFrontOnActivation" access="public" returns="boolean">
|
|
7116
|
+
/// <description> Get/set flag indicating whether to bring draggable to front when activated </description>
|
|
7117
|
+
/// <param name="val" type="boolean" default="undefined"> If defined, a value of True enables functionality, False disables it (default) </param>
|
|
7118
|
+
/// </function>
|
|
7119
|
+
this.BringToFrontOnActivation = function(val)
|
|
7120
|
+
{
|
|
7121
|
+
Fit.Validation.ExpectBoolean(val, true);
|
|
7122
|
+
|
|
7123
|
+
if (Fit.Validation.IsSet(val) === true)
|
|
7124
|
+
{
|
|
7125
|
+
bringToFrontOnActivation = val;
|
|
7126
|
+
|
|
7127
|
+
// NOTICE: z-index is not reset when BringToFrontOnActivation is disabled.
|
|
7128
|
+
// It may have been enabled at some point, but we keep the z-index to make
|
|
7129
|
+
// sure the element remains below other elements that have BringToFrontOnActivation
|
|
7130
|
+
// enabled. Resetting the z-index style attribute will cause the z-index value of
|
|
7131
|
+
// 99999 from CSS to be applied when dragging the element, causing it to temporarily
|
|
7132
|
+
// be positioned above elements with BringToFrontOnActivation enabled while dragging it.
|
|
7133
|
+
// That becomes bad UX when the user stops dragging it and releases it, at which point
|
|
7134
|
+
// the temporary z-index value of 99999 from CSS is no longer in effect and z-index:1200
|
|
7135
|
+
// takes effect again, which causes the element to be hidden behind elements with
|
|
7136
|
+
// BringToFrontOnActivation enabled.
|
|
7137
|
+
}
|
|
7138
|
+
|
|
7139
|
+
return bringToFrontOnActivation;
|
|
7140
|
+
}
|
|
7141
|
+
|
|
7142
|
+
/// <function container="Fit.DragDrop.Draggable" name="BringToFront" access="public">
|
|
7143
|
+
/// <description> Bring draggable to front </description>
|
|
7144
|
+
/// </function>
|
|
7145
|
+
this.BringToFront = function()
|
|
7146
|
+
{
|
|
7147
|
+
Fit.DragDrop.Draggable._internal.zIndex++;
|
|
7148
|
+
elm.style.zIndex = Fit.DragDrop.Draggable._internal.zIndex;
|
|
7149
|
+
}
|
|
7150
|
+
|
|
7020
7151
|
/// <function container="Fit.DragDrop.Draggable" name="Reset" access="public">
|
|
7021
7152
|
/// <description> Reset draggable to initial position </description>
|
|
7022
7153
|
/// </function>
|
|
@@ -7028,6 +7159,7 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
7028
7159
|
elm.style.position = posState.position;
|
|
7029
7160
|
elm.style.left = posState.left;
|
|
7030
7161
|
elm.style.top = posState.top;
|
|
7162
|
+
elm.style.zIndex = "";
|
|
7031
7163
|
|
|
7032
7164
|
posState = null;
|
|
7033
7165
|
}
|
|
@@ -7057,9 +7189,15 @@ Fit.DragDrop.Draggable = function(domElm, domTriggerElm)
|
|
|
7057
7189
|
Fit.Dom.RemoveClass(elm, "FitDragDropDraggable");
|
|
7058
7190
|
Fit.Dom.RemoveClass((trgElm !== null ? trgElm : elm), "FitDragDropDraggableHandle");
|
|
7059
7191
|
|
|
7192
|
+
Fit.Events.RemoveHandler(elm, activationEventId);
|
|
7060
7193
|
Fit.Events.RemoveHandler(((trgElm !== null) ? trgElm : elm), mouseDownEventId);
|
|
7061
7194
|
|
|
7062
|
-
|
|
7195
|
+
if (Fit.DragDrop.Draggable._internal.active !== null && Fit.DragDrop.Draggable._internal.active.Draggable === me)
|
|
7196
|
+
{
|
|
7197
|
+
Fit.DragDrop.Draggable._internal.active = null;
|
|
7198
|
+
}
|
|
7199
|
+
|
|
7200
|
+
me = elm = posState = trgElm = bringToFrontOnActivation = onDragStart = onDragging = onDragStop = activationEventId = mouseDownEventId = null;
|
|
7063
7201
|
}
|
|
7064
7202
|
|
|
7065
7203
|
// Event handling
|
|
@@ -14574,16 +14712,21 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14574
14712
|
var dialog = me.GetDomElement();
|
|
14575
14713
|
var focusTrapStart = null;
|
|
14576
14714
|
var focusTrapEnd = null;
|
|
14577
|
-
var
|
|
14715
|
+
var titleContainer = null;
|
|
14716
|
+
var titleText = null;
|
|
14578
14717
|
var titleButtons = null;
|
|
14579
14718
|
var cmdMaximize = null;
|
|
14580
14719
|
var cmdDismiss = null;
|
|
14581
14720
|
var content = null;
|
|
14582
14721
|
var iframe = null;
|
|
14722
|
+
var resizer = null;
|
|
14583
14723
|
var buttons = null;
|
|
14584
14724
|
var modal = false;
|
|
14585
14725
|
var layer = null;
|
|
14586
14726
|
|
|
14727
|
+
var draggable = null;
|
|
14728
|
+
var suppressPositioning = false;
|
|
14729
|
+
|
|
14587
14730
|
var width = null;
|
|
14588
14731
|
var minWidth = null;
|
|
14589
14732
|
var maxWidth = null;
|
|
@@ -14608,6 +14751,7 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14608
14751
|
Fit.Dom.AddClass(dialog, "FitUiControlDialog");
|
|
14609
14752
|
Fit.Dom.Data(dialog, "framed", "false");
|
|
14610
14753
|
Fit.Dom.Data(dialog, "maximized", "false");
|
|
14754
|
+
Fit.Dom.Data(dialog, "resizable", "false");
|
|
14611
14755
|
|
|
14612
14756
|
focusTrapStart = document.createElement("div");
|
|
14613
14757
|
focusTrapStart.tabIndex = 0;
|
|
@@ -14682,44 +14826,43 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14682
14826
|
|
|
14683
14827
|
if (val !== undefined) // Allow null to remove title
|
|
14684
14828
|
{
|
|
14685
|
-
if (val === null &&
|
|
14829
|
+
if (val === null && titleContainer !== null) // Remove title
|
|
14686
14830
|
{
|
|
14687
|
-
if (titleButtons !== null)
|
|
14831
|
+
if (titleButtons !== null || draggable !== null) // Clear title but keep title bar used for buttons and drag support
|
|
14688
14832
|
{
|
|
14689
|
-
Fit.Dom.Text(
|
|
14690
|
-
Fit.Dom.Add(title, titleButtons);
|
|
14833
|
+
Fit.Dom.Text(titleText, "");
|
|
14691
14834
|
}
|
|
14692
|
-
else
|
|
14835
|
+
else // Remove title bar
|
|
14693
14836
|
{
|
|
14694
|
-
Fit.Dom.Remove(
|
|
14695
|
-
|
|
14837
|
+
Fit.Dom.Remove(titleContainer);
|
|
14838
|
+
titleContainer = null;
|
|
14839
|
+
titleText = null;
|
|
14696
14840
|
|
|
14697
14841
|
setContentHeight();
|
|
14698
14842
|
updatePosition();
|
|
14699
14843
|
}
|
|
14700
14844
|
}
|
|
14701
|
-
else
|
|
14845
|
+
else // Set title
|
|
14702
14846
|
{
|
|
14703
|
-
if (
|
|
14847
|
+
if (titleContainer === null)
|
|
14704
14848
|
{
|
|
14705
|
-
|
|
14706
|
-
Fit.Dom.AddClass(
|
|
14707
|
-
Fit.Dom.InsertAfter(focusTrapStart,
|
|
14708
|
-
}
|
|
14709
|
-
|
|
14710
|
-
Fit.Dom.Text(title, val);
|
|
14849
|
+
titleContainer = document.createElement("div");
|
|
14850
|
+
Fit.Dom.AddClass(titleContainer, "FitUiControlDialogTitle");
|
|
14851
|
+
Fit.Dom.InsertAfter(focusTrapStart, titleContainer);
|
|
14711
14852
|
|
|
14712
|
-
|
|
14713
|
-
|
|
14714
|
-
Fit.Dom.Add(
|
|
14853
|
+
titleText = document.createElement("div");
|
|
14854
|
+
Fit.Dom.AddClass(titleText, "FitUiControlDialogTitleText");
|
|
14855
|
+
Fit.Dom.Add(titleContainer, titleText);
|
|
14715
14856
|
}
|
|
14716
14857
|
|
|
14858
|
+
Fit.Dom.Text(titleText, val);
|
|
14859
|
+
|
|
14717
14860
|
setContentHeight();
|
|
14718
14861
|
updatePosition();
|
|
14719
14862
|
}
|
|
14720
14863
|
}
|
|
14721
14864
|
|
|
14722
|
-
return (
|
|
14865
|
+
return (titleText !== null ? Fit.Dom.Text(titleText) : null);
|
|
14723
14866
|
}
|
|
14724
14867
|
|
|
14725
14868
|
/// <function container="Fit.Controls.Dialog" name="Width" access="public" returns="Fit.TypeDefs.CssValue">
|
|
@@ -14741,12 +14884,17 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14741
14884
|
width = { Value: val, Unit: ((Fit.Validation.IsSet(unit) === true) ? unit : "px") };
|
|
14742
14885
|
dialog.style.width = width.Value + width.Unit;
|
|
14743
14886
|
|
|
14744
|
-
|
|
14887
|
+
// Disable default min-width and default max-width from CSS when width alone is set, unless Resizable is
|
|
14888
|
+
// enabled, in which case we must prevent dialog from "collapsing" completely due to resizing, or become
|
|
14889
|
+
// larger than the viewport. When resizing is enabled, appropriate values for min-width and max-width are
|
|
14890
|
+
// set from CSS, but can be overridden using MinimumWidth(..) and MaximumWidth(..)
|
|
14891
|
+
|
|
14892
|
+
if (minWidth === null && me.Resizable() === false)
|
|
14745
14893
|
{
|
|
14746
14894
|
dialog.style.minWidth = "0";
|
|
14747
14895
|
}
|
|
14748
14896
|
|
|
14749
|
-
if (maxWidth === null)
|
|
14897
|
+
if (maxWidth === null && me.Resizable() === false)
|
|
14750
14898
|
{
|
|
14751
14899
|
dialog.style.maxWidth = "none";
|
|
14752
14900
|
}
|
|
@@ -14785,6 +14933,7 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14785
14933
|
|
|
14786
14934
|
// defaultValue must match min-width in Dialog.css
|
|
14787
14935
|
var defaultValue = { Value: 280, Unit: "px" };
|
|
14936
|
+
var defaultValueResizable = { Value: 15, Unit: "em" };
|
|
14788
14937
|
|
|
14789
14938
|
if (Fit.Validation.IsSet(val) === true)
|
|
14790
14939
|
{
|
|
@@ -14796,12 +14945,17 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14796
14945
|
else
|
|
14797
14946
|
{
|
|
14798
14947
|
minWidth = null;
|
|
14799
|
-
dialog.style.minWidth = (width !== null ? "0" : ""); // Apply "0" (no min-width) if width is set
|
|
14948
|
+
dialog.style.minWidth = (width !== null && me.Resizable() === false ? "0" : ""); // Apply "0" (no min-width) if width is set, to override min-width from CSS - similar logic found in Width(..)
|
|
14800
14949
|
}
|
|
14801
14950
|
|
|
14802
14951
|
updatePosition();
|
|
14803
14952
|
}
|
|
14804
14953
|
|
|
14954
|
+
if (minWidth === null && me.Resizable() === true)
|
|
14955
|
+
{
|
|
14956
|
+
return defaultValueResizable;
|
|
14957
|
+
}
|
|
14958
|
+
|
|
14805
14959
|
return (minWidth !== null ? minWidth : (width !== null ? width : defaultValue));
|
|
14806
14960
|
}
|
|
14807
14961
|
|
|
@@ -14817,6 +14971,7 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14817
14971
|
|
|
14818
14972
|
// defaultValue must match max-width in Dialog.css
|
|
14819
14973
|
var defaultValue = { Value: 800, Unit: "px" };
|
|
14974
|
+
var defaultValueResizable = { Value: 100, Unit: "%" };
|
|
14820
14975
|
|
|
14821
14976
|
if (Fit.Validation.IsSet(val) === true)
|
|
14822
14977
|
{
|
|
@@ -14828,12 +14983,17 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14828
14983
|
else
|
|
14829
14984
|
{
|
|
14830
14985
|
maxWidth = null;
|
|
14831
|
-
dialog.style.maxWidth = (width !== null ? "none" : ""); // Apply "none" (no max-width) if width is set
|
|
14986
|
+
dialog.style.maxWidth = (width !== null && me.Resizable() === false ? "none" : ""); // Apply "none" (no max-width) if width is set, to override max-width from CSS - similar logic found in Width(..)
|
|
14832
14987
|
}
|
|
14833
14988
|
|
|
14834
14989
|
updatePosition();
|
|
14835
14990
|
}
|
|
14836
14991
|
|
|
14992
|
+
if (maxWidth === null && me.Resizable() === true)
|
|
14993
|
+
{
|
|
14994
|
+
return defaultValueResizable;
|
|
14995
|
+
}
|
|
14996
|
+
|
|
14837
14997
|
return (maxWidth !== null ? maxWidth : (width !== null ? width : defaultValue));
|
|
14838
14998
|
}
|
|
14839
14999
|
|
|
@@ -14882,6 +15042,7 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14882
15042
|
|
|
14883
15043
|
// defaultValue must match min-height in Dialog.css (which is not defined)
|
|
14884
15044
|
var defaultValue = { Value: -1, Unit: "px" };
|
|
15045
|
+
var defaultValueResizable = { Value: 10, Unit: "em" };
|
|
14885
15046
|
|
|
14886
15047
|
if (Fit.Validation.IsSet(val) === true)
|
|
14887
15048
|
{
|
|
@@ -14900,6 +15061,11 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14900
15061
|
updatePosition();
|
|
14901
15062
|
}
|
|
14902
15063
|
|
|
15064
|
+
if (minHeight === null && me.Resizable() === true)
|
|
15065
|
+
{
|
|
15066
|
+
return defaultValueResizable;
|
|
15067
|
+
}
|
|
15068
|
+
|
|
14903
15069
|
return (minHeight !== null ? minHeight : defaultValue);
|
|
14904
15070
|
}
|
|
14905
15071
|
|
|
@@ -14915,6 +15081,7 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14915
15081
|
|
|
14916
15082
|
// defaultValue must match max-height in Dialog.css (which is not defined)
|
|
14917
15083
|
var defaultValue = { Value: -1, Unit: "px" };
|
|
15084
|
+
var defaultValueResizable = { Value: 100, Unit: "%" };
|
|
14918
15085
|
|
|
14919
15086
|
if (Fit.Validation.IsSet(val) === true)
|
|
14920
15087
|
{
|
|
@@ -14933,6 +15100,11 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14933
15100
|
updatePosition();
|
|
14934
15101
|
}
|
|
14935
15102
|
|
|
15103
|
+
if (maxHeight === null && me.Resizable() === true)
|
|
15104
|
+
{
|
|
15105
|
+
return defaultValueResizable;
|
|
15106
|
+
}
|
|
15107
|
+
|
|
14936
15108
|
return (maxHeight !== null ? maxHeight : defaultValue);
|
|
14937
15109
|
}
|
|
14938
15110
|
|
|
@@ -14949,9 +15121,19 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
14949
15121
|
if (val !== modal && me.IsOpen() === true)
|
|
14950
15122
|
{
|
|
14951
15123
|
if (val === true)
|
|
15124
|
+
{
|
|
15125
|
+
layer.style.zIndex = dialog.style.zIndex; // Update in case dialog was/is draggable and it was brought to front (z-index set by Fit.DragDrop.Draggable when Draggable is enabled)
|
|
14952
15126
|
Fit.Dom.InsertBefore(dialog, layer);
|
|
15127
|
+
|
|
15128
|
+
if (me.IsOpen() === true)
|
|
15129
|
+
{
|
|
15130
|
+
me.BringToFront();
|
|
15131
|
+
}
|
|
15132
|
+
}
|
|
14953
15133
|
else
|
|
15134
|
+
{
|
|
14954
15135
|
Fit.Dom.Remove(layer);
|
|
15136
|
+
}
|
|
14955
15137
|
}
|
|
14956
15138
|
|
|
14957
15139
|
modal = val;
|
|
@@ -15165,6 +15347,84 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15165
15347
|
return (cmdDismiss !== null);
|
|
15166
15348
|
}
|
|
15167
15349
|
|
|
15350
|
+
/// <function container="Fit.Controls.Dialog" name="Draggable" access="public" returns="boolean">
|
|
15351
|
+
/// <description> Get/set flag indicating whether dialog can be moved around on screen </description>
|
|
15352
|
+
/// <param name="val" type="boolean" default="undefined"> If defined, a value of True enables dragging, False disables it (default) </param>
|
|
15353
|
+
/// </function>
|
|
15354
|
+
this.Draggable = function(val)
|
|
15355
|
+
{
|
|
15356
|
+
Fit.Validation.ExpectBoolean(val, true);
|
|
15357
|
+
|
|
15358
|
+
if (Fit.Validation.IsSet(val) === true)
|
|
15359
|
+
{
|
|
15360
|
+
if (val === true && draggable === null)
|
|
15361
|
+
{
|
|
15362
|
+
if (me.Title() === null) // Ensure title element
|
|
15363
|
+
{
|
|
15364
|
+
me.Title("");
|
|
15365
|
+
}
|
|
15366
|
+
|
|
15367
|
+
draggable = new Fit.DragDrop.Draggable(me.GetDomElement(), titleText);
|
|
15368
|
+
draggable.BringToFrontOnActivation(true);
|
|
15369
|
+
draggable.OnDragStart(function()
|
|
15370
|
+
{
|
|
15371
|
+
if (me.Maximized() === true)
|
|
15372
|
+
{
|
|
15373
|
+
return false; // Prevent dragging while maximized
|
|
15374
|
+
}
|
|
15375
|
+
|
|
15376
|
+
suppressPositioning = true;
|
|
15377
|
+
});
|
|
15378
|
+
}
|
|
15379
|
+
else if (val === false && draggable !== null)
|
|
15380
|
+
{
|
|
15381
|
+
draggable.Dispose();
|
|
15382
|
+
draggable = null;
|
|
15383
|
+
suppressPositioning = false;
|
|
15384
|
+
|
|
15385
|
+
if (me.Title() === "")
|
|
15386
|
+
{
|
|
15387
|
+
me.Title(null); // Remove title element - will remain enabled if buttons (dismiss/maximize) are present though
|
|
15388
|
+
}
|
|
15389
|
+
|
|
15390
|
+
updatePosition();
|
|
15391
|
+
}
|
|
15392
|
+
}
|
|
15393
|
+
|
|
15394
|
+
return (draggable !== null);
|
|
15395
|
+
}
|
|
15396
|
+
|
|
15397
|
+
/// <function container="Fit.Controls.Dialog" name="Resizable" access="public" returns="boolean">
|
|
15398
|
+
/// <description> Get/set flag indicating whether dialog can be resized by the user </description>
|
|
15399
|
+
/// <param name="val" type="boolean" default="undefined"> If defined, a value of True enables resizing, False disables it (default) </param>
|
|
15400
|
+
/// </function>
|
|
15401
|
+
this.Resizable = function(val)
|
|
15402
|
+
{
|
|
15403
|
+
Fit.Validation.ExpectBoolean(val, true);
|
|
15404
|
+
|
|
15405
|
+
if (Fit.Validation.IsSet(val) === true)
|
|
15406
|
+
{
|
|
15407
|
+
if (val === true && resizer === null)
|
|
15408
|
+
{
|
|
15409
|
+
resizer = createResizerElement();
|
|
15410
|
+
Fit.Dom.InsertAfter(content, resizer);
|
|
15411
|
+
Fit.Dom.Data(dialog, "resizable", "true");
|
|
15412
|
+
}
|
|
15413
|
+
else if (val === false && resizer !== null)
|
|
15414
|
+
{
|
|
15415
|
+
Fit.Dom.Remove(resizer);
|
|
15416
|
+
resizer = null;
|
|
15417
|
+
Fit.Dom.Data(dialog, "resizable", "false");
|
|
15418
|
+
|
|
15419
|
+
// Undo width/height set by user
|
|
15420
|
+
me.Width(me.Width().Value, me.Width().Unit);
|
|
15421
|
+
me.Height(me.Height().Value, me.Height().Unit);
|
|
15422
|
+
}
|
|
15423
|
+
}
|
|
15424
|
+
|
|
15425
|
+
return (resizer !== null);
|
|
15426
|
+
}
|
|
15427
|
+
|
|
15168
15428
|
/// <function container="Fit.Controls.Dialog" name="AddButton" access="public">
|
|
15169
15429
|
/// <description> Add button to dialog </description>
|
|
15170
15430
|
/// <param name="btn" type="Fit.Controls.Button"> Instance of Fit.Controls.Button </param>
|
|
@@ -15264,6 +15524,18 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15264
15524
|
return Fit.Dom.IsRooted(dialog);
|
|
15265
15525
|
}
|
|
15266
15526
|
|
|
15527
|
+
/// <function container="Fit.Controls.Dialog" name="BringToFront" access="public">
|
|
15528
|
+
/// <description> Bring draggable dialog to front </description>
|
|
15529
|
+
/// </function>
|
|
15530
|
+
this.BringToFront = function()
|
|
15531
|
+
{
|
|
15532
|
+
if (draggable !== null)
|
|
15533
|
+
{
|
|
15534
|
+
draggable.BringToFront();
|
|
15535
|
+
layer.style.zIndex = dialog.style.zIndex; // Ensure modal layer always remains exactly behind dialog with the same z-index value
|
|
15536
|
+
}
|
|
15537
|
+
}
|
|
15538
|
+
|
|
15267
15539
|
/// <function container="Fit.Controls.Dialog" name="Open" access="public">
|
|
15268
15540
|
/// <description> Open dialog </description>
|
|
15269
15541
|
/// <param name="renderTarget" type="DOMElement" default="undefined">
|
|
@@ -15279,8 +15551,13 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15279
15551
|
if (me.IsOpen() === true)
|
|
15280
15552
|
return;
|
|
15281
15553
|
|
|
15554
|
+
me.BringToFront();
|
|
15555
|
+
|
|
15282
15556
|
if (modal === true)
|
|
15557
|
+
{
|
|
15558
|
+
layer.style.zIndex = dialog.style.zIndex; // Ensure modal layer always remains exactly behind dialog with the same z-index value
|
|
15283
15559
|
Fit.Dom.Add(renderTarget || document.body, layer);
|
|
15560
|
+
}
|
|
15284
15561
|
|
|
15285
15562
|
Fit.Dom.Add(renderTarget || document.body, dialog);
|
|
15286
15563
|
|
|
@@ -15388,6 +15665,11 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15388
15665
|
cmdDismiss.Dispose();
|
|
15389
15666
|
}
|
|
15390
15667
|
|
|
15668
|
+
if (draggable !== null)
|
|
15669
|
+
{
|
|
15670
|
+
draggable.Dispose();
|
|
15671
|
+
}
|
|
15672
|
+
|
|
15391
15673
|
if (buttons !== null)
|
|
15392
15674
|
{
|
|
15393
15675
|
Fit.Array.ForEach(Fit.Array.Copy(buttons.children), function(buttonElm) // Using Copy(..) since Dispose() modifies children collection
|
|
@@ -15406,7 +15688,7 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15406
15688
|
Fit.Events.RemoveHandler(window, resizeHandlerId);
|
|
15407
15689
|
}
|
|
15408
15690
|
|
|
15409
|
-
me = dialog =
|
|
15691
|
+
me = dialog = focusTrapStart = focusTrapEnd = titleContainer = titleText = titleButtons = cmdMaximize = cmdDismiss = content = iframe = resizer = buttons = modal = layer = draggable = suppressPositioning = width = minWidth = maxWidth = height = minHeight = maxHeight = mutationObserverId = resizeHandlerId = onDismissHandlers = onCloseHandlers = isClosing = null;
|
|
15410
15692
|
|
|
15411
15693
|
base();
|
|
15412
15694
|
});
|
|
@@ -15454,6 +15736,17 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15454
15736
|
Fit.Array.Add(onCloseHandlers, cb);
|
|
15455
15737
|
}
|
|
15456
15738
|
|
|
15739
|
+
// ============================================
|
|
15740
|
+
// Protected
|
|
15741
|
+
// ============================================
|
|
15742
|
+
|
|
15743
|
+
this._internal = (this._internal ? this._internal : {});
|
|
15744
|
+
|
|
15745
|
+
this._internal.GetLayerElement = function()
|
|
15746
|
+
{
|
|
15747
|
+
return layer;
|
|
15748
|
+
}
|
|
15749
|
+
|
|
15457
15750
|
// ============================================
|
|
15458
15751
|
// Private
|
|
15459
15752
|
// ============================================
|
|
@@ -15465,6 +15758,130 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15465
15758
|
return div;
|
|
15466
15759
|
}
|
|
15467
15760
|
|
|
15761
|
+
function createResizerElement()
|
|
15762
|
+
{
|
|
15763
|
+
// NOTICE: Resizing a dialog with an iframe:
|
|
15764
|
+
// Resizing might not work properly with iframes with content from a foreign domain,
|
|
15765
|
+
// since browsers won't dispatch mouse/touch events over foreign domains.
|
|
15766
|
+
// Some older browsers won't even dispatch the events over iframes with content
|
|
15767
|
+
// originating from the same domain as the one hosting the main page.
|
|
15768
|
+
// This becomes a problem if the user is able to quickly move the mouse over the
|
|
15769
|
+
// iframe while resizing, and the computer/browser is not fast enough to "catch up" with
|
|
15770
|
+
// the movement of the resize handle. Slowly resizing the dialog in this case works.
|
|
15771
|
+
// Possible solution:
|
|
15772
|
+
// If we need better support for resizing dialogs with iframes, consider using a timer
|
|
15773
|
+
// which on a regular basis (2-10 times per second) updates the dialog size based on the
|
|
15774
|
+
// pointer position. That way the missing invocation of OnTouchMove or OnMouseMove is mitigated.
|
|
15775
|
+
// It should also dispatch the logic found in OnTouchEnd, OnTouchCancel and OnMouseUp if the
|
|
15776
|
+
// timer detects that the pointer (mouse or finger) has been released. This can be determined
|
|
15777
|
+
// using: Fit.Events.GetPointerState().Buttons.Touch || Fit.Events.GetPointerState().Buttons.Primary
|
|
15778
|
+
// However, make sure this issue is resolved first: https://github.com/Jemt/Fit.UI/issues/153
|
|
15779
|
+
// The issue relates to the reliablity of Fit.Events.GetPointerState().Buttons.Primary since it
|
|
15780
|
+
// is unset OnMouseOut, which will be triggered if mouse/finger leaves resize handle.
|
|
15781
|
+
|
|
15782
|
+
var resizer = document.createElement("div");
|
|
15783
|
+
Fit.Dom.AddClass(resizer, "FitUiControlDialogResizer");
|
|
15784
|
+
|
|
15785
|
+
Fit.Events.AddHandler(resizer, (Fit.Browser.IsTouchEnabled() === true ? "touchstart" : "mousedown"), function(e)
|
|
15786
|
+
{
|
|
15787
|
+
if (me.Maximized() === true)
|
|
15788
|
+
{
|
|
15789
|
+
return; // Prevent resizing while maximized
|
|
15790
|
+
}
|
|
15791
|
+
|
|
15792
|
+
var ev = Fit.Events.GetEvent(e);
|
|
15793
|
+
|
|
15794
|
+
var initPos = Fit.Events.GetPointerState().Coordinates.ViewPort;
|
|
15795
|
+
var initDim = { Width: me.GetDomElement().offsetWidth, Height: me.GetDomElement().offsetHeight };
|
|
15796
|
+
|
|
15797
|
+
var moveHandler = null; // OnMouseMove or OnTouchMove event ID
|
|
15798
|
+
var releaseHandler = null; // OnMouseUp or OnTouchEnd event ID
|
|
15799
|
+
var cancelHandler = null; // OnTouchCancel event ID (only set on touch devices)
|
|
15800
|
+
|
|
15801
|
+
var cleanup = function()
|
|
15802
|
+
{
|
|
15803
|
+
Fit.Events.RemoveHandler(document, moveHandler);
|
|
15804
|
+
Fit.Events.RemoveHandler(document, releaseHandler);
|
|
15805
|
+
|
|
15806
|
+
if (cancelHandler !== null)
|
|
15807
|
+
{
|
|
15808
|
+
Fit.Events.RemoveHandler(document, cancelHandler);
|
|
15809
|
+
}
|
|
15810
|
+
};
|
|
15811
|
+
|
|
15812
|
+
moveHandler = Fit.Events.AddHandler(document, (Fit.Browser.IsTouchEnabled() === true ? "touchmove" : "mousemove"), { passive: false /* https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener */ }, function(e)
|
|
15813
|
+
{
|
|
15814
|
+
if (me === null) // Unlikely, but theoretically possible that dialog gets disposed while being resized
|
|
15815
|
+
{
|
|
15816
|
+
cleanup();
|
|
15817
|
+
return;
|
|
15818
|
+
}
|
|
15819
|
+
|
|
15820
|
+
var ev = Fit.Events.GetEvent(e);
|
|
15821
|
+
|
|
15822
|
+
// Determine mouse/finger travel
|
|
15823
|
+
|
|
15824
|
+
var pp = Fit.Events.GetPointerState().Coordinates.ViewPort;
|
|
15825
|
+
var left = pp.X - initPos.X; // Positive = moved right, negative = moved left
|
|
15826
|
+
var top = pp.Y - initPos.Y; // Positive = moved down, negative = moved up
|
|
15827
|
+
|
|
15828
|
+
if (suppressPositioning === false) // Dialog remains centered - adjust amount of resizing needed ("double up")
|
|
15829
|
+
{
|
|
15830
|
+
left = left * 2; // Double up when dialog is centered since both left and right side is resized
|
|
15831
|
+
top = top * 1.3; // Approximate value to adjust resizing vertically - not 100% accurate - resize handle will not follow pointer precisely, but close enough - reason: dialog is not centered 50/50 vertically but 25/75, so a static value such as 1.3 is not accurate - the actual adjustment needed for accurate positioning is variable
|
|
15832
|
+
}
|
|
15833
|
+
|
|
15834
|
+
// Calculate and apply new width and height
|
|
15835
|
+
|
|
15836
|
+
var newWidth = initDim.Width + left;
|
|
15837
|
+
var newHeight = initDim.Height + top;
|
|
15838
|
+
|
|
15839
|
+
if (newWidth > 0)
|
|
15840
|
+
{
|
|
15841
|
+
dialog.style.width = newWidth + "px";
|
|
15842
|
+
}
|
|
15843
|
+
|
|
15844
|
+
if (newHeight > 0)
|
|
15845
|
+
{
|
|
15846
|
+
dialog.style.height = newHeight + "px";
|
|
15847
|
+
setContentHeight();
|
|
15848
|
+
}
|
|
15849
|
+
|
|
15850
|
+
if (newWidth > 0 || newHeight > 0)
|
|
15851
|
+
{
|
|
15852
|
+
updatePosition();
|
|
15853
|
+
}
|
|
15854
|
+
|
|
15855
|
+
// Stop page scrolling on iOS (required in both ontouchstart and ontouchmove handlers).
|
|
15856
|
+
// Ontouchmove must be registered with { passive: false } for this to work in browsers
|
|
15857
|
+
// which defaults to passive:true. This also prevents text selection on older browsers
|
|
15858
|
+
// not supporting user-select:none.
|
|
15859
|
+
|
|
15860
|
+
Fit.Events.PreventDefault(ev);
|
|
15861
|
+
});
|
|
15862
|
+
|
|
15863
|
+
releaseHandler = Fit.Events.AddHandler(document, (Fit.Browser.IsTouchEnabled() === true ? "touchend" : "mouseup"), function(e)
|
|
15864
|
+
{
|
|
15865
|
+
cleanup();
|
|
15866
|
+
});
|
|
15867
|
+
|
|
15868
|
+
if (Fit.Browser.IsTouchEnabled() === true)
|
|
15869
|
+
{
|
|
15870
|
+
cancelHandler = Fit.Events.AddHandler(document, "touchcancel", function(e) // Can be triggered on iOS by swiping down notification panel or control center while resizing
|
|
15871
|
+
{
|
|
15872
|
+
cleanup();
|
|
15873
|
+
});
|
|
15874
|
+
}
|
|
15875
|
+
|
|
15876
|
+
if (ev.type === "touchstart")
|
|
15877
|
+
{
|
|
15878
|
+
Fit.Events.PreventDefault(ev); // Stop page scrolling on iOS (required in both ontouchstart and ontouchmove handlers)
|
|
15879
|
+
}
|
|
15880
|
+
});
|
|
15881
|
+
|
|
15882
|
+
return resizer;
|
|
15883
|
+
}
|
|
15884
|
+
|
|
15468
15885
|
function setContentHeight()
|
|
15469
15886
|
{
|
|
15470
15887
|
if (me.IsOpen() === false)
|
|
@@ -15478,10 +15895,10 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15478
15895
|
|
|
15479
15896
|
content.style.height = "";
|
|
15480
15897
|
|
|
15481
|
-
if ((buttons !== null ||
|
|
15898
|
+
if ((buttons !== null || titleContainer !== null) && (me.Maximized() === true || me.Height().Value !== -1 || me.MinimumHeight().Value !== -1 || me.MaximumHeight().Value !== -1))
|
|
15482
15899
|
{
|
|
15483
15900
|
var dh = dialog.offsetHeight;
|
|
15484
|
-
var th = (
|
|
15901
|
+
var th = (titleContainer !== null ? titleContainer.offsetHeight : 0);
|
|
15485
15902
|
var bh = (buttons !== null ? buttons.offsetHeight : 0);
|
|
15486
15903
|
|
|
15487
15904
|
content.style.height = (dh - th - bh) + "px";
|
|
@@ -15490,6 +15907,9 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15490
15907
|
|
|
15491
15908
|
function updatePosition()
|
|
15492
15909
|
{
|
|
15910
|
+
if (suppressPositioning === true)
|
|
15911
|
+
return;
|
|
15912
|
+
|
|
15493
15913
|
if (me.IsOpen() === false)
|
|
15494
15914
|
return;
|
|
15495
15915
|
|
|
@@ -15513,13 +15933,18 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15513
15933
|
elm.style.top = "0px";
|
|
15514
15934
|
|
|
15515
15935
|
var dim = Fit.Browser.GetViewPortDimensions();
|
|
15516
|
-
var
|
|
15517
|
-
var
|
|
15936
|
+
var offsetTop = (dim.Height - elm.offsetHeight) * 0.25; // Place dialog vertically with 25% of available space above dialog and remaining 75% space below dialog
|
|
15937
|
+
var offsetLeft = (dim.Width - elm.offsetWidth) * 0.5; // Place dialog exactly in the middle horizontally
|
|
15518
15938
|
|
|
15519
|
-
if (offsetTop < 0)
|
|
15939
|
+
if (offsetTop < 0) // Value becomes negative if dialog is higher than viewport
|
|
15940
|
+
{
|
|
15520
15941
|
offsetTop = 0;
|
|
15521
|
-
|
|
15942
|
+
}
|
|
15943
|
+
|
|
15944
|
+
if (offsetLeft < 0) // Value becomes negative if dialog is wider than viewport
|
|
15945
|
+
{
|
|
15522
15946
|
offsetLeft = 0;
|
|
15947
|
+
}
|
|
15523
15948
|
|
|
15524
15949
|
elm.style.left = offsetLeft + "px";
|
|
15525
15950
|
elm.style.top = offsetTop + "px";
|
|
@@ -15533,6 +15958,12 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15533
15958
|
{
|
|
15534
15959
|
Fit.Dom.Remove(titleButtons);
|
|
15535
15960
|
titleButtons = null;
|
|
15961
|
+
|
|
15962
|
+
if (me.Title() === "")
|
|
15963
|
+
{
|
|
15964
|
+
me.Title(null); // Remove title element - will remain enabled if Draggable is enabled
|
|
15965
|
+
}
|
|
15966
|
+
|
|
15536
15967
|
return;
|
|
15537
15968
|
}
|
|
15538
15969
|
|
|
@@ -15545,7 +15976,7 @@ Fit.Controls.Dialog = function(controlId)
|
|
|
15545
15976
|
|
|
15546
15977
|
titleButtons = document.createElement("div");
|
|
15547
15978
|
Fit.Dom.AddClass(titleButtons, "FitUiControlDialogTitleButtons");
|
|
15548
|
-
Fit.Dom.Add(
|
|
15979
|
+
Fit.Dom.Add(titleContainer, titleButtons);
|
|
15549
15980
|
}
|
|
15550
15981
|
|
|
15551
15982
|
// Add/re-add to ensure proper order
|
|
@@ -15590,7 +16021,9 @@ Fit.Controls.Dialog._internal.BaseDialog = function(content, showCancel, cb)
|
|
|
15590
16021
|
var d = new Fit.Controls.Dialog();
|
|
15591
16022
|
d.Content(content.replace(/\n/g, "<br>"));
|
|
15592
16023
|
d.Modal(true);
|
|
16024
|
+
|
|
15593
16025
|
Fit.Dom.AddClass(d.GetDomElement(), "FitUiControlDialogBase");
|
|
16026
|
+
Fit.Dom.AddClass(d._internal.GetLayerElement(), "FitUiControlDialogBaseModalLayer");
|
|
15594
16027
|
|
|
15595
16028
|
// Declare buttons
|
|
15596
16029
|
|
|
@@ -21659,6 +22092,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
21659
22092
|
var designEditorMustDisposeWhenReady = false;
|
|
21660
22093
|
var designEditorUpdateSizeDebouncer = -1;
|
|
21661
22094
|
var designEditorActiveToolbarPanel = null; // { DomElement: HTMLElement, UnlockFocusStateIfEmojiPanelIsClosed: function, CloseEmojiPanel: function }
|
|
22095
|
+
var designEditorDetached = null; // { GetValue: function, Reload: function, Dispose: function }
|
|
21662
22096
|
//var htmlWrappedInParagraph = false;
|
|
21663
22097
|
var wasAutoChangedToMultiLineMode = false; // Used to revert to single line if multi line was automatically enabled along with DesignMode(true), Maximizable(true), or Resizable(true)
|
|
21664
22098
|
var minimizeHeight = -1;
|
|
@@ -21674,6 +22108,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
21674
22108
|
var debounceOnChangeTimeout = -1;
|
|
21675
22109
|
var debouncedOnChange = null;
|
|
21676
22110
|
var imageBlobUrls = []; // Specific to DesignMode
|
|
22111
|
+
var locale = null;
|
|
21677
22112
|
|
|
21678
22113
|
// ============================================
|
|
21679
22114
|
// Init
|
|
@@ -21739,6 +22174,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
21739
22174
|
me._internal.Data("designmode", "false");
|
|
21740
22175
|
|
|
21741
22176
|
Fit.Internationalization.OnLocaleChanged(localize);
|
|
22177
|
+
localize();
|
|
21742
22178
|
|
|
21743
22179
|
me.OnBlur(function(sender)
|
|
21744
22180
|
{
|
|
@@ -21981,20 +22417,22 @@ Fit.Controls.Input = function(ctlId)
|
|
|
21981
22417
|
input.value = val;
|
|
21982
22418
|
}
|
|
21983
22419
|
|
|
22420
|
+
// Notice: Identical logic found in DesignMode(true, config)!
|
|
21984
22421
|
if (designEditorConfig !== null && designEditorConfig.Plugins && designEditorConfig.Plugins.Images && designEditorConfig.Plugins.Images.RevokeExternalBlobUrlsOnDispose === true)
|
|
21985
22422
|
{
|
|
21986
|
-
// Keep track of image blobs added via Value(..) so we can dispose them automatically.
|
|
22423
|
+
// Keep track of image blobs added via Value(..) so we can dispose of them automatically.
|
|
21987
22424
|
// When RevokeExternalBlobUrlsOnDispose is True it basically means that the Input control
|
|
21988
22425
|
// is allowed (and expected) to take control over memory management for these blobs
|
|
21989
22426
|
// based on the rule set in RevokeBlobUrlsOnDispose.
|
|
22427
|
+
// This code is also found in DesignMode(true, config) since images might be added before
|
|
22428
|
+
// editor is created, in which case we do not yet have the editor configuration used to determine
|
|
22429
|
+
// the desired behaviour.
|
|
21990
22430
|
|
|
21991
|
-
var
|
|
22431
|
+
var blobUrls = Fit.String.ParseImageBlobUrls(val);
|
|
21992
22432
|
|
|
21993
|
-
Fit.Array.ForEach(
|
|
22433
|
+
Fit.Array.ForEach(blobUrls, function(blobUrl)
|
|
21994
22434
|
{
|
|
21995
|
-
|
|
21996
|
-
|
|
21997
|
-
if (Fit.Array.Contains(blobImages, blobUrl) === false)
|
|
22435
|
+
if (Fit.Array.Contains(imageBlobUrls, blobUrl) === false)
|
|
21998
22436
|
{
|
|
21999
22437
|
Fit.Array.Add(imageBlobUrls, blobUrl);
|
|
22000
22438
|
}
|
|
@@ -22206,7 +22644,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22206
22644
|
});
|
|
22207
22645
|
}
|
|
22208
22646
|
|
|
22209
|
-
me = orgVal = preVal = input = cmdResize = designEditor = designEditorDom = designEditorDirty = designEditorDirtyPending = designEditorConfig = designEditorReloadConfig = designEditorRestoreButtonState = designEditorSuppressPaste = designEditorSuppressOnResize = designEditorMustReloadWhenReady = designEditorMustDisposeWhenReady = designEditorUpdateSizeDebouncer = designEditorActiveToolbarPanel /*= htmlWrappedInParagraph*/ = wasAutoChangedToMultiLineMode = minimizeHeight = maximizeHeight = minMaxUnit = maximizeHeightConfigured = resizable = nativeResizableAvailable = mutationObserverId = rootedEventId = createWhenReadyIntervalId = isIe8 = debounceOnChangeTimeout = debouncedOnChange = imageBlobUrls = null;
|
|
22647
|
+
me = orgVal = preVal = input = cmdResize = designEditor = designEditorDom = designEditorDirty = designEditorDirtyPending = designEditorConfig = designEditorReloadConfig = designEditorRestoreButtonState = designEditorSuppressPaste = designEditorSuppressOnResize = designEditorMustReloadWhenReady = designEditorMustDisposeWhenReady = designEditorUpdateSizeDebouncer = designEditorActiveToolbarPanel = designEditorDetached /*= htmlWrappedInParagraph*/ = wasAutoChangedToMultiLineMode = minimizeHeight = maximizeHeight = minMaxUnit = maximizeHeightConfigured = resizable = nativeResizableAvailable = mutationObserverId = rootedEventId = createWhenReadyIntervalId = isIe8 = debounceOnChangeTimeout = debouncedOnChange = imageBlobUrls = locale = null;
|
|
22210
22648
|
|
|
22211
22649
|
base();
|
|
22212
22650
|
});
|
|
@@ -22717,7 +23155,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22717
23155
|
/// <description> Configuration for image plugins </description>
|
|
22718
23156
|
/// <member name="Enabled" type="boolean"> Flag indicating whether to enable image plugins or not (defaults to False) </member>
|
|
22719
23157
|
/// <member name="EmbedType" type="'base64' | 'blob'" default="undefined">
|
|
22720
|
-
/// How to store and embed images. Base64 is persistent while blob
|
|
23158
|
+
/// How to store and embed images. Base64 (default) is persistent while blob is temporary
|
|
22721
23159
|
/// and must be extracted from memory and uploaded/stored to be permanantly persisted.
|
|
22722
23160
|
/// References to blobs can be parsed from the HTML value produced by the editor.
|
|
22723
23161
|
/// </member>
|
|
@@ -22751,6 +23189,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22751
23189
|
/// <member name="Links" type="boolean" default="undefined"> Enable links (defaults to True) </member>
|
|
22752
23190
|
/// <member name="Emojis" type="boolean" default="undefined"> Enable emoji button (defaults to False) </member>
|
|
22753
23191
|
/// <member name="Images" type="boolean" default="undefined"> Enable image button (defaults to false) </member>
|
|
23192
|
+
/// <member name="Detach" type="boolean" default="undefined"> Enable detach button (defaults to false) </member>
|
|
22754
23193
|
/// <member name="Position" type="'Top' | 'Bottom'" default="undefined"> Toolbar position (defaults to Top) </member>
|
|
22755
23194
|
/// <member name="Sticky" type="boolean" default="undefined"> Make toolbar stick to edge of scroll container on supported browsers when scrolling (defaults to False) </member>
|
|
22756
23195
|
/// <member name="HideInitially" type="boolean" default="undefined"> Hide toolbar until control gains focus (defaults to False) </member>
|
|
@@ -22781,6 +23220,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22781
23220
|
/// <member name="Icon" type="string" default="undefined"> Optional URL to icon/image </member>
|
|
22782
23221
|
/// <member name="Url" type="string" default="undefined"> Optional URL to associate with tag </member>
|
|
22783
23222
|
/// <member name="Data" type="string" default="undefined"> Optional data to associate with tag </member>
|
|
23223
|
+
/// <member name="Context" type="string" default="undefined"> Optional context information to associate with tag </member>
|
|
22784
23224
|
/// </container>
|
|
22785
23225
|
/// <container name="Fit.Controls.InputTypeDefs.DesignModeTagsOnResponseEventHandlerArgs">
|
|
22786
23226
|
/// <description> Response handler event arguments </description>
|
|
@@ -22802,6 +23242,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22802
23242
|
/// <member name="Type" type="string"> Tag type (marker) </member>
|
|
22803
23243
|
/// <member name="Url" type="string" default="undefined"> Optional tag URL </member>
|
|
22804
23244
|
/// <member name="Data" type="string" default="undefined"> Optional tag data </member>
|
|
23245
|
+
/// <member name="Context" type="string" default="undefined"> Optional tag context </member>
|
|
22805
23246
|
/// </container>
|
|
22806
23247
|
/// <container name="Fit.Controls.InputTypeDefs.DesignModeTagsTagCreatorCallbackArgs">
|
|
22807
23248
|
/// <description> TagCreator event arguments </description>
|
|
@@ -22838,8 +23279,8 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22838
23279
|
/// btoa(JSON.stringify({ creationDate: new Date(), active: true }))
|
|
22839
23280
|
///
|
|
22840
23281
|
/// The data eventuelly results in a tag being added to the editor with the following format:
|
|
22841
|
-
/// <a data-tag-type="@" data-tag-id="unique id 1" data-tag-data="..." href="show/1">Tag name 1</a>
|
|
22842
|
-
/// The data-tag-data
|
|
23282
|
+
/// <a data-tag-type="@" data-tag-id="unique id 1" data-tag-data="..." data-tag-context="..." href="show/1">Tag name 1</a>
|
|
23283
|
+
/// The data-tag-data and data-tag-context attributes are only declared if the corresponding Data and Context properties are defined in data.
|
|
22843
23284
|
/// </member>
|
|
22844
23285
|
/// <member name="JsonpCallback" type="string" default="undefined"> Name of URL parameter receiving name of JSONP callback function (only for JSONP services) </member>
|
|
22845
23286
|
/// <member name="JsonpTimeout" type="integer" default="undefined"> Number of milliseconds to allow JSONP request to wait for a response before aborting (only for JSONP services) </member>
|
|
@@ -22882,6 +23323,20 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22882
23323
|
/// <member name="PreventResizeBeyondMaximumHeight" type="boolean" default="undefined"> Prevent user from resizing editor beyond maximum height (see MaximumHeight property - defaults to False) </member>
|
|
22883
23324
|
/// </container>
|
|
22884
23325
|
|
|
23326
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeDetachable">
|
|
23327
|
+
/// <description> Detachable configuration </description>
|
|
23328
|
+
/// <member name="Title" type="string" default="undefined"> Dialog title </member>
|
|
23329
|
+
/// <member name="Maximizable" type="boolean" default="undefined"> Flag indicating whether dialog is maximizable </member>
|
|
23330
|
+
/// <member name="Maximized" type="boolean" default="undefined"> Flag indicating whether dialog is initially maximized </member>
|
|
23331
|
+
/// <member name="Draggable" type="boolean" default="undefined"> Flag indicating whether dialog is draggable </member>
|
|
23332
|
+
/// <member name="Width" type="{ Value: number, Unit?: Fit.TypeDefs.CssUnit }" default="undefined"> Dialog width </member>
|
|
23333
|
+
/// <member name="MinimumWidth" type="{ Value: number, Unit?: Fit.TypeDefs.CssUnit }" default="undefined"> Minimum width of dialog </member>
|
|
23334
|
+
/// <member name="MaximumWidth" type="{ Value: number, Unit?: Fit.TypeDefs.CssUnit }" default="undefined"> Maximum Width of dialog </member>
|
|
23335
|
+
/// <member name="Height" type="{ Value: number, Unit?: Fit.TypeDefs.CssUnit }" default="undefined"> Dialog height </member>
|
|
23336
|
+
/// <member name="MinimumHeight" type="{ Value: number, Unit?: Fit.TypeDefs.CssUnit }" default="undefined"> Minimum height of dialog </member>
|
|
23337
|
+
/// <member name="MaximumHeight" type="{ Value: number, Unit?: Fit.TypeDefs.CssUnit }" default="undefined"> Maximum height of dialog </member>
|
|
23338
|
+
/// </container>
|
|
23339
|
+
|
|
22885
23340
|
/// <container name="Fit.Controls.InputTypeDefs.DesignModeConfig">
|
|
22886
23341
|
/// <description> Configuration for DesignMode </description>
|
|
22887
23342
|
/// <member name="Plugins" type="Fit.Controls.InputTypeDefs.DesignModeConfigPlugins" default="undefined"> Plugins configuration </member>
|
|
@@ -22889,6 +23344,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22889
23344
|
/// <member name="InfoPanel" type="Fit.Controls.InputTypeDefs.DesignModeConfigInfoPanel" default="undefined"> Information panel configuration </member>
|
|
22890
23345
|
/// <member name="Tags" type="Fit.Controls.InputTypeDefs.DesignModeConfigTags" default="undefined"> Tags configuration </member>
|
|
22891
23346
|
/// <member name="AutoGrow" type="Fit.Controls.InputTypeDefs.DesignModeAutoGrow" default="undefined"> Auto grow configuration </member>
|
|
23347
|
+
/// <member name="Detachable" type="Fit.Controls.InputTypeDefs.DesignModeDetachable" default="undefined"> Detachable configuration </member>
|
|
22892
23348
|
/// </container>
|
|
22893
23349
|
|
|
22894
23350
|
/// <function container="Fit.Controls.Input" name="DesignMode" access="public" returns="boolean">
|
|
@@ -22922,6 +23378,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22922
23378
|
Fit.Validation.ExpectStringValue(((editorConfig || {}).Toolbar || {}).Position, true);
|
|
22923
23379
|
Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Sticky, true);
|
|
22924
23380
|
Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).HideInitially, true);
|
|
23381
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Detach, true);
|
|
22925
23382
|
Fit.Validation.ExpectObject((editorConfig || {}).InfoPanel, true);
|
|
22926
23383
|
Fit.Validation.ExpectString(((editorConfig || {}).InfoPanel || {}).Text, true);
|
|
22927
23384
|
Fit.Validation.ExpectString(((editorConfig || {}).InfoPanel || {}).Alignment, true);
|
|
@@ -22935,6 +23392,29 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22935
23392
|
Fit.Validation.ExpectNumber((((editorConfig || {}).AutoGrow || {}).MaximumHeight || {}).Value, true);
|
|
22936
23393
|
Fit.Validation.ExpectStringValue((((editorConfig || {}).AutoGrow || {}).MaximumHeight || {}).Unit, true);
|
|
22937
23394
|
Fit.Validation.ExpectBoolean(((editorConfig || {}).AutoGrow || {}).PreventResizeBeyondMaximumHeight, true);
|
|
23395
|
+
Fit.Validation.ExpectObject((editorConfig || {}).Detachable, true);
|
|
23396
|
+
Fit.Validation.ExpectString(((editorConfig || {}).Detachable || {}).Title, true);
|
|
23397
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Detachable || {}).Maximizable, true);
|
|
23398
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Detachable || {}).Maximized, true);
|
|
23399
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Detachable || {}).Draggable, true);
|
|
23400
|
+
Fit.Validation.ExpectObject(((editorConfig || {}).Detachable || {}).Width, true);
|
|
23401
|
+
Fit.Validation.ExpectNumber((((editorConfig || {}).Detachable || {}).Width || {}).Value, true);
|
|
23402
|
+
Fit.Validation.ExpectStringValue((((editorConfig || {}).Detachable || {}).Width || {}).Unit, true);
|
|
23403
|
+
Fit.Validation.ExpectObject(((editorConfig || {}).Detachable || {}).MinimumWidth, true);
|
|
23404
|
+
Fit.Validation.ExpectNumber((((editorConfig || {}).Detachable || {}).MinimumWidth || {}).Value, true);
|
|
23405
|
+
Fit.Validation.ExpectStringValue((((editorConfig || {}).Detachable || {}).MinimumWidth || {}).Unit, true);
|
|
23406
|
+
Fit.Validation.ExpectObject(((editorConfig || {}).Detachable || {}).MaximumWidth, true);
|
|
23407
|
+
Fit.Validation.ExpectNumber((((editorConfig || {}).Detachable || {}).MaximumWidth || {}).Value, true);
|
|
23408
|
+
Fit.Validation.ExpectStringValue((((editorConfig || {}).Detachable || {}).MaximumWidth || {}).Unit, true);
|
|
23409
|
+
Fit.Validation.ExpectObject(((editorConfig || {}).Detachable || {}).Height, true);
|
|
23410
|
+
Fit.Validation.ExpectNumber((((editorConfig || {}).Detachable || {}).Height || {}).Value, true);
|
|
23411
|
+
Fit.Validation.ExpectStringValue((((editorConfig || {}).Detachable || {}).Height || {}).Unit, true);
|
|
23412
|
+
Fit.Validation.ExpectObject(((editorConfig || {}).Detachable || {}).MinimumHeight, true);
|
|
23413
|
+
Fit.Validation.ExpectNumber((((editorConfig || {}).Detachable || {}).MinimumHeight || {}).Value, true);
|
|
23414
|
+
Fit.Validation.ExpectStringValue((((editorConfig || {}).Detachable || {}).MinimumHeight || {}).Unit, true);
|
|
23415
|
+
Fit.Validation.ExpectObject(((editorConfig || {}).Detachable || {}).MaximumHeight, true);
|
|
23416
|
+
Fit.Validation.ExpectNumber((((editorConfig || {}).Detachable || {}).MaximumHeight || {}).Value, true);
|
|
23417
|
+
Fit.Validation.ExpectStringValue((((editorConfig || {}).Detachable || {}).MaximumHeight || {}).Unit, true);
|
|
22938
23418
|
|
|
22939
23419
|
if (editorConfig && editorConfig.Tags)
|
|
22940
23420
|
{
|
|
@@ -22987,6 +23467,26 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22987
23467
|
designEditorConfig = Fit.Core.Clone(editorConfig); // Clone to prevent external code from making changes later
|
|
22988
23468
|
}
|
|
22989
23469
|
|
|
23470
|
+
// Notice: Identical logic found in Value(..)!
|
|
23471
|
+
if (designEditorConfig !== null && designEditorConfig.Plugins && designEditorConfig.Plugins.Images && designEditorConfig.Plugins.Images.RevokeExternalBlobUrlsOnDispose === true)
|
|
23472
|
+
{
|
|
23473
|
+
// Keep track of image blobs added via Value(..) so we can dispose of them automatically.
|
|
23474
|
+
// When RevokeExternalBlobUrlsOnDispose is True it basically means that the Input control
|
|
23475
|
+
// is allowed (and expected) to take control over memory management for these blobs
|
|
23476
|
+
// based on the rule set in RevokeBlobUrlsOnDispose.
|
|
23477
|
+
// This code is also found in Value(..) since images might be added after editor has been created.
|
|
23478
|
+
|
|
23479
|
+
var blobUrls = Fit.String.ParseImageBlobUrls(me.Value());
|
|
23480
|
+
|
|
23481
|
+
Fit.Array.ForEach(blobUrls, function(blobUrl)
|
|
23482
|
+
{
|
|
23483
|
+
if (Fit.Array.Contains(imageBlobUrls, blobUrl) === false)
|
|
23484
|
+
{
|
|
23485
|
+
Fit.Array.Add(imageBlobUrls, blobUrl);
|
|
23486
|
+
}
|
|
23487
|
+
});
|
|
23488
|
+
}
|
|
23489
|
+
|
|
22990
23490
|
if (me.MultiLine() === false)
|
|
22991
23491
|
{
|
|
22992
23492
|
me.MultiLine(true);
|
|
@@ -23327,6 +23827,11 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23327
23827
|
|
|
23328
23828
|
var focused = me.Focused();
|
|
23329
23829
|
|
|
23830
|
+
if (focused === true) // Make sure focus is preserved when editor is destroyed
|
|
23831
|
+
{
|
|
23832
|
+
me.GetDomElement().focus();
|
|
23833
|
+
}
|
|
23834
|
+
|
|
23330
23835
|
if (Fit._internal.Controls.Input.ActiveEditorForDialog === me)
|
|
23331
23836
|
{
|
|
23332
23837
|
if (Fit._internal.Controls.Input.ActiveDialogForEditor !== null)
|
|
@@ -23377,31 +23882,25 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23377
23882
|
me._internal.Data("toolbar-sticky", null);
|
|
23378
23883
|
|
|
23379
23884
|
revertToSingleLineIfNecessary();
|
|
23380
|
-
|
|
23381
|
-
// Remove tabindex used to prevent control from losing focus when clicking toolbar buttons
|
|
23382
|
-
Fit.Dom.Attribute(me.GetDomElement(), "tabindex", null);
|
|
23383
|
-
|
|
23384
23885
|
if (focused === true)
|
|
23385
23886
|
{
|
|
23386
|
-
|
|
23387
|
-
|
|
23388
|
-
|
|
23389
|
-
// above (MultiLine(false)). Wrapping the code in setTimeout(..) solves the problem.
|
|
23390
|
-
|
|
23391
|
-
setTimeout(function()
|
|
23392
|
-
{
|
|
23393
|
-
if (me === null)
|
|
23394
|
-
return; // Control was disposed
|
|
23887
|
+
// On IE8 input.focus() does not work if input field is switched to a traditional input field,
|
|
23888
|
+
// or if input field is hidden/invisible. It's just not reliable and not worth it. Remove focus
|
|
23889
|
+
// from the control in IE8 when DesignMode is disabled and preserve focus in every other browser.
|
|
23395
23890
|
|
|
23396
|
-
|
|
23397
|
-
|
|
23891
|
+
if (isIe8 === false)
|
|
23892
|
+
{
|
|
23893
|
+
input.focus();
|
|
23398
23894
|
}
|
|
23399
23895
|
else
|
|
23400
23896
|
{
|
|
23401
|
-
|
|
23897
|
+
me.GetDomElement().blur(); // Control container was given focus further up - this will fire OnBlur as expected
|
|
23402
23898
|
}
|
|
23403
23899
|
}
|
|
23404
23900
|
|
|
23901
|
+
// Remove tabindex used to prevent control from losing focus when clicking toolbar buttons
|
|
23902
|
+
Fit.Dom.Attribute(me.GetDomElement(), "tabindex", null);
|
|
23903
|
+
|
|
23405
23904
|
repaint();
|
|
23406
23905
|
}
|
|
23407
23906
|
}
|
|
@@ -23435,6 +23934,17 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23435
23934
|
return debounceOnChangeTimeout;
|
|
23436
23935
|
}
|
|
23437
23936
|
|
|
23937
|
+
// ============================================
|
|
23938
|
+
// Protected
|
|
23939
|
+
// ============================================
|
|
23940
|
+
|
|
23941
|
+
this._internal = (this._internal ? this._internal : {});
|
|
23942
|
+
|
|
23943
|
+
this._internal.DesignModeEnabledAndReady = function()
|
|
23944
|
+
{
|
|
23945
|
+
return designModeEnabledAndReady();
|
|
23946
|
+
}
|
|
23947
|
+
|
|
23438
23948
|
// ============================================
|
|
23439
23949
|
// Private
|
|
23440
23950
|
// ============================================
|
|
@@ -23497,8 +24007,8 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23497
24007
|
}
|
|
23498
24008
|
|
|
23499
24009
|
var langSupport = ["da", "de", "en"];
|
|
23500
|
-
var
|
|
23501
|
-
var lang = Fit.Array.Contains(langSupport,
|
|
24010
|
+
var localeCode = Fit.Internationalization.Locale().length === 2 ? Fit.Internationalization.Locale() : Fit.Internationalization.Locale().substring(0, 2);
|
|
24011
|
+
var lang = Fit.Array.Contains(langSupport, localeCode) === true ? localeCode : "en";
|
|
23502
24012
|
var plugins = [];
|
|
23503
24013
|
var toolbar = [];
|
|
23504
24014
|
var mentions = [];
|
|
@@ -23512,7 +24022,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23512
24022
|
Fit.Array.Add(plugins, "emoji");
|
|
23513
24023
|
}
|
|
23514
24024
|
|
|
23515
|
-
if ((
|
|
24025
|
+
if (designModeEnableImagePlugin() === true)
|
|
23516
24026
|
{
|
|
23517
24027
|
if (config.Toolbar && config.Toolbar.Images === true)
|
|
23518
24028
|
{
|
|
@@ -23522,6 +24032,8 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23522
24032
|
plugins = Fit.Array.Merge(plugins, ["base64imagepaste", "dragresize"]);
|
|
23523
24033
|
}
|
|
23524
24034
|
|
|
24035
|
+
Fit.Array.Add(plugins, "custombuttons");
|
|
24036
|
+
|
|
23525
24037
|
// Add toolbar buttons
|
|
23526
24038
|
|
|
23527
24039
|
if (!config.Toolbar || config.Toolbar.Formatting !== false)
|
|
@@ -23582,6 +24094,43 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23582
24094
|
items: insert
|
|
23583
24095
|
});
|
|
23584
24096
|
}
|
|
24097
|
+
|
|
24098
|
+
var customButtons = [];
|
|
24099
|
+
var customToolbarGroups = [];
|
|
24100
|
+
|
|
24101
|
+
if (config.Toolbar.Detach === true)
|
|
24102
|
+
{
|
|
24103
|
+
Fit.Array.Add(customButtons,
|
|
24104
|
+
{
|
|
24105
|
+
Label: locale.Detach,
|
|
24106
|
+
Command: "Detach",
|
|
24107
|
+
Icon: Fit.GetUrl() + "/Controls/Input/" + (window.devicePixelRatio === 2 ? "maximize-highres.png" : "maximize.png"),
|
|
24108
|
+
Callback: function(args)
|
|
24109
|
+
{
|
|
24110
|
+
//console.log("Command " + args.Command.name + " executed", args);
|
|
24111
|
+
openDetachedDesignEditor();
|
|
24112
|
+
}
|
|
24113
|
+
});
|
|
24114
|
+
|
|
24115
|
+
/*Fit.Array.Add(customButtons,
|
|
24116
|
+
{
|
|
24117
|
+
Label: "Testing 1-2-3",
|
|
24118
|
+
Command: "TestButton",
|
|
24119
|
+
Icon: "/files/images/Bird.png",
|
|
24120
|
+
Callback: function(args)
|
|
24121
|
+
{
|
|
24122
|
+
alert("Hello world");
|
|
24123
|
+
}
|
|
24124
|
+
});*/
|
|
24125
|
+
|
|
24126
|
+
Fit.Array.Add(customToolbarGroups,
|
|
24127
|
+
{
|
|
24128
|
+
name: "DetachableEditor",
|
|
24129
|
+
items: ["Detach"/*, "TestButton"*/]
|
|
24130
|
+
});
|
|
24131
|
+
}
|
|
24132
|
+
|
|
24133
|
+
toolbar = Fit.Array.Merge(toolbar, customToolbarGroups);
|
|
23585
24134
|
}
|
|
23586
24135
|
|
|
23587
24136
|
// Configure tags/mentions plugin
|
|
@@ -23770,11 +24319,11 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23770
24319
|
|
|
23771
24320
|
if (alternativeItem !== null)
|
|
23772
24321
|
{
|
|
23773
|
-
return '<a data-tag-type="' + (alternativeItem.Type || trigger.Marker) + '" data-tag-id="' + (alternativeItem.Value || item.Value) + '"' + (alternativeItem.Data || item.Data ? ' data-tag-data="' + (alternativeItem.Data || item.Data) + '"' : '') + (alternativeItem.Url || item.Url ? ' href="' + (alternativeItem.Url || item.Url) + '"' : 'href=""') + '>' + (alternativeItem.Title || (trigger.Marker + item.Title)) + '</a>';
|
|
24322
|
+
return '<a data-tag-type="' + (alternativeItem.Type || trigger.Marker) + '" data-tag-id="' + (alternativeItem.Value || item.Value) + '"' + (alternativeItem.Data || item.Data ? ' data-tag-data="' + (alternativeItem.Data || item.Data) + '"' : '') + (alternativeItem.Context || item.Context ? ' data-tag-context="' + (alternativeItem.Context || item.Context) + '"' : '') + (alternativeItem.Url || item.Url ? ' href="' + (alternativeItem.Url || item.Url) + '"' : 'href=""') + '>' + (alternativeItem.Title || (trigger.Marker + item.Title)) + '</a>';
|
|
23774
24323
|
}
|
|
23775
24324
|
else
|
|
23776
24325
|
{
|
|
23777
|
-
return '<a data-tag-type="' + trigger.Marker + '" data-tag-id="' + item.Value + '"' + (item.Data ? ' data-tag-data="' + item.Data + '"' : '') + (item.Url ? ' href="' + item.Url + '"' : 'href=""') + '>' + trigger.Marker + item.Title + '</a>';
|
|
24326
|
+
return '<a data-tag-type="' + trigger.Marker + '" data-tag-id="' + item.Value + '"' + (item.Data ? ' data-tag-data="' + item.Data + '"' : '') + (item.Context ? ' data-tag-context="' + item.Context + '"' : '') + (item.Url ? ' href="' + item.Url + '"' : 'href=""') + '>' + trigger.Marker + item.Title + '</a>';
|
|
23778
24327
|
}
|
|
23779
24328
|
}
|
|
23780
24329
|
};
|
|
@@ -23785,7 +24334,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23785
24334
|
mention.feed = Fit.Core.CreateDebouncer(mention.feed, trigger.DebounceQuery || 300).Invoke;
|
|
23786
24335
|
}
|
|
23787
24336
|
|
|
23788
|
-
Fit.Array.Add(mentions, mention)
|
|
24337
|
+
Fit.Array.Add(mentions, mention);
|
|
23789
24338
|
});
|
|
23790
24339
|
}
|
|
23791
24340
|
|
|
@@ -23830,7 +24379,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23830
24379
|
toolbarLocation: designEditorConfig !== null && designEditorConfig.Toolbar && designEditorConfig.Toolbar.Position === "Bottom" ? "bottom" : "top",
|
|
23831
24380
|
uiColor: Fit._internal.Controls.Input.Editor.Skin === "moono-lisa" || Fit._internal.Controls.Input.Editor.Skin === null ? "#FFFFFF" : undefined,
|
|
23832
24381
|
//allowedContent: true, // http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules and http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent
|
|
23833
|
-
extraAllowedContent: "a[data-tag-type,data-tag-id,data-tag-data]", // https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-extraAllowedContent
|
|
24382
|
+
extraAllowedContent: "a[data-tag-type,data-tag-id,data-tag-data,data-tag-context]", // https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-extraAllowedContent
|
|
23834
24383
|
language: lang,
|
|
23835
24384
|
disableNativeSpellChecker: me.CheckSpelling() === false,
|
|
23836
24385
|
readOnly: me.Enabled() === false,
|
|
@@ -23855,6 +24404,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23855
24404
|
resize_dir: resizable === Fit.Controls.InputResizing.Enabled ? "both" : resizable === Fit.Controls.InputResizing.Vertical ? "vertical" : resizable === Fit.Controls.InputResizing.Horizontal ? "horizontal" : "none", // Specific to resize plugin (horizontal | vertical | both - https://ckeditor.com/docs/ckeditor4/latest/features/resize.html)
|
|
23856
24405
|
toolbar: toolbar,
|
|
23857
24406
|
removeButtons: "", // Set to empty string to prevent CKEditor from removing buttons such as Underline
|
|
24407
|
+
customButtons: customButtons,
|
|
23858
24408
|
mentions: mentions,
|
|
23859
24409
|
emoji_minChars: 9999, // Impossible requirement to number of search characters to "disable" emoji auto complete menu - we cannot make it work properly with light dismissable panels/callouts since we have no event available for registering the data-disable-light-dismiss="true" attribute, and it's not very useful in any case
|
|
23860
24410
|
on:
|
|
@@ -23953,17 +24503,21 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23953
24503
|
if (Fit.Dom.GetComputedStyle(toolbarContainer, "position") === "sticky") // False on non-supported browsers as position:sticky is applied via the @supports CSS rule
|
|
23954
24504
|
{
|
|
23955
24505
|
var scrollParent = Fit.Dom.GetScrollParent(me.GetDomElement());
|
|
23956
|
-
var toolbarPosition = me._internal.Data("toolbar-position"); // top | bottom
|
|
23957
24506
|
|
|
23958
|
-
if (
|
|
23959
|
-
{
|
|
23960
|
-
var paddingOffset = Fit.Dom.GetComputedStyle(scrollParent, "padding-top"); // E.g. "28px"
|
|
23961
|
-
toolbarContainer.style.top = paddingOffset !== "0px" ? "-" + paddingOffset : "";
|
|
23962
|
-
}
|
|
23963
|
-
else
|
|
24507
|
+
if (scrollParent !== null) // In case editor is hosted in a container with position:fixed with overflow:hidden, in which case Fit.Dom.GetScrollParent(..) returns null
|
|
23964
24508
|
{
|
|
23965
|
-
var
|
|
23966
|
-
|
|
24509
|
+
var toolbarPosition = me._internal.Data("toolbar-position"); // top | bottom
|
|
24510
|
+
|
|
24511
|
+
if (toolbarPosition === "top")
|
|
24512
|
+
{
|
|
24513
|
+
var paddingOffset = Fit.Dom.GetComputedStyle(scrollParent, "padding-top"); // E.g. "28px"
|
|
24514
|
+
toolbarContainer.style.top = paddingOffset !== "0px" ? "-" + paddingOffset : "";
|
|
24515
|
+
}
|
|
24516
|
+
else
|
|
24517
|
+
{
|
|
24518
|
+
var paddingOffset = Fit.Dom.GetComputedStyle(scrollParent, "padding-bottom"); // E.g. "28px"
|
|
24519
|
+
toolbarContainer.style.bottom = paddingOffset !== "0px" ? "-" + paddingOffset : "";
|
|
24520
|
+
}
|
|
23967
24521
|
}
|
|
23968
24522
|
}
|
|
23969
24523
|
}
|
|
@@ -24127,7 +24681,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
24127
24681
|
// place focus at the end of the editor as expected.
|
|
24128
24682
|
if (me.Focused() === true)
|
|
24129
24683
|
{
|
|
24130
|
-
designEditor.focus();
|
|
24684
|
+
designEditor.focus(); // Won't work on iOS as assigning focus must be the result of a direct user interaction, which this is not since it is postponed using setTimeout(..) and async. loading of the editor
|
|
24131
24685
|
}
|
|
24132
24686
|
}, 0);
|
|
24133
24687
|
},
|
|
@@ -24193,11 +24747,18 @@ Fit.Controls.Input = function(ctlId)
|
|
|
24193
24747
|
|
|
24194
24748
|
if (elm.tagName === "A" && Fit.Dom.Data(elm, "tag-id") !== null)
|
|
24195
24749
|
{
|
|
24196
|
-
|
|
24197
|
-
|
|
24750
|
+
// Notice that selectionChange handler is invoked while editor is loading if control was given initial focus.
|
|
24751
|
+
// But at this point the toolbar buttons are not yet available to be disabled, so disableDesignEditorButtons()
|
|
24752
|
+
// won't work. However, as soon as the editor is done loading, focus is re-assigned to the editable area
|
|
24753
|
+
// which will trigger selectionChange handler once again, at which point designModeEnabledAndReady() returns true.
|
|
24754
|
+
if (designModeEnabledAndReady() === true)
|
|
24198
24755
|
{
|
|
24199
|
-
|
|
24200
|
-
|
|
24756
|
+
designEditorSuppressPaste = true;
|
|
24757
|
+
setTimeout(function() // Postpone - otherwise we won't be able to temporarily disable some of the buttons (https://jsfiddle.net/ymv56znq/14/)
|
|
24758
|
+
{
|
|
24759
|
+
disableDesignEditorButtons();
|
|
24760
|
+
}, 0);
|
|
24761
|
+
}
|
|
24201
24762
|
}
|
|
24202
24763
|
else
|
|
24203
24764
|
{
|
|
@@ -24526,6 +25087,258 @@ Fit.Controls.Input = function(ctlId)
|
|
|
24526
25087
|
}
|
|
24527
25088
|
}
|
|
24528
25089
|
|
|
25090
|
+
function openDetachedDesignEditor()
|
|
25091
|
+
{
|
|
25092
|
+
me._internal.FocusStateLocked(true);
|
|
25093
|
+
|
|
25094
|
+
var deConfig = null;
|
|
25095
|
+
|
|
25096
|
+
var updateDetachedConfiguration = function()
|
|
25097
|
+
{
|
|
25098
|
+
deConfig = Fit.Core.Clone(designEditorConfig || {});
|
|
25099
|
+
|
|
25100
|
+
// Configure detached editor like original, but with a few required changes.
|
|
25101
|
+
// We need to make sure image blobs are handled properly, that detached editor
|
|
25102
|
+
// cannot created another detached editor, that the toolbar is initially visible
|
|
25103
|
+
// at the top of the dialog, and that auto grow is disabled.
|
|
25104
|
+
|
|
25105
|
+
if (designModeEnableImagePlugin() === true)
|
|
25106
|
+
{
|
|
25107
|
+
deConfig = Fit.Core.Merge(deConfig, // Override image plugin configuration
|
|
25108
|
+
{
|
|
25109
|
+
Plugins:
|
|
25110
|
+
{
|
|
25111
|
+
Images:
|
|
25112
|
+
{
|
|
25113
|
+
Enabled: true,
|
|
25114
|
+
EmbedType: deConfig.Plugins && deConfig.Plugins.Images && deConfig.Plugins.Images.EmbedType,
|
|
25115
|
+
|
|
25116
|
+
// Image blobs added in detached editor must always be disposed if no longer referenced.
|
|
25117
|
+
// Furthermore we make sure image blobs originating from main editor are never disposed.
|
|
25118
|
+
// When detached editor is closed, images transfered from detached editor to main editor
|
|
25119
|
+
// are added to the main editor's index over image blobs so that the main editor becomes
|
|
25120
|
+
// responsible for the memory management of these.
|
|
25121
|
+
// If detached editor is closed without transfering changes (canceled), all images found
|
|
25122
|
+
// in the detached editor, which are not referenced in the main editor, are disposed.
|
|
25123
|
+
// See OnClick handlers for OK and Cancel buttons.
|
|
25124
|
+
|
|
25125
|
+
RevokeBlobUrlsOnDispose: "UnreferencedOnly", // Make dialog editor preserve newly added (and still referenced) image blobs when disposed
|
|
25126
|
+
RevokeExternalBlobUrlsOnDispose: false // Make dialog editor preserve images blobs initially added from main editor
|
|
25127
|
+
}
|
|
25128
|
+
}
|
|
25129
|
+
});
|
|
25130
|
+
}
|
|
25131
|
+
|
|
25132
|
+
deConfig.Toolbar = deConfig.Toolbar || {};
|
|
25133
|
+
deConfig.Toolbar.Detach = false;
|
|
25134
|
+
deConfig.Toolbar.Position = "Top";
|
|
25135
|
+
deConfig.Toolbar.Sticky = false;
|
|
25136
|
+
deConfig.Toolbar.HideInitially = false;
|
|
25137
|
+
|
|
25138
|
+
delete deConfig.AutoGrow;
|
|
25139
|
+
};
|
|
25140
|
+
|
|
25141
|
+
updateDetachedConfiguration();
|
|
25142
|
+
|
|
25143
|
+
// Create dialog
|
|
25144
|
+
|
|
25145
|
+
var dia = new Fit.Controls.Dialog();
|
|
25146
|
+
Fit.Dom.AddClass(dia.GetDomElement(), "FitUiControlInputDetached");
|
|
25147
|
+
|
|
25148
|
+
// Create editor
|
|
25149
|
+
|
|
25150
|
+
var de = new Fit.Controls.Input();
|
|
25151
|
+
|
|
25152
|
+
var setDetachedEditorSettings = function()
|
|
25153
|
+
{
|
|
25154
|
+
de.Width(100, "%");
|
|
25155
|
+
de.Height(-1);
|
|
25156
|
+
de.CheckSpelling(me.CheckSpelling());
|
|
25157
|
+
de.DesignMode(true, deConfig);
|
|
25158
|
+
};
|
|
25159
|
+
|
|
25160
|
+
setDetachedEditorSettings();
|
|
25161
|
+
de.Value(me.Value());
|
|
25162
|
+
|
|
25163
|
+
// Make editor adjust to the dimensions of the dialog
|
|
25164
|
+
|
|
25165
|
+
// Adjust editor size to fit dialog using a timer.
|
|
25166
|
+
// Alternatively expose an OnResize event on Fit.Controls.Dialog, use it in
|
|
25167
|
+
// combination with window.onresize, and adjust editor when these events are triggered.
|
|
25168
|
+
// However, the process of monitoring the dimensions using a timer is practically free,
|
|
25169
|
+
// so even though the timer interupts browser events such as onmousemove, onscroll, etc.,
|
|
25170
|
+
// it creates no lack at all.
|
|
25171
|
+
var height = -1
|
|
25172
|
+
var dimMonitorId = setInterval(function()
|
|
25173
|
+
{
|
|
25174
|
+
if (height === -1 && de._internal.DesignModeEnabledAndReady() === false)
|
|
25175
|
+
{
|
|
25176
|
+
return;
|
|
25177
|
+
}
|
|
25178
|
+
|
|
25179
|
+
var newHeight = dia.GetDomElement().offsetHeight;
|
|
25180
|
+
|
|
25181
|
+
if (newHeight !== height)
|
|
25182
|
+
{
|
|
25183
|
+
height = newHeight
|
|
25184
|
+
de.Height(Fit.Dom.GetInnerDimensions(dia.GetContentDomElement()).Height);
|
|
25185
|
+
}
|
|
25186
|
+
}, 250);
|
|
25187
|
+
|
|
25188
|
+
// Configure dialog
|
|
25189
|
+
|
|
25190
|
+
var setDialogSettings = function(update)
|
|
25191
|
+
{
|
|
25192
|
+
var detachConfig = deConfig.Detachable || {};
|
|
25193
|
+
detachConfig = Fit.Core.Merge(detachConfig, // Apply default values - existing properties are preserved (Fit.Core.MergeOverwriteBehaviour.Never)
|
|
25194
|
+
{
|
|
25195
|
+
Title: "",
|
|
25196
|
+
Maximizable: true,
|
|
25197
|
+
Maximized: false,
|
|
25198
|
+
Draggable: true,
|
|
25199
|
+
Resizable: true,
|
|
25200
|
+
Width: detachConfig.Width ? detachConfig.Width : { Value: 850, Unit: "px" },
|
|
25201
|
+
MinimumWidth: detachConfig.MinimumWidth ? detachConfig.MinimumWidth : { Value: 20, Unit: "em" },
|
|
25202
|
+
MaximumWidth: detachConfig.MaximumWidth ? detachConfig.MaximumWidth : { Value: 100, Unit: "%" },
|
|
25203
|
+
Height: detachConfig.Height ? detachConfig.Height : { Value: 550, Unit: "px" },
|
|
25204
|
+
MinimumHeight: detachConfig.MinimumHeight ? detachConfig.MinimumHeight : { Value: 12, Unit: "em" },
|
|
25205
|
+
MaximumHeight: detachConfig.MaximumHeight ? detachConfig.MaximumHeight : { Value: 100, Unit: "%" }
|
|
25206
|
+
}, Fit.Core.MergeOverwriteBehaviour.Never);
|
|
25207
|
+
|
|
25208
|
+
var updateDimensions = (!detachConfig.Resizable || update !== true);
|
|
25209
|
+
|
|
25210
|
+
dia.Title(detachConfig.Title);
|
|
25211
|
+
dia.Modal(true);
|
|
25212
|
+
dia.Draggable(detachConfig.Draggable);
|
|
25213
|
+
dia.Resizable(detachConfig.Resizable);
|
|
25214
|
+
dia.Maximizable(detachConfig.Maximizable);
|
|
25215
|
+
dia.Maximized(detachConfig.Maximized);
|
|
25216
|
+
updateDimensions === true && dia.Width(detachConfig.Width.Value, detachConfig.Width.Unit || "px");
|
|
25217
|
+
updateDimensions === true && dia.Height(detachConfig.Height.Value, detachConfig.Height.Unit || "px");
|
|
25218
|
+
dia.MinimumWidth(detachConfig.MinimumWidth.Value, detachConfig.MinimumWidth.Unit || "px");
|
|
25219
|
+
dia.MinimumHeight(detachConfig.MinimumHeight.Value, detachConfig.MinimumHeight.Unit || "px");
|
|
25220
|
+
dia.MaximumWidth(detachConfig.MaximumWidth.Value, detachConfig.MaximumWidth.Unit || "px");
|
|
25221
|
+
dia.MaximumHeight(detachConfig.MaximumHeight.Value, detachConfig.MaximumHeight.Unit || "px");
|
|
25222
|
+
};
|
|
25223
|
+
|
|
25224
|
+
setDialogSettings();
|
|
25225
|
+
|
|
25226
|
+
// Localization support
|
|
25227
|
+
|
|
25228
|
+
var localizeDetachedEditor = function()
|
|
25229
|
+
{
|
|
25230
|
+
// Editor itself is already localized, so we just need to
|
|
25231
|
+
// localize the dialog. The locale variable will already have
|
|
25232
|
+
// been updated by the OnLocaleChanged handler registered in init().
|
|
25233
|
+
|
|
25234
|
+
cmdOk.Title(locale.Ok);
|
|
25235
|
+
cmdCancel.Title(locale.Cancel);
|
|
25236
|
+
};
|
|
25237
|
+
Fit.Internationalization.OnLocaleChanged(localizeDetachedEditor);
|
|
25238
|
+
|
|
25239
|
+
// Expose detached editor API
|
|
25240
|
+
|
|
25241
|
+
designEditorDetached =
|
|
25242
|
+
{
|
|
25243
|
+
GetValue: function()
|
|
25244
|
+
{
|
|
25245
|
+
return de.Value();
|
|
25246
|
+
},
|
|
25247
|
+
|
|
25248
|
+
Reload: function()
|
|
25249
|
+
{
|
|
25250
|
+
// Update configuration
|
|
25251
|
+
updateDetachedConfiguration();
|
|
25252
|
+
|
|
25253
|
+
// Update editor
|
|
25254
|
+
setDetachedEditorSettings();
|
|
25255
|
+
|
|
25256
|
+
// Update dialog
|
|
25257
|
+
setDialogSettings(true);
|
|
25258
|
+
|
|
25259
|
+
// Make dimension monitor ensure proper editor height (dialog height might have been changed)
|
|
25260
|
+
height = -1;
|
|
25261
|
+
},
|
|
25262
|
+
|
|
25263
|
+
Dispose: function()
|
|
25264
|
+
{
|
|
25265
|
+
clearInterval(dimMonitorId);
|
|
25266
|
+
Fit.Internationalization.RemoveOnLocaleChanged(localizeDetachedEditor);
|
|
25267
|
+
de.Dispose();
|
|
25268
|
+
dia.Dispose(); // Will also dispose associated buttons
|
|
25269
|
+
designEditorDetached = null;
|
|
25270
|
+
}
|
|
25271
|
+
};
|
|
25272
|
+
|
|
25273
|
+
var cmdOk = new Fit.Controls.Button();
|
|
25274
|
+
cmdOk.Title(locale.Ok);
|
|
25275
|
+
cmdOk.Icon("check");
|
|
25276
|
+
cmdOk.Type(Fit.Controls.ButtonType.Success);
|
|
25277
|
+
cmdOk.OnClick(function(sender)
|
|
25278
|
+
{
|
|
25279
|
+
var referencedBlobUrls = Fit.String.ParseImageBlobUrls(de.Value());
|
|
25280
|
+
Fit.Array.ForEach(referencedBlobUrls, function(blobUrl)
|
|
25281
|
+
{
|
|
25282
|
+
if (Fit.Array.Contains(imageBlobUrls, blobUrl) === false)
|
|
25283
|
+
{
|
|
25284
|
+
Fit.Array.Add(imageBlobUrls, blobUrl);
|
|
25285
|
+
}
|
|
25286
|
+
});
|
|
25287
|
+
|
|
25288
|
+
me.Value(de.Value());
|
|
25289
|
+
|
|
25290
|
+
designEditorDetached.Dispose();
|
|
25291
|
+
|
|
25292
|
+
me.Focused(true);
|
|
25293
|
+
me._internal.FocusStateLocked(false);
|
|
25294
|
+
});
|
|
25295
|
+
dia.AddButton(cmdOk);
|
|
25296
|
+
|
|
25297
|
+
var cmdCancel = new Fit.Controls.Button();
|
|
25298
|
+
cmdCancel.Title(locale.Cancel);
|
|
25299
|
+
cmdCancel.Icon("ban");
|
|
25300
|
+
cmdCancel.Type(Fit.Controls.ButtonType.Danger);
|
|
25301
|
+
cmdCancel.OnClick(function(sender)
|
|
25302
|
+
{
|
|
25303
|
+
var closeDialog = function()
|
|
25304
|
+
{
|
|
25305
|
+
var referencedBlobUrls = Fit.String.ParseImageBlobUrls(de.Value());
|
|
25306
|
+
Fit.Array.ForEach(referencedBlobUrls, function(blobUrl)
|
|
25307
|
+
{
|
|
25308
|
+
if (Fit.Array.Contains(imageBlobUrls, blobUrl) === false) // Only remove images added in dialog editor
|
|
25309
|
+
{
|
|
25310
|
+
URL.revokeObjectURL(blobUrl);
|
|
25311
|
+
}
|
|
25312
|
+
});
|
|
25313
|
+
|
|
25314
|
+
designEditorDetached.Dispose();
|
|
25315
|
+
|
|
25316
|
+
me.Focused(true);
|
|
25317
|
+
me._internal.FocusStateLocked(false);
|
|
25318
|
+
};
|
|
25319
|
+
|
|
25320
|
+
if (de.IsDirty() === true)
|
|
25321
|
+
{
|
|
25322
|
+
Fit.Controls.Dialog.Confirm(locale.CancelConfirmTitle + "<br><br>" + locale.CancelConfirmDescription, function(res)
|
|
25323
|
+
{
|
|
25324
|
+
if (res === true)
|
|
25325
|
+
{
|
|
25326
|
+
closeDialog();
|
|
25327
|
+
}
|
|
25328
|
+
});
|
|
25329
|
+
}
|
|
25330
|
+
else
|
|
25331
|
+
{
|
|
25332
|
+
closeDialog();
|
|
25333
|
+
}
|
|
25334
|
+
});
|
|
25335
|
+
dia.AddButton(cmdCancel);
|
|
25336
|
+
|
|
25337
|
+
dia.Open();
|
|
25338
|
+
de.Render(dia.GetContentDomElement());
|
|
25339
|
+
de.Focused(true);
|
|
25340
|
+
}
|
|
25341
|
+
|
|
24529
25342
|
function revertToSingleLineIfNecessary()
|
|
24530
25343
|
{
|
|
24531
25344
|
if (wasAutoChangedToMultiLineMode === true && me.Maximizable() === false && me.Resizable() === Fit.Controls.InputResizing.Disabled && me.DesignMode() === false)
|
|
@@ -24589,10 +25402,25 @@ Fit.Controls.Input = function(ctlId)
|
|
|
24589
25402
|
var height = me.Height();
|
|
24590
25403
|
var currentWasAutoChangedToMultiLineMode = wasAutoChangedToMultiLineMode; // DesignMode(false) will result in wasAutoChangedToMultiLineMode being set to false if DesignMode(true) changed the control to MultiLine mode
|
|
24591
25404
|
|
|
25405
|
+
// Prevent detached editor from being closed when reloading, e.g. if CheckSpelling is changed.
|
|
25406
|
+
// Editor will also be reloaded if a different editor configuration is passed to DesignMode(true, updatedConfig).
|
|
25407
|
+
var detachedEditor = null;
|
|
25408
|
+
if (designEditorDetached !== null)
|
|
25409
|
+
{
|
|
25410
|
+
detachedEditor = designEditorDetached;
|
|
25411
|
+
designEditorDetached = null; // Prevent me.DesignMode(false), which in turn calls destroyDesignEditorInstance(), from closing detached editor dialog
|
|
25412
|
+
}
|
|
25413
|
+
|
|
24592
25414
|
me.DesignMode(false);
|
|
24593
25415
|
me.DesignMode(true, reloadConfig || designEditorReloadConfig || undefined); // Use reloadConfig if set (and if reload was not postponed) or use designEditorReloadConfig if reload was postponed with updated editor config
|
|
24594
25416
|
designEditorReloadConfig = null;
|
|
24595
25417
|
|
|
25418
|
+
if (detachedEditor !== null)
|
|
25419
|
+
{
|
|
25420
|
+
designEditorDetached = detachedEditor;
|
|
25421
|
+
designEditorDetached.Reload(); // Reload detached editor to reflect any changes made to configuration
|
|
25422
|
+
}
|
|
25423
|
+
|
|
24596
25424
|
me.Height(height.Value, height.Unit);
|
|
24597
25425
|
wasAutoChangedToMultiLineMode = currentWasAutoChangedToMultiLineMode;
|
|
24598
25426
|
}
|
|
@@ -24611,9 +25439,14 @@ Fit.Controls.Input = function(ctlId)
|
|
|
24611
25439
|
|
|
24612
25440
|
designEditor.destroy();
|
|
24613
25441
|
|
|
25442
|
+
if (designEditorDetached !== null)
|
|
25443
|
+
{
|
|
25444
|
+
designEditorDetached.Dispose();
|
|
25445
|
+
}
|
|
25446
|
+
|
|
24614
25447
|
designEditor = null;
|
|
24615
25448
|
designEditorDom = null;
|
|
24616
|
-
designEditorDirty = false;
|
|
25449
|
+
//designEditorDirty = false; // Do NOT reset this! We need to preserve dirty state in case DesignMode is reloaded!
|
|
24617
25450
|
designEditorDirtyPending = false;
|
|
24618
25451
|
//designEditorConfig = null; // Do NOT nullify this! We need it, in case DesignMode is toggled!
|
|
24619
25452
|
//designEditorReloadConfig = null; // Do NOT nullify this! We need it, in case DesignMode is reloaded!
|
|
@@ -24623,6 +25456,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
24623
25456
|
designEditorMustReloadWhenReady = false;
|
|
24624
25457
|
designEditorMustDisposeWhenReady = false;
|
|
24625
25458
|
designEditorActiveToolbarPanel = null;
|
|
25459
|
+
designEditorDetached = null;
|
|
24626
25460
|
|
|
24627
25461
|
if (designEditorUpdateSizeDebouncer !== -1)
|
|
24628
25462
|
{
|
|
@@ -24654,12 +25488,47 @@ Fit.Controls.Input = function(ctlId)
|
|
|
24654
25488
|
return designEditorDom !== null; // Editor is fully loaded when editor DOM is made available
|
|
24655
25489
|
}
|
|
24656
25490
|
|
|
25491
|
+
function designModeEnableImagePlugin()
|
|
25492
|
+
{
|
|
25493
|
+
var config = designEditorConfig || {};
|
|
25494
|
+
var enableImagePlugin = (config.Plugins && config.Plugins.Images && config.Plugins.Images.Enabled === true) || (config.Toolbar && config.Toolbar.Images === true) || false;
|
|
25495
|
+
|
|
25496
|
+
// Force enable image support if images are contained in value - otherwise editor will remove them
|
|
25497
|
+
if (enableImagePlugin === false && designEditorDetached !== null && designEditorDetached.GetValue().indexOf("<img ") > -1)
|
|
25498
|
+
{
|
|
25499
|
+
enableImagePlugin = true;
|
|
25500
|
+
}
|
|
25501
|
+
if (enableImagePlugin === false && me.Value().indexOf("<img ") > -1)
|
|
25502
|
+
{
|
|
25503
|
+
enableImagePlugin = true;
|
|
25504
|
+
}
|
|
25505
|
+
|
|
25506
|
+
return enableImagePlugin;
|
|
25507
|
+
}
|
|
25508
|
+
|
|
24657
25509
|
function localize()
|
|
24658
25510
|
{
|
|
25511
|
+
locale = Fit.Internationalization.GetLocale(me);
|
|
25512
|
+
|
|
24659
25513
|
if (me.DesignMode() === true)
|
|
24660
25514
|
{
|
|
25515
|
+
// Prevent reloadEditor() from reloading detached editor.
|
|
25516
|
+
// It will automatically reload when locale is changed.
|
|
25517
|
+
// Without this guard the editor would reload twice.
|
|
25518
|
+
var detachedEditor = null;
|
|
25519
|
+
if (designEditorDetached !== null)
|
|
25520
|
+
{
|
|
25521
|
+
detachedEditor = designEditorDetached;
|
|
25522
|
+
designEditorDetached = null; // Prevent reloadEditor() from reloading detached editor
|
|
25523
|
+
}
|
|
25524
|
+
|
|
24661
25525
|
// Re-create editor with new language
|
|
24662
25526
|
reloadEditor();
|
|
25527
|
+
|
|
25528
|
+
if (detachedEditor !== null)
|
|
25529
|
+
{
|
|
25530
|
+
designEditorDetached = detachedEditor;
|
|
25531
|
+
}
|
|
24663
25532
|
}
|
|
24664
25533
|
}
|
|
24665
25534
|
|
|
@@ -24776,6 +25645,40 @@ Fit.Controls.InputResizing = // Enums must exist runtime
|
|
|
24776
25645
|
Horizontal: "Horizontal",
|
|
24777
25646
|
Vertical: "Vertical"
|
|
24778
25647
|
};
|
|
25648
|
+
Fit.Internationalization.AddLocalization(Fit.Controls.Input,
|
|
25649
|
+
{
|
|
25650
|
+
// Primary locales must be registered before country specific overrides.
|
|
25651
|
+
// Example order: en, en_GB, de, de_AT, etc.
|
|
25652
|
+
// All locales inherit from en. All country specific overrides inherit
|
|
25653
|
+
// from their general locale (e.g. de_AT inherits from de).
|
|
25654
|
+
// English (en) MUST be defined, and be defined first!
|
|
25655
|
+
|
|
25656
|
+
"en":
|
|
25657
|
+
{
|
|
25658
|
+
"Detach": "Open in dialog",
|
|
25659
|
+
"Ok": "OK",
|
|
25660
|
+
"Cancel": "Cancel",
|
|
25661
|
+
"CancelConfirmTitle": "Discard changes?",
|
|
25662
|
+
"CancelConfirmDescription": "Are you sure you want to discard the changes?"
|
|
25663
|
+
},
|
|
25664
|
+
"da":
|
|
25665
|
+
{
|
|
25666
|
+
"Detach": "Åben i dialog",
|
|
25667
|
+
"Ok": "OK",
|
|
25668
|
+
"Cancel": "Annullér",
|
|
25669
|
+
"CancelConfirmTitle": "Annullér ændringer?",
|
|
25670
|
+
"CancelConfirmDescription": "Er du sikker på at du vil annullere ændringerne?"
|
|
25671
|
+
},
|
|
25672
|
+
"de":
|
|
25673
|
+
{
|
|
25674
|
+
"Detach": "Im Dialog öffnen",
|
|
25675
|
+
"Ok": "OK",
|
|
25676
|
+
"Cancel": "Abbrechen",
|
|
25677
|
+
"CancelConfirmTitle": "Änderungen verwerfen?",
|
|
25678
|
+
"CancelConfirmDescription": "Möchten Sie die Änderungen wirklich verwerfen?"
|
|
25679
|
+
}
|
|
25680
|
+
});
|
|
25681
|
+
|
|
24779
25682
|
/// <container name="Fit.Controls.ListView" extends="Fit.Controls.PickerBase;Fit.Controls.Component">
|
|
24780
25683
|
/// Picker control which allows for entries
|
|
24781
25684
|
/// to be selected in the DropDown control.
|
|
@@ -26094,7 +26997,7 @@ Fit.Controls.SoftLog = function(controlId)
|
|
|
26094
26997
|
|
|
26095
26998
|
/// <function container="Fit.Controls.SoftLog" name="MaxEntries" access="public" returns="integer">
|
|
26096
26999
|
/// <description> Get/set number of log entries preserved </description>
|
|
26097
|
-
/// <param name="val" type="
|
|
27000
|
+
/// <param name="val" type="integer" default="undefined"> If defined, changes number of log entries preserved </param>
|
|
26098
27001
|
/// </function>
|
|
26099
27002
|
this.MaxEntries = function(val)
|
|
26100
27003
|
{
|