fit-ui 2.5.6 → 2.6.2
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/Documentation.html +3 -3
- package/dist/Fit.UI.css +102 -6
- package/dist/Fit.UI.js +750 -109
- package/dist/Fit.UI.min.css +1 -1
- package/dist/Fit.UI.min.js +1 -1
- package/dist/Resources/CKEditor/build-config.js +7 -3
- package/dist/Resources/CKEditor/ckeditor.js +93 -5
- package/dist/Resources/CKEditor/lang/da.js +2 -2
- package/dist/Resources/CKEditor/lang/de.js +2 -2
- package/dist/Resources/CKEditor/lang/en.js +2 -2
- package/dist/Resources/CKEditor/plugins/autocomplete/skins/default.css +38 -0
- package/dist/Resources/CKEditor/plugins/base64image/plugin.js +1 -1
- package/dist/Resources/CKEditor/plugins/emoji/assets/iconsall.png +0 -0
- package/dist/Resources/CKEditor/plugins/emoji/assets/iconsall.svg +58 -0
- package/dist/Resources/CKEditor/plugins/emoji/emoji.json +1 -0
- package/dist/Resources/CKEditor/plugins/emoji/skins/default.css +237 -0
- package/dist/Resources/CKEditor/plugins/icons.png +0 -0
- package/dist/Resources/CKEditor/plugins/icons_hidpi.png +0 -0
- package/dist/Resources/CKEditor/skins/moono-lisa/editor.css +5 -5
- package/dist/Resources/CKEditor/skins/moono-lisa/editor_gecko.css +5 -5
- package/dist/Resources/CKEditor/skins/moono-lisa/editor_ie.css +5 -5
- package/dist/Resources/CKEditor/skins/moono-lisa/editor_ie8.css +5 -5
- package/dist/Resources/CKEditor/skins/moono-lisa/editor_iequirks.css +5 -5
- package/dist/Resources/CKEditor/skins/moono-lisa/icons.png +0 -0
- package/dist/Resources/CKEditor/skins/moono-lisa/icons_hidpi.png +0 -0
- package/package.json +1 -1
- package/types/index.d.ts +497 -136
- package/dist/Resources/CKEditor/plugins/htmlwriter/plugin.js +0 -364
- package/dist/Resources/CKEditor/plugins/resize/plugin.js +0 -187
package/dist/Fit.UI.js
CHANGED
|
@@ -648,7 +648,7 @@ Fit._internal =
|
|
|
648
648
|
{
|
|
649
649
|
Core:
|
|
650
650
|
{
|
|
651
|
-
VersionInfo: { Major: 2, Minor:
|
|
651
|
+
VersionInfo: { Major: 2, Minor: 6, Patch: 2 } // Do NOT modify format - version numbers are programmatically changed when releasing new versions - MUST be on a separate line!
|
|
652
652
|
}
|
|
653
653
|
};
|
|
654
654
|
|
|
@@ -4473,6 +4473,14 @@ Fit.Controls.DirtyCheckAll = function(scope)
|
|
|
4473
4473
|
return result;
|
|
4474
4474
|
}
|
|
4475
4475
|
|
|
4476
|
+
// <container name="Fit._internal.ControlBase">
|
|
4477
|
+
// <member name="ReduceDocumentRootPollution" static="true" type="boolean">
|
|
4478
|
+
// Reduce use of document root to host elements such as
|
|
4479
|
+
// context menus, dialogs, widgets, etc., which are temporarily
|
|
4480
|
+
// visible when interacting with controls on the screen.
|
|
4481
|
+
// </member>
|
|
4482
|
+
// </container>
|
|
4483
|
+
Fit._internal.ControlBase.ReduceDocumentRootPollution = true;
|
|
4476
4484
|
/// <container name="Fit.Cookies">
|
|
4477
4485
|
/// Cookie functionality.
|
|
4478
4486
|
/// Set/Get/Remove functions can be invoked as static members, or an instance of Fit.Cookies
|
|
@@ -9267,6 +9275,7 @@ Fit.Http.JsonpRequest = function(uri, jsonpCallbackName)
|
|
|
9267
9275
|
var timeout = 30000;
|
|
9268
9276
|
var timer = -1;
|
|
9269
9277
|
var response = null;
|
|
9278
|
+
var aborted = false;
|
|
9270
9279
|
|
|
9271
9280
|
var onRequestHandlers = [];
|
|
9272
9281
|
var onSuccessHandlers = [];
|
|
@@ -9324,6 +9333,14 @@ Fit.Http.JsonpRequest = function(uri, jsonpCallbackName)
|
|
|
9324
9333
|
return timeout;
|
|
9325
9334
|
}
|
|
9326
9335
|
|
|
9336
|
+
/// <function container="Fit.Http.JsonpRequest" name="Abort" access="public">
|
|
9337
|
+
/// <description> Abort request </description>
|
|
9338
|
+
/// </function>
|
|
9339
|
+
this.Abort = function()
|
|
9340
|
+
{
|
|
9341
|
+
aborted = true;
|
|
9342
|
+
}
|
|
9343
|
+
|
|
9327
9344
|
/// <function container="Fit.Http.JsonpRequest" name="SetParameter" access="public">
|
|
9328
9345
|
/// <description> Set URL parameter </description>
|
|
9329
9346
|
/// <param name="key" type="string"> URL parameter key </param>
|
|
@@ -9373,6 +9390,8 @@ Fit.Http.JsonpRequest = function(uri, jsonpCallbackName)
|
|
|
9373
9390
|
/// </function>
|
|
9374
9391
|
this.Start = function()
|
|
9375
9392
|
{
|
|
9393
|
+
aborted = false;
|
|
9394
|
+
|
|
9376
9395
|
// Fire OnRequest handlers
|
|
9377
9396
|
|
|
9378
9397
|
if (fireEvent(onRequestHandlers) === false)
|
|
@@ -9406,7 +9425,10 @@ Fit.Http.JsonpRequest = function(uri, jsonpCallbackName)
|
|
|
9406
9425
|
response = resp;
|
|
9407
9426
|
delete Fit._internal.Http.JsonpRequest.Callbacks[cbId];
|
|
9408
9427
|
|
|
9409
|
-
|
|
9428
|
+
if (aborted === false)
|
|
9429
|
+
{
|
|
9430
|
+
fireEvent(onSuccessHandlers);
|
|
9431
|
+
}
|
|
9410
9432
|
}
|
|
9411
9433
|
|
|
9412
9434
|
// Configure timeout
|
|
@@ -9419,7 +9441,10 @@ Fit.Http.JsonpRequest = function(uri, jsonpCallbackName)
|
|
|
9419
9441
|
// NOTICE: Do not remove callback - it would cause a JavaScript error if the situation described above occures.
|
|
9420
9442
|
Fit._internal.Http.JsonpRequest.Callbacks[cbId] = function(response) { };
|
|
9421
9443
|
|
|
9422
|
-
|
|
9444
|
+
if (aborted === false)
|
|
9445
|
+
{
|
|
9446
|
+
fireEvent(onTimeoutHandlers);
|
|
9447
|
+
}
|
|
9423
9448
|
}, timeout);
|
|
9424
9449
|
|
|
9425
9450
|
// Construct request URL
|
|
@@ -14233,6 +14258,11 @@ Fit.Controls.DatePicker = function(ctlId)
|
|
|
14233
14258
|
|
|
14234
14259
|
function moveCalenderWidgetLocally()
|
|
14235
14260
|
{
|
|
14261
|
+
if (Fit._internal.ControlBase.ReduceDocumentRootPollution !== true)
|
|
14262
|
+
{
|
|
14263
|
+
return;
|
|
14264
|
+
}
|
|
14265
|
+
|
|
14236
14266
|
// We want the benefits of a connected calendar control (connected to input control),
|
|
14237
14267
|
// but do not want it rendered in the root of the document. It pollutes the global scope,
|
|
14238
14268
|
// and it doesn't work with dialogs with light dismiss, since interacting with the calendar
|
|
@@ -14308,6 +14338,11 @@ Fit.Controls.DatePicker = function(ctlId)
|
|
|
14308
14338
|
|
|
14309
14339
|
function moveCalenderWidgetGlobally() // Undo everything done in moveCalenderWidgetLocally()
|
|
14310
14340
|
{
|
|
14341
|
+
if (Fit._internal.ControlBase.ReduceDocumentRootPollution !== true)
|
|
14342
|
+
{
|
|
14343
|
+
return;
|
|
14344
|
+
}
|
|
14345
|
+
|
|
14311
14346
|
var calendarWidget = document.getElementById("fitui-datepicker-div");
|
|
14312
14347
|
Fit.Dom.Add(document.body, calendarWidget);
|
|
14313
14348
|
|
|
@@ -21585,6 +21620,9 @@ Fit.Controls.Input = function(ctlId)
|
|
|
21585
21620
|
var designEditor = null;
|
|
21586
21621
|
var designEditorDirty = false;
|
|
21587
21622
|
var designEditorDirtyPending = false;
|
|
21623
|
+
var designEditorConfig = null;
|
|
21624
|
+
var designEditorRestoreButtonState = null;
|
|
21625
|
+
var designEditorSuppressPaste = false;
|
|
21588
21626
|
//var htmlWrappedInParagraph = false;
|
|
21589
21627
|
var wasAutoChangedToMultiLineMode = false; // Used to revert to single line if multi line was automatically enabled along with DesignMode(true), Maximizable(true), or Resizable(true)
|
|
21590
21628
|
var minimizeHeight = -1;
|
|
@@ -21678,6 +21716,21 @@ Fit.Controls.Input = function(ctlId)
|
|
|
21678
21716
|
}
|
|
21679
21717
|
|
|
21680
21718
|
fireOnChange(); // Only fires OnChange if value has actually changed
|
|
21719
|
+
|
|
21720
|
+
// Restore editor's toolbar buttons in case they were temporarily disabled
|
|
21721
|
+
|
|
21722
|
+
if (designEditor !== null)
|
|
21723
|
+
{
|
|
21724
|
+
restoreDesignEditorButtons();
|
|
21725
|
+
}
|
|
21726
|
+
});
|
|
21727
|
+
|
|
21728
|
+
Fit.Events.AddHandler(me.GetDomElement(), "paste", true, function(e)
|
|
21729
|
+
{
|
|
21730
|
+
if (designEditor !== null && designEditorSuppressPaste === true)
|
|
21731
|
+
{
|
|
21732
|
+
Fit.Events.Stop(e);
|
|
21733
|
+
}
|
|
21681
21734
|
});
|
|
21682
21735
|
|
|
21683
21736
|
try
|
|
@@ -21850,7 +21903,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
21850
21903
|
input.value = val;
|
|
21851
21904
|
}
|
|
21852
21905
|
|
|
21853
|
-
if (
|
|
21906
|
+
if (designEditorConfig !== null && designEditorConfig.Plugins && designEditorConfig.Plugins.Images && designEditorConfig.Plugins.Images.RevokeExternalBlobUrlsOnDispose === true)
|
|
21854
21907
|
{
|
|
21855
21908
|
// Keep track of image blobs added via Value(..) so we can dispose them automatically.
|
|
21856
21909
|
// When RevokeExternalBlobUrlsOnDispose is True it basically means that the Input control
|
|
@@ -21952,7 +22005,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
21952
22005
|
{
|
|
21953
22006
|
// This will destroy control - it will no longer work!
|
|
21954
22007
|
|
|
21955
|
-
var curVal =
|
|
22008
|
+
var curVal = designEditorConfig !== null && designEditorConfig.Plugins && designEditorConfig.Plugins.Images && designEditorConfig.Plugins.Images.RevokeBlobUrlsOnDispose === "UnreferencedOnly" ? me.Value() : null;
|
|
21956
22009
|
|
|
21957
22010
|
if (Fit._internal.Controls.Input.ActiveEditorForDialog === me)
|
|
21958
22011
|
{
|
|
@@ -22020,7 +22073,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22020
22073
|
debouncedOnChange.Cancel();
|
|
22021
22074
|
}
|
|
22022
22075
|
|
|
22023
|
-
if (
|
|
22076
|
+
if (designEditorConfig === null || !designEditorConfig.Plugins || !designEditorConfig.Plugins.Images || !designEditorConfig.Plugins.Images.RevokeBlobUrlsOnDispose || designEditorConfig.Plugins.Images.RevokeBlobUrlsOnDispose === "All")
|
|
22024
22077
|
{
|
|
22025
22078
|
Fit.Array.ForEach(imageBlobUrls, function(imageUrl)
|
|
22026
22079
|
{
|
|
@@ -22038,7 +22091,7 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22038
22091
|
});
|
|
22039
22092
|
}
|
|
22040
22093
|
|
|
22041
|
-
me = orgVal = preVal = input = cmdResize = designEditor = designEditorDirty = designEditorDirtyPending /*= htmlWrappedInParagraph*/ = wasAutoChangedToMultiLineMode = minimizeHeight = maximizeHeight = minMaxUnit = resizable = nativeResizableAvailable = mutationObserverId = rootedEventId = createWhenReadyIntervalId = isIe8 = debounceOnChangeTimeout = debouncedOnChange = imageBlobUrls = null;
|
|
22094
|
+
me = orgVal = preVal = input = cmdResize = designEditor = designEditorDirty = designEditorDirtyPending = designEditorConfig = designEditorRestoreButtonState = designEditorSuppressPaste /*= htmlWrappedInParagraph*/ = wasAutoChangedToMultiLineMode = minimizeHeight = maximizeHeight = minMaxUnit = resizable = nativeResizableAvailable = mutationObserverId = rootedEventId = createWhenReadyIntervalId = isIe8 = debounceOnChangeTimeout = debouncedOnChange = imageBlobUrls = null;
|
|
22042
22095
|
|
|
22043
22096
|
base();
|
|
22044
22097
|
});
|
|
@@ -22499,16 +22552,220 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22499
22552
|
return (cmdResize !== null && Fit.Dom.HasClass(cmdResize, "fa-chevron-up") === true);
|
|
22500
22553
|
}
|
|
22501
22554
|
|
|
22555
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeConfigPluginsImagesConfig">
|
|
22556
|
+
/// <description> Configuration for image plugins </description>
|
|
22557
|
+
/// <member name="Enabled" type="boolean"> Flag indicating whether to enable image plugins or not (defaults to False) </member>
|
|
22558
|
+
/// <member name="EmbedType" type="'base64' | 'blob'" default="undefined">
|
|
22559
|
+
/// How to store and embed images. Base64 is persistent while blob (default) is temporary
|
|
22560
|
+
/// and must be extracted from memory and uploaded/stored to be permanantly persisted.
|
|
22561
|
+
/// References to blobs can be parsed from the HTML value produced by the editor.
|
|
22562
|
+
/// </member>
|
|
22563
|
+
/// <member name="RevokeBlobUrlsOnDispose" type="'All' | 'UnreferencedOnly'" default="undefined">
|
|
22564
|
+
/// This option is in effect when EmbedType is blob.
|
|
22565
|
+
/// Dispose images from blob storage (revoke blob URLs) added though image plugins when control is disposed.
|
|
22566
|
+
/// If "UnreferencedOnly" is specified, the component using Fit.UI's input control will be responsible for
|
|
22567
|
+
/// disposing referenced blobs. Failing to do so may cause a memory leak. Defaults to All.
|
|
22568
|
+
/// </member>
|
|
22569
|
+
/// <member name="RevokeExternalBlobUrlsOnDispose" type="boolean" default="undefined">
|
|
22570
|
+
/// This option is in effect when EmbedType is blob.
|
|
22571
|
+
/// Dispose images from blob storage (revoke blob URLs) added through Value(..)
|
|
22572
|
+
/// function when control is disposed. Basically ownership of these blobs are handed
|
|
22573
|
+
/// over to the control for the duration of its life time.
|
|
22574
|
+
/// These images are furthermore subject to the rule set in RevokeBlobUrlsOnDispose.
|
|
22575
|
+
/// Defaults to False.
|
|
22576
|
+
/// </member>
|
|
22577
|
+
/// </container>
|
|
22578
|
+
|
|
22579
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeConfigPlugins">
|
|
22580
|
+
/// <description> Additional plugins enabled in DesignMode </description>
|
|
22581
|
+
/// <member name="Emojis" type="boolean" default="undefined"> Plugin(s) related to emoji support (defaults to False) </member>
|
|
22582
|
+
/// <member name="Images" type="Fit.Controls.InputTypeDefs.DesignModeConfigPluginsImagesConfig" default="undefined"> Plugin(s) related to support for images (defaults to False) </member>
|
|
22583
|
+
/// </container>
|
|
22584
|
+
|
|
22585
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeConfigToolbar">
|
|
22586
|
+
/// <description> Toolbar buttons enabled in DesignMode </description>
|
|
22587
|
+
/// <member name="Formatting" type="boolean" default="undefined"> Enable text formatting (bold, italic, underline) (defaults to True) </member>
|
|
22588
|
+
/// <member name="Justify" type="boolean" default="undefined"> Enable text alignment (defaults to True) </member>
|
|
22589
|
+
/// <member name="Lists" type="boolean" default="undefined"> Enable ordered and unordered lists with indentation (defaults to True) </member>
|
|
22590
|
+
/// <member name="Links" type="boolean" default="undefined"> Enable links (defaults to True) </member>
|
|
22591
|
+
/// <member name="Emojis" type="boolean" default="undefined"> Enable emoji button (defaults to False) </member>
|
|
22592
|
+
/// <member name="Images" type="boolean" default="undefined"> Enable image button (defaults to false) </member>
|
|
22593
|
+
/// </container>
|
|
22594
|
+
|
|
22595
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeConfigInfoPanel">
|
|
22596
|
+
/// <description> Information panel at the bottom of the editor </description>
|
|
22597
|
+
/// <member name="Text" type="string" default="undefined"> Text to display </member>
|
|
22598
|
+
/// <member name="Alignment" type="'Left' | 'Center' | 'Right'" default="undefined"> Text alignment - defaults to Center </member>
|
|
22599
|
+
/// </container>
|
|
22600
|
+
|
|
22601
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeTagsOnRequestEventHandlerArgs">
|
|
22602
|
+
/// <description> Request handler event arguments </description>
|
|
22603
|
+
/// <member name="Sender" type="Fit.Controls.Input"> Instance of control </member>
|
|
22604
|
+
/// <member name="Request" type="Fit.Http.JsonRequest | Fit.Http.JsonpRequest"> Instance of JsonRequest or JsonpRequest </member>
|
|
22605
|
+
/// <member name="Query" type="{ Marker: string, Query: string }"> Query information </member>
|
|
22606
|
+
/// </container>
|
|
22607
|
+
/// <function container="Fit.Controls.InputTypeDefs" name="DesignModeTagsOnRequest" returns="boolean | void">
|
|
22608
|
+
/// <description> Cancelable request event handler </description>
|
|
22609
|
+
/// <param name="sender" type="Fit.Controls.Input"> Instance of control </param>
|
|
22610
|
+
/// <param name="eventArgs" type="Fit.Controls.InputTypeDefs.DesignModeTagsOnRequestEventHandlerArgs"> Event arguments </param>
|
|
22611
|
+
/// </function>
|
|
22612
|
+
|
|
22613
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeTagsOnResponseJsonTag">
|
|
22614
|
+
/// <description> JSON object representing tag </description>
|
|
22615
|
+
/// <member name="Value" type="string"> Unique value </member>
|
|
22616
|
+
/// <member name="Title" type="string"> Title </member>
|
|
22617
|
+
/// <member name="Icon" type="string" default="undefined"> Optional URL to icon/image </member>
|
|
22618
|
+
/// <member name="Url" type="string" default="undefined"> Optional URL to associate with tag </member>
|
|
22619
|
+
/// <member name="Data" type="string" default="undefined"> Optional data to associate with tag </member>
|
|
22620
|
+
/// </container>
|
|
22621
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeTagsOnResponseEventHandlerArgs">
|
|
22622
|
+
/// <description> Response handler event arguments </description>
|
|
22623
|
+
/// <member name="Sender" type="Fit.Controls.Input"> Instance of control </member>
|
|
22624
|
+
/// <member name="Request" type="Fit.Http.JsonRequest | Fit.Http.JsonpRequest"> Instance of JsonRequest or JsonpRequest </member>
|
|
22625
|
+
/// <member name="Query" type="{ Marker: string, Query: string }"> Query information </member>
|
|
22626
|
+
/// <member name="Tags" type="Fit.Controls.InputTypeDefs.DesignModeTagsOnResponseJsonTag[]"> Tags received from WebService </member>
|
|
22627
|
+
/// </container>
|
|
22628
|
+
/// <function container="Fit.Controls.InputTypeDefs" name="DesignModeTagsOnResponse">
|
|
22629
|
+
/// <description> Response event handler </description>
|
|
22630
|
+
/// <param name="sender" type="Fit.Controls.Input"> Instance of control </param>
|
|
22631
|
+
/// <param name="eventArgs" type="Fit.Controls.InputTypeDefs.DesignModeTagsOnResponseEventHandlerArgs"> Event arguments </param>
|
|
22632
|
+
/// </function>
|
|
22633
|
+
|
|
22634
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeTagsTagCreatorReturnType">
|
|
22635
|
+
/// <description> JSON object representing tag to be inserted into editor </description>
|
|
22636
|
+
/// <member name="Title" type="string"> Tag title </member>
|
|
22637
|
+
/// <member name="Value" type="string"> Tag value (ID) </member>
|
|
22638
|
+
/// <member name="Type" type="string"> Tag type (marker) </member>
|
|
22639
|
+
/// <member name="Url" type="string" default="undefined"> Optional tag URL </member>
|
|
22640
|
+
/// <member name="Data" type="string" default="undefined"> Optional tag data </member>
|
|
22641
|
+
/// </container>
|
|
22642
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeTagsTagCreatorCallbackArgs">
|
|
22643
|
+
/// <description> TagCreator event arguments </description>
|
|
22644
|
+
/// <member name="Sender" type="Fit.Controls.Input"> Instance of control </member>
|
|
22645
|
+
/// <member name="QueryMarker" type="string"> Query marker </member>
|
|
22646
|
+
/// <member name="Tag" type="Fit.Controls.InputTypeDefs.DesignModeTagsOnResponseJsonTag"> Tag received from WebService </member>
|
|
22647
|
+
/// </container>
|
|
22648
|
+
/// <function container="Fit.Controls.InputTypeDefs" name="DesignModeTagsTagCreator" returns="Fit.Controls.InputTypeDefs.DesignModeTagsTagCreatorReturnType | null | void">
|
|
22649
|
+
/// <description>
|
|
22650
|
+
/// Function producing JSON object representing tag to be inserted into editor.
|
|
22651
|
+
/// Returning nothing or Null results in default tag being inserted into editor.
|
|
22652
|
+
/// </description>
|
|
22653
|
+
/// <param name="sender" type="Fit.Controls.Input"> Instance of control </param>
|
|
22654
|
+
/// <param name="eventArgs" type="Fit.Controls.InputTypeDefs.DesignModeTagsTagCreatorCallbackArgs"> Event arguments </param>
|
|
22655
|
+
/// </function>
|
|
22656
|
+
|
|
22657
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeConfigTags">
|
|
22658
|
+
/// <description> Configuration for tags in DesignMode </description>
|
|
22659
|
+
/// <member name="Triggers" type="{ Marker: string, MinimumCharacters?: integer, DebounceQuery?: integer }[]"> Markers triggering tags request and context menu </member>
|
|
22660
|
+
/// <member name="QueryUrl" type="string">
|
|
22661
|
+
/// URL to request data from. Endpoint receives the following payload:
|
|
22662
|
+
/// { Marker: "@", Query: "search" }
|
|
22663
|
+
///
|
|
22664
|
+
/// Data is expected to be returned in the following format:
|
|
22665
|
+
/// [
|
|
22666
|
+
/// { Value: "t-1", Title: "Tag 1", Icon: "images/img1.jpeg", Url: "show/1", Data: "..." },
|
|
22667
|
+
/// { Value: "t-2", Title: "Tag 2", Icon: "images/img2.jpeg", Url: "show/2", Data: "..." }, ...
|
|
22668
|
+
/// ]
|
|
22669
|
+
///
|
|
22670
|
+
/// The Value and Title properties are required. The Icon property is optional and must specify the path to an image.
|
|
22671
|
+
/// The Url property is optional and must specify a path to a related page/resource.
|
|
22672
|
+
/// The Data property is optional and allows for additional data to be associated with the tag.
|
|
22673
|
+
/// To hold multiple values, consider using a base64 encoded JSON object:
|
|
22674
|
+
/// btoa(JSON.stringify({ creationDate: new Date(), active: true }))
|
|
22675
|
+
///
|
|
22676
|
+
/// The data eventuelly results in a tag being added to the editor with the following format:
|
|
22677
|
+
/// <a data-tag-type="@" data-tag-id="unique id 1" data-tag-data="..." href="show/1">Tag name 1</a>
|
|
22678
|
+
/// The data-tag-data attribute is only declared if the corresponding Data property is defined in data.
|
|
22679
|
+
/// </member>
|
|
22680
|
+
/// <member name="JsonpCallback" type="string" default="undefined"> Name of URL parameter receiving name of JSONP callback function (only for JSONP services) </member>
|
|
22681
|
+
/// <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>
|
|
22682
|
+
/// <member name="OnRequest" type="Fit.Controls.InputTypeDefs.DesignModeTagsOnRequest" default="undefined">
|
|
22683
|
+
/// Event handler invoked when tags are requested. Request may be canceled by returning False.
|
|
22684
|
+
/// Function receives two arguments:
|
|
22685
|
+
/// Sender (Fit.Controls.Input) and EventArgs object.
|
|
22686
|
+
/// EventArgs object contains the following properties:
|
|
22687
|
+
/// - Sender: Fit.Controls.Input instance
|
|
22688
|
+
/// - Request: Fit.Http.JsonpRequest or Fit.Http.JsonRequest instance
|
|
22689
|
+
/// - Query: Contains query information in its Marker and Query property
|
|
22690
|
+
/// </member>
|
|
22691
|
+
/// <member name="OnResponse" type="Fit.Controls.InputTypeDefs.DesignModeTagsOnResponse" default="undefined">
|
|
22692
|
+
/// Event handler invoked when tags data is received, allowing for data transformation.
|
|
22693
|
+
/// Function receives two arguments:
|
|
22694
|
+
/// Sender (Fit.Controls.Input) and EventArgs object.
|
|
22695
|
+
/// EventArgs object contains the following properties:
|
|
22696
|
+
/// - Sender: Fit.Controls.Input instance
|
|
22697
|
+
/// - Request: Fit.Http.JsonpRequest or Fit.Http.JsonRequest instance
|
|
22698
|
+
/// - Query: Contains query information in its Marker and Query property
|
|
22699
|
+
/// - Tags: JSON tags array received from WebService
|
|
22700
|
+
/// </member>
|
|
22701
|
+
/// <member name="TagCreator" type="Fit.Controls.InputTypeDefs.DesignModeTagsTagCreator" default="undefined">
|
|
22702
|
+
/// Callback invoked when a tag is being inserted into editor, allowing
|
|
22703
|
+
/// for customization to the title and attributes associated with the tag.
|
|
22704
|
+
/// Function receives two arguments:
|
|
22705
|
+
/// Sender (Fit.Controls.Input) and EventArgs object.
|
|
22706
|
+
/// EventArgs object contains the following properties:
|
|
22707
|
+
/// - Sender: Fit.Controls.Input instance
|
|
22708
|
+
/// - QueryMarker: String containing query marker
|
|
22709
|
+
/// - Tag: JSON tag received from WebService
|
|
22710
|
+
/// </member>
|
|
22711
|
+
/// </container>
|
|
22712
|
+
|
|
22713
|
+
/// <container name="Fit.Controls.InputTypeDefs.DesignModeConfig">
|
|
22714
|
+
/// <description> Configuration for DesignMode </description>
|
|
22715
|
+
/// <member name="Plugins" type="Fit.Controls.InputTypeDefs.DesignModeConfigPlugins" default="undefined"> Plugins configuration </member>
|
|
22716
|
+
/// <member name="Toolbar" type="Fit.Controls.InputTypeDefs.DesignModeConfigToolbar" default="undefined"> Toolbar configuration </member>
|
|
22717
|
+
/// <member name="InfoPanel" type="Fit.Controls.InputTypeDefs.DesignModeConfigInfoPanel" default="undefined"> Information panel configuration </member>
|
|
22718
|
+
/// <member name="Tags" type="Fit.Controls.InputTypeDefs.DesignModeConfigTags" default="undefined"> Tags configuration </member>
|
|
22719
|
+
/// </container>
|
|
22720
|
+
|
|
22502
22721
|
/// <function container="Fit.Controls.Input" name="DesignMode" access="public" returns="boolean">
|
|
22503
22722
|
/// <description>
|
|
22504
22723
|
/// Get/set value indicating whether control is in Design Mode allowing for rich HTML content.
|
|
22505
22724
|
/// Notice that this control type requires dimensions (Width/Height) to be specified in pixels.
|
|
22506
22725
|
/// </description>
|
|
22507
22726
|
/// <param name="val" type="boolean" default="undefined"> If defined, True enables Design Mode, False disables it </param>
|
|
22727
|
+
/// <param name="editorConfig" type="Fit.Controls.InputTypeDefs.DesignModeConfig" default="undefined">
|
|
22728
|
+
/// If provided and DesignMode is enabled, configuration is applied when editor is created.
|
|
22729
|
+
/// </param>
|
|
22508
22730
|
/// </function>
|
|
22509
|
-
this.DesignMode = function(val)
|
|
22731
|
+
this.DesignMode = function(val, editorConfig)
|
|
22510
22732
|
{
|
|
22511
22733
|
Fit.Validation.ExpectBoolean(val, true);
|
|
22734
|
+
Fit.Validation.ExpectObject(editorConfig, true);
|
|
22735
|
+
Fit.Validation.ExpectObject((editorConfig || {}).Plugins, true);
|
|
22736
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Plugins || {}).Emojis, true);
|
|
22737
|
+
Fit.Validation.ExpectObject(((editorConfig || {}).Plugins || {}).Images, true);
|
|
22738
|
+
Fit.Validation.ExpectBoolean((((editorConfig || {}).Plugins || {}).Images || {}).Enabled, true);
|
|
22739
|
+
Fit.Validation.ExpectStringValue((((editorConfig || {}).Plugins || {}).Images || {}).EmbedType, true);
|
|
22740
|
+
Fit.Validation.ExpectStringValue((((editorConfig || {}).Plugins || {}).Images || {}).RevokeBlobUrlsOnDispose, true);
|
|
22741
|
+
Fit.Validation.ExpectBoolean((((editorConfig || {}).Plugins || {}).Images || {}).RevokeExternalBlobUrlsOnDispose, true);
|
|
22742
|
+
Fit.Validation.ExpectObject((editorConfig || {}).Toolbar, true);
|
|
22743
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Formatting, true);
|
|
22744
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Justify, true);
|
|
22745
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Lists, true);
|
|
22746
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Links, true);
|
|
22747
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Emojis, true);
|
|
22748
|
+
Fit.Validation.ExpectBoolean(((editorConfig || {}).Toolbar || {}).Images, true);
|
|
22749
|
+
Fit.Validation.ExpectObject((editorConfig || {}).InfoPanel, true);
|
|
22750
|
+
Fit.Validation.ExpectString(((editorConfig || {}).InfoPanel || {}).Text, true);
|
|
22751
|
+
Fit.Validation.ExpectString(((editorConfig || {}).InfoPanel || {}).Alignment, true);
|
|
22752
|
+
Fit.Validation.ExpectObject((editorConfig || {}).Tags, true);
|
|
22753
|
+
|
|
22754
|
+
if (editorConfig && editorConfig.Tags)
|
|
22755
|
+
{
|
|
22756
|
+
Fit.Validation.ExpectTypeArray(editorConfig.Tags.Triggers, function(trigger)
|
|
22757
|
+
{
|
|
22758
|
+
Fit.Validation.ExpectStringValue(trigger.Marker);
|
|
22759
|
+
Fit.Validation.ExpectInteger(trigger.MinimumCharacters, true);
|
|
22760
|
+
Fit.Validation.ExpectInteger(trigger.DebounceQuery, true);
|
|
22761
|
+
});
|
|
22762
|
+
Fit.Validation.ExpectStringValue(editorConfig.Tags.QueryUrl);
|
|
22763
|
+
Fit.Validation.ExpectStringValue(editorConfig.Tags.JsonpCallback, true);
|
|
22764
|
+
Fit.Validation.ExpectInteger(editorConfig.Tags.JsonpTimeout, true);
|
|
22765
|
+
Fit.Validation.ExpectFunction(editorConfig.Tags.OnRequest, true);
|
|
22766
|
+
Fit.Validation.ExpectFunction(editorConfig.Tags.OnResponse, true);
|
|
22767
|
+
Fit.Validation.ExpectFunction(editorConfig.Tags.TagCreator, true);
|
|
22768
|
+
}
|
|
22512
22769
|
|
|
22513
22770
|
if (Fit.Validation.IsSet(val) === true)
|
|
22514
22771
|
{
|
|
@@ -22519,6 +22776,11 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22519
22776
|
|
|
22520
22777
|
if (val === true && designMode === false)
|
|
22521
22778
|
{
|
|
22779
|
+
if (Fit.Validation.IsSet(editorConfig) === true)
|
|
22780
|
+
{
|
|
22781
|
+
designEditorConfig = editorConfig;
|
|
22782
|
+
}
|
|
22783
|
+
|
|
22522
22784
|
if (Fit._internal.Controls.Input.ActiveEditorForDialog === me)
|
|
22523
22785
|
{
|
|
22524
22786
|
// Control is actually already in Design Mode, but waiting
|
|
@@ -22633,23 +22895,26 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22633
22895
|
return;
|
|
22634
22896
|
}
|
|
22635
22897
|
|
|
22636
|
-
|
|
22637
|
-
|
|
22638
|
-
|
|
22639
|
-
|
|
22640
|
-
|
|
22641
|
-
|
|
22642
|
-
|
|
22643
|
-
|
|
22644
|
-
|
|
22645
|
-
|
|
22646
|
-
|
|
22647
|
-
|
|
22648
|
-
|
|
22649
|
-
|
|
22650
|
-
|
|
22651
|
-
|
|
22652
|
-
|
|
22898
|
+
if (Fit._internal.ControlBase.ReduceDocumentRootPollution === true)
|
|
22899
|
+
{
|
|
22900
|
+
// Move dialog to control - otherwise placed in the root of the document where it pollutes,
|
|
22901
|
+
// and makes it impossible to interact with the dialog in light dismissable panels and callouts.
|
|
22902
|
+
// Dialog is placed alongside control and not within the control's container, to prevent Fit.UI
|
|
22903
|
+
// styling from affecting the dialog.
|
|
22904
|
+
// DISABLED: It breaks file picker controls in dialogs which are hosted in iframes.
|
|
22905
|
+
// When an iframe is re-rooted in DOM it reloads, and any dynamically created content is lost.
|
|
22906
|
+
// We will have to increase the z-index to make sure dialogs open on top of modal layers.
|
|
22907
|
+
// EDIT 2021-08-20: Enabled again. The base64image plugin has now been altered so it no longer
|
|
22908
|
+
// uses CKEditor's built-in file picker which is wrapped in an iFrame. Therefore the dialog can
|
|
22909
|
+
// once again be mounted next to the Input control.
|
|
22910
|
+
|
|
22911
|
+
var ckeDialogElement = this.getElement().$;
|
|
22912
|
+
Fit.Dom.InsertAfter(Fit._internal.Controls.Input.ActiveEditorForDialog.GetDomElement(), ckeDialogElement);
|
|
22913
|
+
|
|
22914
|
+
// 2nd+ time dialog is opened it remains invisible - make it appear and position it
|
|
22915
|
+
ckeDialogElement.style.display = !CKEDITOR.env.ie || CKEDITOR.env.edge ? "flex" : ""; // https://github.com/ckeditor/ckeditor4/blob/8b208d05d1338d046cdc8f971c9faf21604dd75d/plugins/dialog/plugin.js#L152
|
|
22916
|
+
this.layout(); // 'this' is the dialog instance - layout() positions dialog
|
|
22917
|
+
}
|
|
22653
22918
|
});
|
|
22654
22919
|
|
|
22655
22920
|
dialog.on("hide", function(ev) // Fires when user closes dialog, or when hide() is called on dialog, or if destroy() is called on editor instance from Dispose() or DesignMode(false)
|
|
@@ -22921,6 +23186,278 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22921
23186
|
var langSupport = ["da", "de", "en"];
|
|
22922
23187
|
var locale = Fit.Internationalization.Locale().length === 2 ? Fit.Internationalization.Locale() : Fit.Internationalization.Locale().substring(0, 2);
|
|
22923
23188
|
var lang = Fit.Array.Contains(langSupport, locale) === true ? locale : "en";
|
|
23189
|
+
var plugins = [];
|
|
23190
|
+
var toolbar = [];
|
|
23191
|
+
var mentions = [];
|
|
23192
|
+
|
|
23193
|
+
var config = designEditorConfig || {};
|
|
23194
|
+
|
|
23195
|
+
// Enable additional plugins not compiled into CKEditor by default
|
|
23196
|
+
|
|
23197
|
+
if ((config.Plugins && config.Plugins.Emojis === true) || (config.Toolbar && config.Toolbar.Emojis === true))
|
|
23198
|
+
{
|
|
23199
|
+
Fit.Array.Add(plugins, "emoji");
|
|
23200
|
+
}
|
|
23201
|
+
|
|
23202
|
+
if ((config.Plugins && config.Plugins.Images && config.Plugins.Images.Enabled === true) || (config.Toolbar && config.Toolbar.Images === true))
|
|
23203
|
+
{
|
|
23204
|
+
if (config.Toolbar && config.Toolbar.Images === true)
|
|
23205
|
+
{
|
|
23206
|
+
Fit.Array.Add(plugins, "base64image");
|
|
23207
|
+
}
|
|
23208
|
+
|
|
23209
|
+
plugins = Fit.Array.Merge(plugins, ["base64imagepaste", "dragresize"]);
|
|
23210
|
+
}
|
|
23211
|
+
|
|
23212
|
+
// Add toolbar buttons
|
|
23213
|
+
|
|
23214
|
+
if (!config.Toolbar || config.Toolbar.Formatting !== false)
|
|
23215
|
+
{
|
|
23216
|
+
Fit.Array.Add(toolbar,
|
|
23217
|
+
{
|
|
23218
|
+
name: "BasicFormatting",
|
|
23219
|
+
items: [ "Bold", "Italic", "Underline" ]
|
|
23220
|
+
});
|
|
23221
|
+
}
|
|
23222
|
+
|
|
23223
|
+
if (!config.Toolbar || config.Toolbar.Justify !== false)
|
|
23224
|
+
{
|
|
23225
|
+
Fit.Array.Add(toolbar,
|
|
23226
|
+
{
|
|
23227
|
+
name: "Justify",
|
|
23228
|
+
items: [ "JustifyLeft", "JustifyCenter", "JustifyRight" ]
|
|
23229
|
+
});
|
|
23230
|
+
}
|
|
23231
|
+
|
|
23232
|
+
if (!config.Toolbar || config.Toolbar.Lists !== false)
|
|
23233
|
+
{
|
|
23234
|
+
Fit.Array.Add(toolbar,
|
|
23235
|
+
{
|
|
23236
|
+
name: "Lists",
|
|
23237
|
+
items: [ "NumberedList", "BulletedList", "Indent", "Outdent" ]
|
|
23238
|
+
});
|
|
23239
|
+
}
|
|
23240
|
+
|
|
23241
|
+
if (!config.Toolbar || config.Toolbar.Links !== false)
|
|
23242
|
+
{
|
|
23243
|
+
Fit.Array.Add(toolbar,
|
|
23244
|
+
{
|
|
23245
|
+
name: "Links",
|
|
23246
|
+
items: [ "Link", "Unlink" ]
|
|
23247
|
+
});
|
|
23248
|
+
}
|
|
23249
|
+
|
|
23250
|
+
if (config.Toolbar)
|
|
23251
|
+
{
|
|
23252
|
+
var insert = [];
|
|
23253
|
+
|
|
23254
|
+
if (config.Toolbar.Emojis === true)
|
|
23255
|
+
{
|
|
23256
|
+
Fit.Array.Add(insert, "EmojiPanel");
|
|
23257
|
+
}
|
|
23258
|
+
|
|
23259
|
+
if (config.Toolbar.Images === true)
|
|
23260
|
+
{
|
|
23261
|
+
Fit.Array.Add(insert, "base64image");
|
|
23262
|
+
}
|
|
23263
|
+
|
|
23264
|
+
if (insert.length > 0)
|
|
23265
|
+
{
|
|
23266
|
+
Fit.Array.Add(toolbar,
|
|
23267
|
+
{
|
|
23268
|
+
name: "Insert",
|
|
23269
|
+
items: insert
|
|
23270
|
+
});
|
|
23271
|
+
}
|
|
23272
|
+
}
|
|
23273
|
+
|
|
23274
|
+
// Configure tags/mentions plugin
|
|
23275
|
+
|
|
23276
|
+
if (config.Tags)
|
|
23277
|
+
{
|
|
23278
|
+
var requestAwaiting = null;
|
|
23279
|
+
|
|
23280
|
+
var createEventArgs = function(marker, query, request) // EventsArgs for OnRequest and OnResponse
|
|
23281
|
+
{
|
|
23282
|
+
return { Sender: me, Query: { Marker: marker, Query: query }, Request: request };
|
|
23283
|
+
};
|
|
23284
|
+
|
|
23285
|
+
Fit.Array.ForEach(config.Tags.Triggers, function(trigger)
|
|
23286
|
+
{
|
|
23287
|
+
var mention =
|
|
23288
|
+
{
|
|
23289
|
+
marker: trigger.Marker,
|
|
23290
|
+
minChars: trigger.MinimumCharacters || 0,
|
|
23291
|
+
throttle: 0, // Throttling is not debouncing - it merely ensures that no more than 1 request is made every X milliseconds when value is changed (defaults to 200ms) - real debouncing implemented further down, which reduce and cancel network calls as user types - also a work around for https://github.com/ckeditor/ckeditor4/issues/5036
|
|
23292
|
+
feed: function(args, resolve)
|
|
23293
|
+
{
|
|
23294
|
+
// WebService is expected to return tag items in an array like so:
|
|
23295
|
+
// [ { Title: string, Value: string, Icon?: string, Url?: string, Data?: string }, { ... }, ... ]
|
|
23296
|
+
|
|
23297
|
+
var req = null;
|
|
23298
|
+
|
|
23299
|
+
if (config.Tags.JsonpCallback)
|
|
23300
|
+
{
|
|
23301
|
+
req = new Fit.Http.JsonpRequest(config.Tags.QueryUrl, config.Tags.JsonpCallback);
|
|
23302
|
+
config.Tags.JsonpTimeout && req.Timeout(config.Tags.JsonpTimeout);
|
|
23303
|
+
req.SetParameter("Marker", args.marker);
|
|
23304
|
+
req.SetParameter("Query", args.query);
|
|
23305
|
+
}
|
|
23306
|
+
else
|
|
23307
|
+
{
|
|
23308
|
+
req = new Fit.Http.JsonRequest(config.Tags.QueryUrl);
|
|
23309
|
+
req.SetData({ Marker: args.marker, Query: args.query });
|
|
23310
|
+
}
|
|
23311
|
+
|
|
23312
|
+
if (config.Tags.OnRequest)
|
|
23313
|
+
{
|
|
23314
|
+
var eventArgs = createEventArgs(args.marker, args.query, req);
|
|
23315
|
+
|
|
23316
|
+
if (config.Tags.OnRequest(me, eventArgs) === false)
|
|
23317
|
+
{
|
|
23318
|
+
resolve([]);
|
|
23319
|
+
return;
|
|
23320
|
+
}
|
|
23321
|
+
|
|
23322
|
+
if (eventArgs.Request !== req)
|
|
23323
|
+
{
|
|
23324
|
+
// Support for changing request instans to
|
|
23325
|
+
// take control over webservice communication.
|
|
23326
|
+
|
|
23327
|
+
// Restrict to support for Fit.Http.Request or classes derived from this
|
|
23328
|
+
Fit.Validation.ExpectInstance(eventArgs.Request, Fit.Http.Request);
|
|
23329
|
+
|
|
23330
|
+
req = eventArgs.Request;
|
|
23331
|
+
}
|
|
23332
|
+
}
|
|
23333
|
+
|
|
23334
|
+
var processDataAndResolve = function(items)
|
|
23335
|
+
{
|
|
23336
|
+
if (config.Tags.OnResponse) // OnResponse is allowed to manipulate tags
|
|
23337
|
+
{
|
|
23338
|
+
var eventArgs = Fit.Core.Merge(createEventArgs(args.marker, args.query, req), { Tags: items });
|
|
23339
|
+
config.Tags.OnResponse(me, eventArgs);
|
|
23340
|
+
|
|
23341
|
+
items = eventArgs.Tags; // In case OnResponse event handler assigned new collection
|
|
23342
|
+
}
|
|
23343
|
+
|
|
23344
|
+
Fit.Array.ForEach(items, function(item)
|
|
23345
|
+
{
|
|
23346
|
+
// Set properties required by mentions plugin
|
|
23347
|
+
item.id = item.Value;
|
|
23348
|
+
item.name = item.Title;
|
|
23349
|
+
});
|
|
23350
|
+
|
|
23351
|
+
resolve(items);
|
|
23352
|
+
|
|
23353
|
+
if (items.length > 0 && Fit._internal.ControlBase.ReduceDocumentRootPollution === true)
|
|
23354
|
+
{
|
|
23355
|
+
// Calling resolve(..) above immediately opens the context menu from which
|
|
23356
|
+
// a tag can be selected. However, it is placed in the root of the document
|
|
23357
|
+
// where it pollutes the global scope. Move it next to the Fit.UI control.
|
|
23358
|
+
// We do not mount it within the Fit.UI control as it could cause Fit.UI styles
|
|
23359
|
+
// to take effect on the context menu.
|
|
23360
|
+
|
|
23361
|
+
// Get the autocomplete context menu currently open. There can be only one
|
|
23362
|
+
// such menu open at any time. Each editor can declare multiple autocomplete
|
|
23363
|
+
// context menus since each tag marker is associated with its own context menu.
|
|
23364
|
+
var ctm = document.querySelector("ul.cke_autocomplete_opened");
|
|
23365
|
+
ctm.style.position = "fixed"; // Has position:absolute by default, but this may be affected by a positioned container (offsetParent) - downside: it no longer sticks to the editor when scrolling
|
|
23366
|
+
Fit.Dom.InsertAfter(me.GetDomElement(), ctm);
|
|
23367
|
+
}
|
|
23368
|
+
};
|
|
23369
|
+
|
|
23370
|
+
if (Fit.Core.InstanceOf(req, Fit.Http.JsonpRequest) === true)
|
|
23371
|
+
{
|
|
23372
|
+
req.OnSuccess(function(sender)
|
|
23373
|
+
{
|
|
23374
|
+
var response = req.GetResponse();
|
|
23375
|
+
var items = ((response instanceof Array) ? response : []);
|
|
23376
|
+
|
|
23377
|
+
processDataAndResolve(items);
|
|
23378
|
+
});
|
|
23379
|
+
|
|
23380
|
+
req.OnTimeout(function(sender)
|
|
23381
|
+
{
|
|
23382
|
+
resolve([]);
|
|
23383
|
+
Fit.Validation.ThrowError("Unable to get tags - request did not return data in time (JSONP timeout reached)");
|
|
23384
|
+
});
|
|
23385
|
+
}
|
|
23386
|
+
else
|
|
23387
|
+
{
|
|
23388
|
+
req.OnSuccess(function(sender)
|
|
23389
|
+
{
|
|
23390
|
+
var response = req.GetResponseJson();
|
|
23391
|
+
var items = ((response instanceof Array) ? response : []);
|
|
23392
|
+
|
|
23393
|
+
processDataAndResolve(items);
|
|
23394
|
+
});
|
|
23395
|
+
|
|
23396
|
+
req.OnFailure(function(sender)
|
|
23397
|
+
{
|
|
23398
|
+
resolve([]);
|
|
23399
|
+
Fit.Validation.ThrowError("Unable to get tags - request failed with HTTP Status code " + req.GetHttpStatus());
|
|
23400
|
+
});
|
|
23401
|
+
}
|
|
23402
|
+
|
|
23403
|
+
if (requestAwaiting !== null)
|
|
23404
|
+
{
|
|
23405
|
+
requestAwaiting.Abort();
|
|
23406
|
+
}
|
|
23407
|
+
|
|
23408
|
+
requestAwaiting = req;
|
|
23409
|
+
req.Start();
|
|
23410
|
+
},
|
|
23411
|
+
itemTemplate: function(item) // Item must define "name" and "id" properties - the {name} placeholder is replaced by "@" + the value of the "name" property - to get rid of "@" simply use an alternative property such as nameWithoutTag:"Some username"
|
|
23412
|
+
{
|
|
23413
|
+
if (item.Icon)
|
|
23414
|
+
{
|
|
23415
|
+
return '<li data-id="' + item.Value + '"><img src="' + item.Icon + '" style="width: 24px; height: 24px; border-radius: 24px; vertical-align: middle" alt=""><span style="display: inline-block; width: 150px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: middle; margin-left: 5px">' + item.Title + '</span></li>';
|
|
23416
|
+
}
|
|
23417
|
+
else
|
|
23418
|
+
{
|
|
23419
|
+
return '<li data-id="' + item.Value + '">' + item.Title + '</li>';
|
|
23420
|
+
}
|
|
23421
|
+
},
|
|
23422
|
+
outputTemplate: function(item)
|
|
23423
|
+
{
|
|
23424
|
+
// IMPORTANT: Output produced must respect ACF (Advanced Content Filter).
|
|
23425
|
+
// So the tag produced must be allowed, and any attributes contained must be allowed.
|
|
23426
|
+
|
|
23427
|
+
var alternativeItem = null;
|
|
23428
|
+
|
|
23429
|
+
if (config.Tags.TagCreator)
|
|
23430
|
+
{
|
|
23431
|
+
var callbackArgs = { Sender: me, QueryMarker: trigger.Marker, Tag: Fit.Core.Clone(item) };
|
|
23432
|
+
alternativeItem = config.Tags.TagCreator(me, callbackArgs) || null;
|
|
23433
|
+
}
|
|
23434
|
+
|
|
23435
|
+
// Function should return a link for tags to "just work". Returning a <span> requires the span to be whitelisted in
|
|
23436
|
+
// extraAllowedContent configuration, but even then the editor will continue writing text within the <span> element,
|
|
23437
|
+
// rather than next to it. So one would expect something like: We will assign <span data-tag-type="@" ..>@James Bond</span> to this mission.
|
|
23438
|
+
// But what we get instead is something like: We will assign <span data-tag-type="@" ..>@James Bond to this mission</span>.
|
|
23439
|
+
// The same happens to link tags if the href attribute is removed, which is why we always add it, even when no URL is defined.
|
|
23440
|
+
|
|
23441
|
+
if (alternativeItem !== null)
|
|
23442
|
+
{
|
|
23443
|
+
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>';
|
|
23444
|
+
}
|
|
23445
|
+
else
|
|
23446
|
+
{
|
|
23447
|
+
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>';
|
|
23448
|
+
}
|
|
23449
|
+
}
|
|
23450
|
+
};
|
|
23451
|
+
|
|
23452
|
+
if (trigger.DebounceQuery !== 0) // A value of 0 (zero) disables debouncing
|
|
23453
|
+
{
|
|
23454
|
+
// Wrap feed handler in debounce function so that every time it gets invoked, it cancels the previous invocation
|
|
23455
|
+
mention.feed = Fit.Core.CreateDebouncer(mention.feed, trigger.DebounceQuery || 300).Invoke;
|
|
23456
|
+
}
|
|
23457
|
+
|
|
23458
|
+
Fit.Array.Add(mentions, mention)
|
|
23459
|
+
});
|
|
23460
|
+
}
|
|
22924
23461
|
|
|
22925
23462
|
// Prevent control from losing focus when HTML editor is initialized,
|
|
22926
23463
|
// e.g. if Design Mode is enabled when ordinary input control gains focus.
|
|
@@ -22974,50 +23511,30 @@ Fit.Controls.Input = function(ctlId)
|
|
|
22974
23511
|
designEditor = CKEDITOR.replace(me.GetId() + "_DesignMode",
|
|
22975
23512
|
{
|
|
22976
23513
|
//allowedContent: true, // http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules and http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent
|
|
23514
|
+
extraAllowedContent: "a[data-tag-type,data-tag-id,data-tag-data]", // https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-extraAllowedContent
|
|
22977
23515
|
language: lang,
|
|
22978
23516
|
disableNativeSpellChecker: me.CheckSpelling() === false,
|
|
22979
23517
|
readOnly: me.Enabled() === false,
|
|
22980
23518
|
tabIndex: me.Enabled() === false ? -1 : 0,
|
|
22981
23519
|
title: "",
|
|
22982
23520
|
startupFocus: focused === true ? "end" : false,
|
|
22983
|
-
extraPlugins:
|
|
23521
|
+
extraPlugins: plugins.join(","),
|
|
22984
23522
|
clipboard_handleImages: false, // Disable native support for image pasting - allow base64imagepaste plugin to handle image data if loaded
|
|
22985
23523
|
base64image: // Custom property used by base64image plugin if loaded
|
|
22986
23524
|
{
|
|
22987
|
-
storage: "blob", // "base64" (default) or "blob" - base64 will always be provided by browsers not supporting blob storage
|
|
23525
|
+
storage: designEditorConfig !== null && designEditorConfig.Plugins && designEditorConfig.Plugins.Images && designEditorConfig.Plugins.Images.EmbedType === "blob" ? "blob" : "base64", // "base64" (default) or "blob" - base64 will always be provided by browsers not supporting blob storage
|
|
22988
23526
|
onImageAdded: onImageAdded
|
|
22989
23527
|
},
|
|
22990
23528
|
base64imagepaste: // Custom property used by base64imagepaste plugin if loaded - notice that IE has native support for image pasting as base64 so plugin is not triggered in IE
|
|
22991
23529
|
{
|
|
22992
|
-
storage: "blob", // "base64" (default) or "blob" - base64 will always be provided by browsers not supporting blob storage
|
|
23530
|
+
storage: designEditorConfig !== null && designEditorConfig.Plugins && designEditorConfig.Plugins.Images && designEditorConfig.Plugins.Images.EmbedType === "blob" ? "blob" : "base64", // "base64" (default) or "blob" - base64 will always be provided by browsers not supporting blob storage
|
|
22993
23531
|
onImageAdded: onImageAdded
|
|
22994
23532
|
},
|
|
22995
23533
|
resize_enabled: resizable !== Fit.Controls.InputResizing.Disabled,
|
|
22996
23534
|
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)
|
|
22997
|
-
toolbar:
|
|
22998
|
-
/*[
|
|
22999
|
-
{
|
|
23000
|
-
name: "BasicFormatting",
|
|
23001
|
-
items: [ "Bold", "Italic", "Underline" ]
|
|
23002
|
-
},
|
|
23003
|
-
{
|
|
23004
|
-
name: "Justify",
|
|
23005
|
-
items: [ "JustifyLeft", "JustifyCenter", "JustifyRight" ]
|
|
23006
|
-
},
|
|
23007
|
-
{
|
|
23008
|
-
name: "Lists",
|
|
23009
|
-
items: [ "NumberedList", "BulletedList", "Indent", "Outdent" ]
|
|
23010
|
-
},
|
|
23011
|
-
{
|
|
23012
|
-
name: "Links",
|
|
23013
|
-
items: [ "Link", "Unlink" ]
|
|
23014
|
-
},
|
|
23015
|
-
{
|
|
23016
|
-
name: "Insert",
|
|
23017
|
-
items: [ "base64image" ]
|
|
23018
|
-
}
|
|
23019
|
-
],*/
|
|
23535
|
+
toolbar: toolbar,
|
|
23020
23536
|
removeButtons: "", // Set to empty string to prevent CKEditor from removing buttons such as Underline
|
|
23537
|
+
mentions: mentions,
|
|
23021
23538
|
on:
|
|
23022
23539
|
{
|
|
23023
23540
|
instanceReady: function()
|
|
@@ -23062,6 +23579,60 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23062
23579
|
me.Maximized(true);
|
|
23063
23580
|
}
|
|
23064
23581
|
|
|
23582
|
+
if (config.InfoPanel && config.InfoPanel.Text)
|
|
23583
|
+
{
|
|
23584
|
+
var infoPanel = document.createElement("div");
|
|
23585
|
+
infoPanel.className = "FitUiControlInputInfoPanel";
|
|
23586
|
+
infoPanel.innerHTML = config.InfoPanel.Text;
|
|
23587
|
+
infoPanel.style.cssText = "text-align: " + (config.InfoPanel.Alignment ? config.InfoPanel.Alignment.toLowerCase() : "center");
|
|
23588
|
+
|
|
23589
|
+
var ckEditorInner = designEditor.container.$.querySelector(".cke_inner"); // Div in modern browsers, span in legacy IE
|
|
23590
|
+
var ckEditorBottom = designEditor.container.$.querySelector(".cke_inner span.cke_bottom"); // Only present if resize handle is enable
|
|
23591
|
+
|
|
23592
|
+
if (ckEditorInner !== null)
|
|
23593
|
+
{
|
|
23594
|
+
if (ckEditorBottom !== null)
|
|
23595
|
+
{
|
|
23596
|
+
Fit.Dom.InsertBefore(ckEditorBottom, infoPanel);
|
|
23597
|
+
}
|
|
23598
|
+
else
|
|
23599
|
+
{
|
|
23600
|
+
Fit.Dom.Add(ckEditorInner, infoPanel);
|
|
23601
|
+
}
|
|
23602
|
+
}
|
|
23603
|
+
}
|
|
23604
|
+
|
|
23605
|
+
// DISABLED: Doesn't work! Emoji panel contains an iFrame. When it is re-mounted
|
|
23606
|
+
// in DOM, the iframe reloads, and dynamically added content is lost. Also, this makes
|
|
23607
|
+
// CKEditor throw errors and the dialog never appears.
|
|
23608
|
+
/*if (Fit._internal.ControlBase.ReduceDocumentRootPollution === true)
|
|
23609
|
+
{
|
|
23610
|
+
// Move emoji dialog to control - otherwise placed in the root of the document where it pollutes,
|
|
23611
|
+
// and makes it impossible to interact with the dialog in light dismissable panels and callouts.
|
|
23612
|
+
// Dialog is placed alongside control and not within the control's container, to prevent Fit.UI
|
|
23613
|
+
// styling from affecting the dialog.
|
|
23614
|
+
if (config.Toolbar && config.Toolbar.Emojis === true)
|
|
23615
|
+
{
|
|
23616
|
+
var emojiButton = designEditor.container.$.querySelector("a.cke_button__emojipanel");
|
|
23617
|
+
|
|
23618
|
+
if (emojiButton !== null)
|
|
23619
|
+
{
|
|
23620
|
+
Fit.Events.AddHandler(emojiButton, "click", function(e)
|
|
23621
|
+
{
|
|
23622
|
+
setTimeout(function() // Postpone - made visible after click event
|
|
23623
|
+
{
|
|
23624
|
+
var emojiPanel = document.querySelector("div.cke_emoji-panel:not([style*='display: none'])");
|
|
23625
|
+
|
|
23626
|
+
if (emojiPanel !== null)
|
|
23627
|
+
{
|
|
23628
|
+
Fit.Dom.InsertAfter(me.GetDomElement(), emojiPanel);
|
|
23629
|
+
}
|
|
23630
|
+
}, 0);
|
|
23631
|
+
});
|
|
23632
|
+
}
|
|
23633
|
+
}
|
|
23634
|
+
}*/
|
|
23635
|
+
|
|
23065
23636
|
designEditor._isReadyForInteraction = true;
|
|
23066
23637
|
|
|
23067
23638
|
// Make editor assume configured width and height.
|
|
@@ -23095,8 +23666,73 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23095
23666
|
me._internal.Data("resized", "true");
|
|
23096
23667
|
repaint();
|
|
23097
23668
|
},
|
|
23669
|
+
selectionChange: function(ev)
|
|
23670
|
+
{
|
|
23671
|
+
// Disable/enable toolbar buttons, depending on whether a tag/mention is selected
|
|
23672
|
+
|
|
23673
|
+
var elm = ev.data.selection.getStartElement().$;
|
|
23674
|
+
|
|
23675
|
+
if (elm.tagName === "A" && Fit.Dom.Data(elm, "tag-id") !== null)
|
|
23676
|
+
{
|
|
23677
|
+
designEditorSuppressPaste = true;
|
|
23678
|
+
setTimeout(function() // Postpone - otherwise we won't be able to temporarily disable some of the buttons (https://jsfiddle.net/ymv56znq/14/)
|
|
23679
|
+
{
|
|
23680
|
+
disableDesignEditorButtons();
|
|
23681
|
+
}, 0);
|
|
23682
|
+
}
|
|
23683
|
+
else
|
|
23684
|
+
{
|
|
23685
|
+
designEditorSuppressPaste = false;
|
|
23686
|
+
restoreDesignEditorButtons();
|
|
23687
|
+
}
|
|
23688
|
+
},
|
|
23689
|
+
doubleclick: function(ev)
|
|
23690
|
+
{
|
|
23691
|
+
// Suppress link dialog for tags (similar code found in beforeCommandExec handler below)
|
|
23692
|
+
if (Fit.Dom.Data(ev.data.element.$, "tag-id") !== null)
|
|
23693
|
+
{
|
|
23694
|
+
ev.cancel();
|
|
23695
|
+
return;
|
|
23696
|
+
}
|
|
23697
|
+
},
|
|
23698
|
+
paste: function(ev)
|
|
23699
|
+
{
|
|
23700
|
+
// Prevent pasting (especially images) into tags.
|
|
23701
|
+
// OnPaste is suppressed using an OnPaste handler in capture phase, which will prevent the operation entirely
|
|
23702
|
+
// on supported browsers. On legacy browsers we handle this by invoking undo on the editor instance instead.
|
|
23703
|
+
//var path = ev.editor.elementPath(); // Null if dialog button is triggered without placing text cursor in editor first
|
|
23704
|
+
//if (Fit.Dom.Data(path.lastElement.$, "tag-id") !== null)
|
|
23705
|
+
if (designEditorSuppressPaste === true) // Also handled in a native OnPaste event handler (capture phase) for supported browsers, which suppresses the event entirely
|
|
23706
|
+
{
|
|
23707
|
+
setTimeout(function() // Postpone - allow editor to create snapshot
|
|
23708
|
+
{
|
|
23709
|
+
ev.editor.execCommand("undo"); // Undo change - paste event cannot be canceled, as it has already happened
|
|
23710
|
+
}, 0);
|
|
23711
|
+
return;
|
|
23712
|
+
}
|
|
23713
|
+
},
|
|
23098
23714
|
beforeCommandExec: function(ev)
|
|
23099
23715
|
{
|
|
23716
|
+
// Suppress any command (formatting, link dialog etc.) for tags (similar code found in doubleclick handler above).
|
|
23717
|
+
// Commmands can be triggered in multiple ways, e.g. using toolbar buttons, using keyboard shortcuts, and programmatically.
|
|
23718
|
+
var path = ev.editor.elementPath(); // Null if dialog button is triggered without placing text cursor in editor first
|
|
23719
|
+
if (path === null && ev.editor.getData().indexOf("<p><a data-tag-id=") === 0)
|
|
23720
|
+
{
|
|
23721
|
+
// Text cursor has not been placed in editor, but a command such as Bold or "insert image"
|
|
23722
|
+
// has been triggered, and editor content starts with a tag. This results in command being
|
|
23723
|
+
// applied to the tag, which we do not want. Usually this is prevented by the toolbar being
|
|
23724
|
+
// disabled when a tag is selected (see selectionChange event handler further up), but that
|
|
23725
|
+
// is not the case when the user has not yet placed the cursor in the editor.
|
|
23726
|
+
ev.cancel();
|
|
23727
|
+
return;
|
|
23728
|
+
}
|
|
23729
|
+
else if (path !== null && Fit.Dom.Data(path.lastElement.$, "tag-id") !== null && ev.data.name !== "undo") // Allow undo within tag, in case user typed something by mistake
|
|
23730
|
+
{
|
|
23731
|
+
// Cursor is currently placed in a tag - do not allow formatting
|
|
23732
|
+
ev.cancel();
|
|
23733
|
+
return;
|
|
23734
|
+
}
|
|
23735
|
+
|
|
23100
23736
|
if (ev && ev.data && ev.data.command && ev.data.command.dialogName)
|
|
23101
23737
|
{
|
|
23102
23738
|
// Command triggered was a dialog
|
|
@@ -23153,6 +23789,68 @@ Fit.Controls.Input = function(ctlId)
|
|
|
23153
23789
|
});
|
|
23154
23790
|
}
|
|
23155
23791
|
|
|
23792
|
+
function disableDesignEditorButtons() // Might be called multiple times, e.g. if navigating from one tag/mention to another - buttons must be disabled every time since CKEditor itself re-enable buttons when navigating elements in editor
|
|
23793
|
+
{
|
|
23794
|
+
var preserveButtonState = designEditorRestoreButtonState === null;
|
|
23795
|
+
|
|
23796
|
+
if (preserveButtonState === true)
|
|
23797
|
+
{
|
|
23798
|
+
designEditorRestoreButtonState = {};
|
|
23799
|
+
}
|
|
23800
|
+
|
|
23801
|
+
Fit.Array.ForEach(designEditor.toolbar, function(toolbarGroup)
|
|
23802
|
+
{
|
|
23803
|
+
var items = toolbarGroup.items;
|
|
23804
|
+
|
|
23805
|
+
Fit.Array.ForEach(toolbarGroup.items, function(item)
|
|
23806
|
+
{
|
|
23807
|
+
if (item.command) // Buttons have a command identifier which can be used to resolve the actual command instance
|
|
23808
|
+
{
|
|
23809
|
+
var cmd = designEditor.getCommand(item.command);
|
|
23810
|
+
|
|
23811
|
+
if (preserveButtonState === true && cmd.state !== CKEDITOR.TRISTATE_DISABLED) // https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_command.html#property-state
|
|
23812
|
+
{
|
|
23813
|
+
designEditorRestoreButtonState[item.command] = true;
|
|
23814
|
+
}
|
|
23815
|
+
|
|
23816
|
+
cmd.disable();
|
|
23817
|
+
}
|
|
23818
|
+
else if (item.setState) // MenuButtons allow for direct manipulation of enabled/disabled state
|
|
23819
|
+
{
|
|
23820
|
+
if (preserveButtonState === true && item.getState() !== CKEDITOR.TRISTATE_DISABLED) // https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_command.html#property-state
|
|
23821
|
+
{
|
|
23822
|
+
designEditorRestoreButtonState[item.name] = item;
|
|
23823
|
+
}
|
|
23824
|
+
|
|
23825
|
+
item.setState(CKEDITOR.TRISTATE_DISABLED);
|
|
23826
|
+
}
|
|
23827
|
+
});
|
|
23828
|
+
});
|
|
23829
|
+
}
|
|
23830
|
+
|
|
23831
|
+
function restoreDesignEditorButtons()
|
|
23832
|
+
{
|
|
23833
|
+
console.log("RESTORING toolbar buttons");
|
|
23834
|
+
|
|
23835
|
+
if (designEditorRestoreButtonState !== null)
|
|
23836
|
+
{
|
|
23837
|
+
Fit.Array.ForEach(designEditorRestoreButtonState, function(commandKey)
|
|
23838
|
+
{
|
|
23839
|
+
if (designEditorRestoreButtonState[commandKey] === true) // Command button
|
|
23840
|
+
{
|
|
23841
|
+
var cmd = designEditor.getCommand(commandKey);
|
|
23842
|
+
cmd.enable();
|
|
23843
|
+
}
|
|
23844
|
+
else // MenuButton
|
|
23845
|
+
{
|
|
23846
|
+
designEditorRestoreButtonState[commandKey].setState(CKEDITOR.TRISTATE_OFF); // Enabled but not highlighted/activated like e.g. a bold button would be when selecting bold text
|
|
23847
|
+
}
|
|
23848
|
+
});
|
|
23849
|
+
|
|
23850
|
+
designEditorRestoreButtonState = null;
|
|
23851
|
+
}
|
|
23852
|
+
};
|
|
23853
|
+
|
|
23156
23854
|
function updateDesignEditorSize()
|
|
23157
23855
|
{
|
|
23158
23856
|
if (designEditor !== null)
|
|
@@ -23371,66 +24069,9 @@ Fit._internal.Controls.Input.Editor =
|
|
|
23371
24069
|
/// <member container="Fit._internal.Controls.Input.Editor" name="Skin" access="public" static="true" type="'bootstrapck' | 'moono-lisa' | null">
|
|
23372
24070
|
/// <description> Skin used with DesignMode - must be set before an editor is created and cannot be changed for each individual control </description>
|
|
23373
24071
|
/// </member>
|
|
23374
|
-
Skin: null
|
|
23375
|
-
|
|
23376
|
-
/// <member container="Fit._internal.Controls.Input.Editor" name="Plugins" access="public" static="true" type="('htmlwriter' | 'justify' | 'pastefromword' | 'resize' | 'base64image' | 'base64imagepaste' | 'dragresize')[]">
|
|
23377
|
-
/// <description> Additional plugins used with DesignMode </description>
|
|
23378
|
-
/// </member>
|
|
23379
|
-
Plugins: ["htmlwriter", "justify", "pastefromword", "resize" /*"base64image", "base64imagepaste", "dragresize"*/], // Regarding base64imagepaste and dragresize: IE11 has native support for pasting images as base64 and IE8+ has native support for image resizing, so plugins are not in effect in IE, even when enabled
|
|
23380
|
-
|
|
23381
|
-
/// <member container="Fit._internal.Controls.Input.Editor" name="Toolbar" access="public" static="true" type="( { name: 'BasicFormatting', items: ('Bold' | 'Italic' | 'Underline')[] } | { name: 'Justify', items: ('JustifyLeft' | 'JustifyCenter' | 'JustifyRight')[] } | { name: 'Lists', items: ('NumberedList' | 'BulletedList' | 'Indent' | 'Outdent')[] } | { name: 'Links', items: ('Link' | 'Unlink')[] } | { name: 'Insert', items: ('base64image')[] } )[]">
|
|
23382
|
-
/// <description> Toolbar buttons used with DesignMode - make sure necessary plugins are loaded (see Fit._internal.Controls.Input.EditorPlugins) </description>
|
|
23383
|
-
/// </member>
|
|
23384
|
-
Toolbar:
|
|
23385
|
-
[
|
|
23386
|
-
{
|
|
23387
|
-
name: "BasicFormatting",
|
|
23388
|
-
items: [ "Bold", "Italic", "Underline" ]
|
|
23389
|
-
},
|
|
23390
|
-
{
|
|
23391
|
-
name: "Justify",
|
|
23392
|
-
items: [ "JustifyLeft", "JustifyCenter", "JustifyRight" ]
|
|
23393
|
-
},
|
|
23394
|
-
{
|
|
23395
|
-
name: "Lists",
|
|
23396
|
-
items: [ "NumberedList", "BulletedList", "Indent", "Outdent" ]
|
|
23397
|
-
},
|
|
23398
|
-
{
|
|
23399
|
-
name: "Links",
|
|
23400
|
-
items: [ "Link", "Unlink" ]
|
|
23401
|
-
}/*,
|
|
23402
|
-
{
|
|
23403
|
-
name: "Insert",
|
|
23404
|
-
items: [ "base64image" ]
|
|
23405
|
-
}*/
|
|
23406
|
-
]
|
|
24072
|
+
Skin: null // Notice: CKEditor does not support multiple different skins on the same page - do not change value once an editor has been created
|
|
23407
24073
|
};
|
|
23408
24074
|
|
|
23409
|
-
/// <container name="Fit._internal.Controls.Input.BlobManager">
|
|
23410
|
-
/// Internal settings related to blob storage management in HTML Editor (Design Mode)
|
|
23411
|
-
/// </container>
|
|
23412
|
-
Fit._internal.Controls.Input.BlobManager =
|
|
23413
|
-
{
|
|
23414
|
-
/// <member container="Fit._internal.Controls.Input.BlobManager" name="RevokeBlobUrlsOnDispose" access="public" static="true" type="'All' | 'UnreferencedOnly'">
|
|
23415
|
-
/// <description>
|
|
23416
|
-
/// Dispose images from blob storage (revoke blob URLs) added though image plugins when control is disposed.
|
|
23417
|
-
/// If "UnreferencedOnly" is specified, the component using Fit.UI's input control will be responsible for
|
|
23418
|
-
/// disposing referenced blobs. Failing to do so may cause a memory leak.
|
|
23419
|
-
/// </description>
|
|
23420
|
-
/// </member>
|
|
23421
|
-
RevokeBlobUrlsOnDispose: "All", // "All" | "UnreferencedOnly"
|
|
23422
|
-
|
|
23423
|
-
/// <member container="Fit._internal.Controls.Input.BlobManager" name="RevokeExternalBlobUrlsOnDispose" access="public" static="true" type="boolean">
|
|
23424
|
-
/// <description>
|
|
23425
|
-
/// Dispose images from blob storage (revoke blob URLs) added through Value(..)
|
|
23426
|
-
/// function when control is disposed. Basically ownership of these blobs are handed
|
|
23427
|
-
/// over to the control for the duration of its life time.
|
|
23428
|
-
/// These images are furthermore subject to the rule set in RevokeBlobUrlsOnDispose.
|
|
23429
|
-
/// </description>
|
|
23430
|
-
/// </member>
|
|
23431
|
-
RevokeExternalBlobUrlsOnDispose: false
|
|
23432
|
-
}
|
|
23433
|
-
|
|
23434
24075
|
/// <container name="Fit.Controls.InputResizing">
|
|
23435
24076
|
/// <description> Resizing options </description>
|
|
23436
24077
|
/// <member name="Enabled" access="public" static="true" type="string" default="Enabled"> Allow for resizing both vertically and horizontally </member>
|