@seamly/web-ui 20.4.0 → 20.5.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/build/dist/lib/index.debug.js +35 -68
- package/build/dist/lib/index.debug.min.js +1 -1
- package/build/dist/lib/index.debug.min.js.LICENSE.txt +4 -16
- package/build/dist/lib/index.js +374 -3850
- package/build/dist/lib/index.min.js +1 -1
- package/build/dist/lib/index.min.js.LICENSE.txt +0 -5
- package/build/dist/lib/standalone.js +394 -3862
- package/build/dist/lib/standalone.min.js +1 -1
- package/build/dist/lib/style-guide.js +200 -113
- package/build/dist/lib/style-guide.min.js +1 -1
- package/package.json +2 -4
- package/src/javascripts/api/index.js +17 -1
- package/src/javascripts/domains/config/reducer.js +2 -0
- package/src/javascripts/domains/forms/provider.js +14 -6
- package/src/javascripts/domains/visibility/actions.js +2 -0
- package/src/javascripts/domains/visibility/hooks.js +60 -1
- package/src/javascripts/domains/visibility/reducer.js +5 -0
- package/src/javascripts/domains/visibility/selectors.js +5 -0
- package/src/javascripts/domains/visibility/utils.js +5 -1
- package/src/javascripts/style-guide/components/app.js +2 -0
- package/src/javascripts/style-guide/states.js +30 -50
- package/src/javascripts/ui/components/conversation/event/card-component.js +1 -2
- package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +19 -9
- package/src/javascripts/ui/components/conversation/event/cta.js +1 -2
- package/src/javascripts/ui/components/conversation/event/participant.js +2 -11
- package/src/javascripts/ui/components/conversation/event/splash.js +1 -3
- package/src/javascripts/ui/components/conversation/event/text.js +9 -9
- package/src/javascripts/ui/components/layout/chat.js +52 -48
- package/src/javascripts/ui/components/suggestions/suggestions-list.js +12 -14
- package/src/javascripts/ui/components/view/deprecated-view.js +16 -11
- package/src/javascripts/ui/components/view/inline-view.js +13 -8
- package/src/javascripts/ui/hooks/seamly-entry-hooks.js +3 -2
- package/src/javascripts/ui/hooks/seamly-state-hooks.js +4 -3
- package/src/javascripts/ui/hooks/use-seamly-chat.js +41 -29
- package/src/javascripts/ui/hooks/use-seamly-commands.js +16 -4
- package/src/javascripts/ui/utils/seamly-utils.js +16 -6
- package/src/javascripts/lib/parse-body.js +0 -10
- package/src/javascripts/ui/components/conversation/event/hooks/use-text-rendering.js +0 -35
package/build/dist/lib/index.js
CHANGED
|
@@ -3568,7 +3568,7 @@ Emitter.prototype.hasListeners = function(event){
|
|
|
3568
3568
|
"use strict";
|
|
3569
3569
|
|
|
3570
3570
|
|
|
3571
|
-
var keys = __webpack_require__(
|
|
3571
|
+
var keys = __webpack_require__(215);
|
|
3572
3572
|
var hasSymbols = typeof Symbol === 'function' && typeof Symbol('foo') === 'symbol';
|
|
3573
3573
|
|
|
3574
3574
|
var toStr = Object.prototype.toString;
|
|
@@ -5143,7 +5143,7 @@ module.exports = keysShim;
|
|
|
5143
5143
|
|
|
5144
5144
|
/***/ }),
|
|
5145
5145
|
|
|
5146
|
-
/***/
|
|
5146
|
+
/***/ 215:
|
|
5147
5147
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
5148
5148
|
|
|
5149
5149
|
"use strict";
|
|
@@ -9041,14 +9041,16 @@ const orderHistory = events => {
|
|
|
9041
9041
|
};
|
|
9042
9042
|
|
|
9043
9043
|
const mergeHistory = (stateEvents, historyEvents) => {
|
|
9044
|
-
const
|
|
9045
|
-
|
|
9044
|
+
const newStateEvents = stateEvents.filter(stateEvent => // Deduplicate the event streams, giving events in historyEvents
|
|
9045
|
+
// precedence so the server is able to push changes to events.
|
|
9046
|
+
!historyEvents.some(historyEvent => historyEvent.payload.id === stateEvent.payload.id));
|
|
9047
|
+
const newHistoryEvents = historyEvents.filter(historyEvent => // Remove all non displayable participant messages
|
|
9046
9048
|
!(historyEvent.type === 'participant' && !historyEvent.payload.participant.introduction)) // Reverse is done here because the server sends the history in the order
|
|
9047
9049
|
// newest to oldest. In the case of exactly the same occurredAt timestamps
|
|
9048
9050
|
// these messages will be shown in the wrong order if not reversed. For
|
|
9049
9051
|
// the normal merging logic there is no added effect.
|
|
9050
9052
|
.reverse();
|
|
9051
|
-
return orderHistory([...newHistoryEvents, ...
|
|
9053
|
+
return orderHistory([...newHistoryEvents, ...newStateEvents]);
|
|
9052
9054
|
};
|
|
9053
9055
|
|
|
9054
9056
|
const participantReducer = (state, action) => {
|
|
@@ -9429,8 +9431,12 @@ const seamlyStateReducer = (state, action) => {
|
|
|
9429
9431
|
});
|
|
9430
9432
|
|
|
9431
9433
|
case SET_INITIAL_STATE:
|
|
9434
|
+
const {
|
|
9435
|
+
initialState
|
|
9436
|
+
} = action;
|
|
9432
9437
|
return seamly_utils_objectSpread(seamly_utils_objectSpread({}, state), {}, {
|
|
9433
|
-
initialState
|
|
9438
|
+
initialState,
|
|
9439
|
+
unreadEvents: initialState.unreadMessageCount
|
|
9434
9440
|
});
|
|
9435
9441
|
|
|
9436
9442
|
case SET_SERVICE_DATA_ITEM:
|
|
@@ -9815,15 +9821,20 @@ const useEntryTextLimit = () => {
|
|
|
9815
9821
|
entryMeta: {
|
|
9816
9822
|
options: {
|
|
9817
9823
|
text
|
|
9824
|
+
},
|
|
9825
|
+
optionsOverride: {
|
|
9826
|
+
text: overrideText
|
|
9818
9827
|
}
|
|
9819
9828
|
}
|
|
9820
9829
|
} = useSeamlyStateContext();
|
|
9821
9830
|
const {
|
|
9822
9831
|
limit
|
|
9823
|
-
} = text || {
|
|
9832
|
+
} = overrideText || text || {
|
|
9833
|
+
limit: null
|
|
9834
|
+
};
|
|
9824
9835
|
return {
|
|
9825
|
-
hasLimit: limit
|
|
9826
|
-
limit: limit
|
|
9836
|
+
hasLimit: limit !== null,
|
|
9837
|
+
limit: limit !== null ? limit : null
|
|
9827
9838
|
};
|
|
9828
9839
|
};
|
|
9829
9840
|
const useSeamlyLayoutMode = () => {
|
|
@@ -9859,7 +9870,12 @@ const calculateVisibility = ({
|
|
|
9859
9870
|
} = config;
|
|
9860
9871
|
const {
|
|
9861
9872
|
visible: defaultVisibility
|
|
9862
|
-
} = defaults || {}; //
|
|
9873
|
+
} = defaults || {}; // The app layout should always be open by default.
|
|
9874
|
+
|
|
9875
|
+
if (layoutMode === 'app' && !previousVisibility) {
|
|
9876
|
+
return visibilityStates.open;
|
|
9877
|
+
} // Requesting open should override the responded check.
|
|
9878
|
+
|
|
9863
9879
|
|
|
9864
9880
|
if (layoutMode === 'window' && hideOnNoUserResponse && requestedVisibility !== visibilityStates.open) {
|
|
9865
9881
|
return hasResponded ? requestedVisibility || previousVisibility || visibilityStates.open : visibilityStates.hidden;
|
|
@@ -9878,6 +9894,7 @@ const calculateVisibility = ({
|
|
|
9878
9894
|
|
|
9879
9895
|
|
|
9880
9896
|
const selectVisibility = createSelector(visibility_utils_selectState, state => state.visibility);
|
|
9897
|
+
const selectShowInlineView = createSelector(visibility_utils_selectState, state => state.showInlineView);
|
|
9881
9898
|
|
|
9882
9899
|
;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/actions.js
|
|
9883
9900
|
function actions_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
@@ -9895,6 +9912,7 @@ function actions_defineProperty(obj, key, value) { if (key in obj) { Object.defi
|
|
|
9895
9912
|
const setFromStorage = visibility_utils_createAction('setFromStorage', visibility => ({
|
|
9896
9913
|
visibility
|
|
9897
9914
|
}));
|
|
9915
|
+
const setShowInlineView = visibility_utils_createAction('setShowInlineView');
|
|
9898
9916
|
const validVisibilityStates = [visibilityStates.open, visibilityStates.minimized, visibilityStates.hidden];
|
|
9899
9917
|
const actions_setVisibility = visibility_utils_createThunk('set', (requestedVisibility, {
|
|
9900
9918
|
getState,
|
|
@@ -10173,6 +10191,7 @@ function reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defi
|
|
|
10173
10191
|
|
|
10174
10192
|
const initialState = reducer_objectSpread(reducer_objectSpread({}, defaultConfig), {}, {
|
|
10175
10193
|
hideOnNoUserResponse: false,
|
|
10194
|
+
connectWhenInView: true,
|
|
10176
10195
|
showDisclaimer: false,
|
|
10177
10196
|
showFaq: false,
|
|
10178
10197
|
customComponents: {},
|
|
@@ -10180,7 +10199,7 @@ const initialState = reducer_objectSpread(reducer_objectSpread({}, defaultConfig
|
|
|
10180
10199
|
preChatEvents: []
|
|
10181
10200
|
});
|
|
10182
10201
|
|
|
10183
|
-
const configKeys = ['hideOnNoUserResponse', 'showDisclaimer', 'showFaq', 'namespace', 'customComponents', 'defaults', 'layoutMode', 'api', 'zIndex', 'context', 'appContainerClassNames', 'messages', 'visible', 'visibilityCallback', 'errorCallback', 'agentParticipant', 'userParticipant', 'startChatIcon'];
|
|
10202
|
+
const configKeys = ['hideOnNoUserResponse', 'connectWhenInView', 'showDisclaimer', 'showFaq', 'namespace', 'customComponents', 'defaults', 'layoutMode', 'api', 'zIndex', 'context', 'appContainerClassNames', 'messages', 'visible', 'visibilityCallback', 'errorCallback', 'agentParticipant', 'userParticipant', 'startChatIcon'];
|
|
10184
10203
|
|
|
10185
10204
|
const updateState = (state, {
|
|
10186
10205
|
config
|
|
@@ -10228,6 +10247,8 @@ const updateState = (state, {
|
|
|
10228
10247
|
|
|
10229
10248
|
|
|
10230
10249
|
|
|
10250
|
+
;// CONCATENATED MODULE: external "preact/compat"
|
|
10251
|
+
const compat_namespaceObject = require("preact/compat");
|
|
10231
10252
|
;// CONCATENATED MODULE: ./src/javascripts/lib/css.js
|
|
10232
10253
|
|
|
10233
10254
|
/**
|
|
@@ -11487,6 +11508,7 @@ function useUserHasResponded() {
|
|
|
11487
11508
|
|
|
11488
11509
|
|
|
11489
11510
|
|
|
11511
|
+
|
|
11490
11512
|
const useVisibility = () => {
|
|
11491
11513
|
const dispatch = useStoreDispatch();
|
|
11492
11514
|
const visible = hooks_useSelector(selectVisibility);
|
|
@@ -11502,6 +11524,69 @@ const useVisibility = () => {
|
|
|
11502
11524
|
setVisibility
|
|
11503
11525
|
};
|
|
11504
11526
|
};
|
|
11527
|
+
/**
|
|
11528
|
+
* Custom hook which enables initializing of IntersectionObserver on any node ref.
|
|
11529
|
+
* @param {object} options Hook options.
|
|
11530
|
+
* @param {boolean=} options.freezeOnceVisible Stops observing when the root element is visible.
|
|
11531
|
+
* @param {boolean=} options.enabled Determines if useIntersect is enabled.
|
|
11532
|
+
*/
|
|
11533
|
+
|
|
11534
|
+
const useIntersect = ({
|
|
11535
|
+
freezeOnceVisible = false,
|
|
11536
|
+
enabled = true
|
|
11537
|
+
}) => {
|
|
11538
|
+
const [entry, setEntry] = (0,hooks_namespaceObject.useState)(null);
|
|
11539
|
+
const containerRef = (0,hooks_namespaceObject.useRef)(null);
|
|
11540
|
+
const isVisible = !!entry?.isIntersecting || !enabled;
|
|
11541
|
+
const frozen = isVisible && freezeOnceVisible;
|
|
11542
|
+
|
|
11543
|
+
const observerCallback = ([updatedEntry]) => setEntry(updatedEntry);
|
|
11544
|
+
|
|
11545
|
+
(0,hooks_namespaceObject.useEffect)(() => {
|
|
11546
|
+
const node = containerRef?.current;
|
|
11547
|
+
const hasIOSupport = !!window.IntersectionObserver;
|
|
11548
|
+
|
|
11549
|
+
if (!node && "production" === 'development') {} // Return an arrow function to have a consistent return value
|
|
11550
|
+
|
|
11551
|
+
|
|
11552
|
+
if (!hasIOSupport || frozen || !node || !enabled) return () => undefined;
|
|
11553
|
+
const observerOptions = {
|
|
11554
|
+
threshold: 0,
|
|
11555
|
+
root: null,
|
|
11556
|
+
rootMargin: '0%'
|
|
11557
|
+
};
|
|
11558
|
+
const observer = new IntersectionObserver(observerCallback, observerOptions);
|
|
11559
|
+
observer.observe(node);
|
|
11560
|
+
return () => observer.disconnect();
|
|
11561
|
+
}, [enabled, frozen]);
|
|
11562
|
+
return {
|
|
11563
|
+
isVisible,
|
|
11564
|
+
containerRef
|
|
11565
|
+
};
|
|
11566
|
+
};
|
|
11567
|
+
|
|
11568
|
+
const useShowInlineView = () => {
|
|
11569
|
+
const dispatch = useStoreDispatch();
|
|
11570
|
+
const {
|
|
11571
|
+
connectWhenInView
|
|
11572
|
+
} = useConfig();
|
|
11573
|
+
const showInlineView = hooks_useSelector(selectShowInlineView);
|
|
11574
|
+
const {
|
|
11575
|
+
containerRef,
|
|
11576
|
+
isVisible
|
|
11577
|
+
} = useIntersect({
|
|
11578
|
+
enabled: connectWhenInView,
|
|
11579
|
+
freezeOnceVisible: true
|
|
11580
|
+
});
|
|
11581
|
+
(0,hooks_namespaceObject.useEffect)(() => {
|
|
11582
|
+
if (!isVisible) return;
|
|
11583
|
+
dispatch(setShowInlineView());
|
|
11584
|
+
}, [dispatch, isVisible]);
|
|
11585
|
+
return {
|
|
11586
|
+
containerRef,
|
|
11587
|
+
showInlineView
|
|
11588
|
+
};
|
|
11589
|
+
};
|
|
11505
11590
|
;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/reducer.js
|
|
11506
11591
|
function visibility_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
11507
11592
|
|
|
@@ -11513,7 +11598,8 @@ function visibility_reducer_defineProperty(obj, key, value) { if (key in obj) {
|
|
|
11513
11598
|
|
|
11514
11599
|
|
|
11515
11600
|
const visibility_reducer_initialState = {
|
|
11516
|
-
visibility: visibilityStates.initialize
|
|
11601
|
+
visibility: visibilityStates.initialize,
|
|
11602
|
+
showInlineView: false
|
|
11517
11603
|
};
|
|
11518
11604
|
/* harmony default export */ const visibility_reducer = (visibility_utils_createReducer({
|
|
11519
11605
|
[setFromStorage]: (state, {
|
|
@@ -11525,7 +11611,10 @@ const visibility_reducer_initialState = {
|
|
|
11525
11611
|
payload: visibility
|
|
11526
11612
|
}) => visibility ? visibility_reducer_objectSpread(visibility_reducer_objectSpread({}, state), {}, {
|
|
11527
11613
|
visibility
|
|
11528
|
-
}) : state
|
|
11614
|
+
}) : state,
|
|
11615
|
+
[setShowInlineView]: state => visibility_reducer_objectSpread(visibility_reducer_objectSpread({}, state), {}, {
|
|
11616
|
+
showInlineView: true
|
|
11617
|
+
})
|
|
11529
11618
|
}, visibility_reducer_initialState));
|
|
11530
11619
|
;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/index.js
|
|
11531
11620
|
|
|
@@ -11596,7 +11685,8 @@ const useSeamlyCommands = () => {
|
|
|
11596
11685
|
const hasResponded = useUserHasResponded();
|
|
11597
11686
|
const hasConversation = useSeamlyHasConversation();
|
|
11598
11687
|
const {
|
|
11599
|
-
visible: visibility
|
|
11688
|
+
visible: visibility,
|
|
11689
|
+
setVisibility
|
|
11600
11690
|
} = useVisibility();
|
|
11601
11691
|
const unreadMessageCount = useSeamlyUnreadCount();
|
|
11602
11692
|
const emitEvent = (0,hooks_namespaceObject.useCallback)((...args) => {
|
|
@@ -11654,7 +11744,9 @@ const useSeamlyCommands = () => {
|
|
|
11654
11744
|
type: use_seamly_commands_ADD_EVENT,
|
|
11655
11745
|
event: {
|
|
11656
11746
|
type: 'message',
|
|
11657
|
-
payload: message
|
|
11747
|
+
payload: use_seamly_commands_objectSpread(use_seamly_commands_objectSpread({}, message), {}, {
|
|
11748
|
+
optimisticallyInjected: true
|
|
11749
|
+
})
|
|
11658
11750
|
}
|
|
11659
11751
|
});
|
|
11660
11752
|
}, [api, dispatch, emitEvent, getTextMessageBase]);
|
|
@@ -11752,11 +11844,16 @@ const useSeamlyCommands = () => {
|
|
|
11752
11844
|
type: use_seamly_commands_SET_INITIAL_STATE,
|
|
11753
11845
|
initialState
|
|
11754
11846
|
});
|
|
11847
|
+
|
|
11848
|
+
if (initialState.userResponded) {
|
|
11849
|
+
dispatch(setHasResponded(initialState.userResponded));
|
|
11850
|
+
setVisibility(visibilityStates.open);
|
|
11851
|
+
}
|
|
11755
11852
|
}
|
|
11756
11853
|
}).catch(error => {
|
|
11757
11854
|
dispatch(set(error));
|
|
11758
11855
|
});
|
|
11759
|
-
}, [api, dispatch]);
|
|
11856
|
+
}, [api, dispatch, setVisibility]);
|
|
11760
11857
|
return {
|
|
11761
11858
|
connect,
|
|
11762
11859
|
start,
|
|
@@ -11769,6 +11866,7 @@ const useSeamlyCommands = () => {
|
|
|
11769
11866
|
addMessageBubble,
|
|
11770
11867
|
addUploadBubble,
|
|
11771
11868
|
addDivider,
|
|
11869
|
+
apiConnected: api.connected,
|
|
11772
11870
|
apiConfigReady: api.configReady
|
|
11773
11871
|
};
|
|
11774
11872
|
};
|
|
@@ -11898,11 +11996,12 @@ const useSeamlyEntry = () => {
|
|
|
11898
11996
|
default: defaultEntry,
|
|
11899
11997
|
active,
|
|
11900
11998
|
userSelected,
|
|
11901
|
-
options: entryOptions
|
|
11999
|
+
options: entryOptions,
|
|
12000
|
+
optionsOverride: entryOptionsOverride
|
|
11902
12001
|
} = useSeamlyStateContext().entryMeta;
|
|
11903
12002
|
const dispatch = use_seamly_dispatch();
|
|
11904
12003
|
const activeEntry = userSelected || active || defaultEntry;
|
|
11905
|
-
const activeEntryOptions = entryOptions[activeEntry] || {};
|
|
12004
|
+
const activeEntryOptions = entryOptionsOverride[activeEntry] || entryOptions[activeEntry] || {};
|
|
11906
12005
|
const setBlockAutoEntrySwitch = (0,hooks_namespaceObject.useCallback)(value => {
|
|
11907
12006
|
dispatch({
|
|
11908
12007
|
type: seamly_entry_hooks_SET_BLOCK_AUTO_ENTRY_SWITCH,
|
|
@@ -11948,6 +12047,7 @@ const useSeamlyEntry = () => {
|
|
|
11948
12047
|
|
|
11949
12048
|
|
|
11950
12049
|
|
|
12050
|
+
|
|
11951
12051
|
const {
|
|
11952
12052
|
SET_IS_LOADING: use_seamly_chat_SET_IS_LOADING
|
|
11953
12053
|
} = seamlyActions;
|
|
@@ -11957,28 +12057,31 @@ const useSeamlyChat = () => {
|
|
|
11957
12057
|
t
|
|
11958
12058
|
} = useI18n();
|
|
11959
12059
|
const {
|
|
11960
|
-
|
|
11961
|
-
|
|
12060
|
+
isInline,
|
|
12061
|
+
isWindow
|
|
12062
|
+
} = useSeamlyLayoutMode();
|
|
11962
12063
|
const {
|
|
11963
12064
|
isOpen,
|
|
11964
12065
|
isVisible,
|
|
11965
12066
|
setVisibility
|
|
11966
12067
|
} = useVisibility();
|
|
12068
|
+
const showInlineView = hooks_useSelector(selectShowInlineView);
|
|
11967
12069
|
const dispatch = use_seamly_dispatch();
|
|
11968
12070
|
const events = useEvents();
|
|
11969
12071
|
const spinnerTimeout = (0,hooks_namespaceObject.useRef)(null);
|
|
11970
12072
|
const {
|
|
11971
12073
|
start,
|
|
11972
12074
|
connect,
|
|
11973
|
-
apiConfigReady
|
|
12075
|
+
apiConfigReady,
|
|
12076
|
+
apiConnected
|
|
11974
12077
|
} = use_seamly_commands();
|
|
11975
12078
|
const hasConversation = useSeamlyHasConversation();
|
|
11976
12079
|
const prevIsOpen = (0,hooks_namespaceObject.useRef)(null);
|
|
11977
12080
|
const prevIsVisible = (0,hooks_namespaceObject.useRef)(null);
|
|
12081
|
+
const startCalled = (0,hooks_namespaceObject.useRef)(false);
|
|
11978
12082
|
const {
|
|
11979
12083
|
sendAssertive
|
|
11980
12084
|
} = useLiveRegion();
|
|
11981
|
-
const connectCalled = (0,hooks_namespaceObject.useRef)(false);
|
|
11982
12085
|
const hasEvents = events.length > 0;
|
|
11983
12086
|
(0,hooks_namespaceObject.useEffect)(() => {
|
|
11984
12087
|
if (isVisible) {
|
|
@@ -12027,22 +12130,34 @@ const useSeamlyChat = () => {
|
|
|
12027
12130
|
}
|
|
12028
12131
|
}, [hasEvents, dispatch]);
|
|
12029
12132
|
(0,hooks_namespaceObject.useEffect)(() => {
|
|
12030
|
-
// This is needed to reset the ref to allow connect to happen again.
|
|
12133
|
+
// This is needed to reset the ref to allow connect and start to happen again.
|
|
12031
12134
|
// Mostly due to Interrupt situations and a reset being called.
|
|
12032
|
-
if (!
|
|
12033
|
-
|
|
12135
|
+
if (!apiConfigReady || !apiConnected) {
|
|
12136
|
+
startCalled.current = false;
|
|
12137
|
+
}
|
|
12138
|
+
}, [apiConfigReady, apiConnected]);
|
|
12139
|
+
const connectAndStart = (0,hooks_namespaceObject.useCallback)(async () => {
|
|
12140
|
+
// We don't connect if we are already connected to the api to avoid multiple in-flight connection processes.
|
|
12141
|
+
if (!apiConnected) {
|
|
12142
|
+
await connect();
|
|
12143
|
+
} // We only start a conversation when the chat interface is either 'open' or if using the inline view if it's 'open' or 'minimized'.
|
|
12144
|
+
|
|
12145
|
+
|
|
12146
|
+
if (isOpen || isVisible && isInline) {
|
|
12147
|
+
start();
|
|
12148
|
+
startCalled.current = true;
|
|
12034
12149
|
}
|
|
12035
|
-
}, [
|
|
12150
|
+
}, [apiConnected, connect, isInline, isOpen, isVisible, start]);
|
|
12036
12151
|
(0,hooks_namespaceObject.useEffect)(() => {
|
|
12037
|
-
// We
|
|
12038
|
-
//
|
|
12039
|
-
// We
|
|
12040
|
-
//
|
|
12041
|
-
if (
|
|
12152
|
+
// We dont't connect or start when the apiConfig is not ready yet.
|
|
12153
|
+
// We also keep track of whether start has been called to avoid multiple in-flight connection processes.
|
|
12154
|
+
// We check if the window view is not open and no conversation is started yet.
|
|
12155
|
+
// Lastly we check if the inline view is not scrolled in to view.
|
|
12156
|
+
if (!apiConfigReady || startCalled.current || isWindow && !isOpen && !hasConversation || isInline && !showInlineView) {
|
|
12042
12157
|
return;
|
|
12043
12158
|
}
|
|
12044
12159
|
|
|
12045
|
-
if (hasConversation) {
|
|
12160
|
+
if (hasConversation && isOpen) {
|
|
12046
12161
|
// We deactivate the extra startup loading spinner when a conversation is available
|
|
12047
12162
|
// We also stop setting the loading indicator in the first place to avoid a flash.
|
|
12048
12163
|
clearTimeout(spinnerTimeout.current);
|
|
@@ -12052,11 +12167,8 @@ const useSeamlyChat = () => {
|
|
|
12052
12167
|
});
|
|
12053
12168
|
}
|
|
12054
12169
|
|
|
12055
|
-
|
|
12056
|
-
|
|
12057
|
-
});
|
|
12058
|
-
connectCalled.current = true;
|
|
12059
|
-
}, [isOpen, hasConversation, apiConfigReady, start, connect, dispatch, layoutMode]);
|
|
12170
|
+
connectAndStart();
|
|
12171
|
+
}, [apiConfigReady, connectAndStart, dispatch, hasConversation, isInline, isOpen, isWindow, showInlineView]);
|
|
12060
12172
|
|
|
12061
12173
|
const openChat = () => {
|
|
12062
12174
|
setVisibility(visibilityStates.open);
|
|
@@ -13055,6 +13167,7 @@ function provider_objectWithoutPropertiesLoose(source, excluded) { if (source ==
|
|
|
13055
13167
|
|
|
13056
13168
|
|
|
13057
13169
|
|
|
13170
|
+
|
|
13058
13171
|
function FormProvider(_ref) {
|
|
13059
13172
|
let {
|
|
13060
13173
|
children,
|
|
@@ -13110,13 +13223,13 @@ function FormProvider(_ref) {
|
|
|
13110
13223
|
setIsSubmitted(!ariaDisabled);
|
|
13111
13224
|
|
|
13112
13225
|
if (!ariaDisabled && validationIsValid) {
|
|
13226
|
+
dispatch(setHasResponded(true));
|
|
13113
13227
|
onSubmit(values, {
|
|
13114
13228
|
updateControlValue,
|
|
13115
13229
|
setError
|
|
13116
13230
|
});
|
|
13117
13231
|
}
|
|
13118
|
-
}, [validationIsValid, onSubmit, values, updateControlValue, setError]);
|
|
13119
|
-
|
|
13232
|
+
}, [validationIsValid, dispatch, onSubmit, values, updateControlValue, setError]);
|
|
13120
13233
|
(0,hooks_namespaceObject.useEffect)(() => {
|
|
13121
13234
|
if (onError) {
|
|
13122
13235
|
onError({
|
|
@@ -14014,15 +14127,13 @@ const SuggestionsList = ({
|
|
|
14014
14127
|
suggestions = [],
|
|
14015
14128
|
onClickSuggestion,
|
|
14016
14129
|
hasIcon = true
|
|
14017
|
-
}) => {
|
|
14018
|
-
|
|
14019
|
-
|
|
14020
|
-
|
|
14021
|
-
|
|
14022
|
-
|
|
14023
|
-
|
|
14024
|
-
});
|
|
14025
|
-
};
|
|
14130
|
+
}) => (0,jsx_runtime_namespaceObject.jsx)("ul", {
|
|
14131
|
+
className: css_className('suggestions__list', givenClassName),
|
|
14132
|
+
children: suggestions.map(suggestion => (0,jsx_runtime_namespaceObject.jsx)(suggestions_item, suggestions_list_objectSpread({
|
|
14133
|
+
hasIcon: hasIcon,
|
|
14134
|
+
onClick: onClickSuggestion
|
|
14135
|
+
}, suggestion), suggestion.id))
|
|
14136
|
+
});
|
|
14026
14137
|
|
|
14027
14138
|
/* harmony default export */ const suggestions_list = (SuggestionsList);
|
|
14028
14139
|
;// CONCATENATED MODULE: ./src/javascripts/ui/components/suggestions/index.js
|
|
@@ -14195,10 +14306,10 @@ const Suggestions = ({
|
|
|
14195
14306
|
|
|
14196
14307
|
|
|
14197
14308
|
|
|
14198
|
-
const Chat = ({
|
|
14309
|
+
const Chat = (0,compat_namespaceObject.forwardRef)(({
|
|
14199
14310
|
children,
|
|
14200
14311
|
className: givenClassName = ''
|
|
14201
|
-
}) => {
|
|
14312
|
+
}, forwardedRef) => {
|
|
14202
14313
|
const {
|
|
14203
14314
|
isOpen,
|
|
14204
14315
|
isVisible,
|
|
@@ -14237,6 +14348,7 @@ const Chat = ({
|
|
|
14237
14348
|
className: css_className(classNames),
|
|
14238
14349
|
onKeyDown: onKeyDownHandler,
|
|
14239
14350
|
tabIndex: "-1",
|
|
14351
|
+
ref: forwardedRef,
|
|
14240
14352
|
"aria-label": t('chat.srLabel'),
|
|
14241
14353
|
children: [(0,jsx_runtime_namespaceObject.jsx)("div", {
|
|
14242
14354
|
className: css_className('chat-wrapper'),
|
|
@@ -14245,8 +14357,7 @@ const Chat = ({
|
|
|
14245
14357
|
isAside: true
|
|
14246
14358
|
})]
|
|
14247
14359
|
});
|
|
14248
|
-
};
|
|
14249
|
-
|
|
14360
|
+
});
|
|
14250
14361
|
/* harmony default export */ const chat = (Chat);
|
|
14251
14362
|
;// CONCATENATED MODULE: ./src/javascripts/ui/components/layout/interrupt.js
|
|
14252
14363
|
|
|
@@ -14760,3797 +14871,190 @@ function MessageContainer(_ref) {
|
|
|
14760
14871
|
children: t(isTranslated ? 'translations.toggle.hideButtonText' : 'translations.toggle.showButtonText')
|
|
14761
14872
|
})
|
|
14762
14873
|
})]
|
|
14763
|
-
}))
|
|
14764
|
-
});
|
|
14765
|
-
}
|
|
14766
|
-
|
|
14767
|
-
/* harmony default export */ const message_container = (MessageContainer);
|
|
14768
|
-
;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/choice-prompt.js
|
|
14769
|
-
const choice_prompt_excluded = ["event", "children"];
|
|
14770
|
-
|
|
14771
|
-
function choice_prompt_objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = choice_prompt_objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
14772
|
-
|
|
14773
|
-
function choice_prompt_objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
14774
|
-
|
|
14775
|
-
function choice_prompt_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
14776
|
-
|
|
14777
|
-
function choice_prompt_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? choice_prompt_ownKeys(Object(source), !0).forEach(function (key) { choice_prompt_defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : choice_prompt_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
14778
|
-
|
|
14779
|
-
function choice_prompt_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
14780
|
-
|
|
14781
|
-
|
|
14782
|
-
|
|
14783
|
-
|
|
14784
|
-
|
|
14785
|
-
|
|
14786
|
-
|
|
14787
|
-
|
|
14788
|
-
|
|
14789
|
-
|
|
14790
|
-
|
|
14791
|
-
|
|
14792
|
-
|
|
14793
|
-
const useChoicePrompt = event => {
|
|
14794
|
-
const {
|
|
14795
|
-
payload
|
|
14796
|
-
} = event;
|
|
14797
|
-
const [showOptions, setShowOptions] = (0,hooks_namespaceObject.useState)(false);
|
|
14798
|
-
const {
|
|
14799
|
-
sendAction,
|
|
14800
|
-
addMessageBubble,
|
|
14801
|
-
addDivider
|
|
14802
|
-
} = use_seamly_commands();
|
|
14803
|
-
const {
|
|
14804
|
-
activeServiceSessionId
|
|
14805
|
-
} = useSeamlyServiceInfo();
|
|
14806
|
-
const lastEventId = useLastMessageEventId();
|
|
14807
|
-
const [body] = useTranslatedEventData(event);
|
|
14808
|
-
const {
|
|
14809
|
-
service
|
|
14810
|
-
} = payload;
|
|
14811
|
-
const subEvent = (0,hooks_namespaceObject.useMemo)(() => {
|
|
14812
|
-
return choice_prompt_objectSpread(choice_prompt_objectSpread({}, event), {}, {
|
|
14813
|
-
payload: choice_prompt_objectSpread(choice_prompt_objectSpread({}, event.payload), {}, {
|
|
14814
|
-
body: event.payload.body?.prompt,
|
|
14815
|
-
translatedBody: event.payload.translatedBody && choice_prompt_objectSpread(choice_prompt_objectSpread({}, event.payload.translatedBody), {}, {
|
|
14816
|
-
data: event.payload.translatedBody.data.prompt
|
|
14817
|
-
})
|
|
14818
|
-
})
|
|
14819
|
-
});
|
|
14820
|
-
}, [event]);
|
|
14821
|
-
const chooseAgain = body.chooseAgain && activeServiceSessionId === service.serviceSessionId && payload.id !== lastEventId;
|
|
14822
|
-
(0,hooks_namespaceObject.useEffect)(() => {
|
|
14823
|
-
setShowOptions(payload.id === lastEventId);
|
|
14824
|
-
}, [payload, lastEventId]);
|
|
14825
|
-
|
|
14826
|
-
const onChoiceClickHandler = choice => {
|
|
14827
|
-
if (chooseAgain) {
|
|
14828
|
-
addDivider('new_topic');
|
|
14829
|
-
}
|
|
14830
|
-
|
|
14831
|
-
addMessageBubble(choice.text);
|
|
14832
|
-
sendAction({
|
|
14833
|
-
type: actionTypes.pickChoice,
|
|
14834
|
-
originMessage: payload.id,
|
|
14835
|
-
choice: {
|
|
14836
|
-
id: choice.id,
|
|
14837
|
-
text: choice.text,
|
|
14838
|
-
chooseAgain
|
|
14839
|
-
}
|
|
14840
|
-
});
|
|
14841
|
-
setShowOptions(false);
|
|
14842
|
-
};
|
|
14843
|
-
|
|
14844
|
-
const onChooseAgainClickHandler = () => {
|
|
14845
|
-
setShowOptions(s => !s);
|
|
14846
|
-
};
|
|
14847
|
-
|
|
14848
|
-
return {
|
|
14849
|
-
body,
|
|
14850
|
-
subEvent,
|
|
14851
|
-
showOptions,
|
|
14852
|
-
chooseAgain,
|
|
14853
|
-
onChoiceClickHandler,
|
|
14854
|
-
onChooseAgainClickHandler
|
|
14855
|
-
};
|
|
14856
|
-
};
|
|
14857
|
-
|
|
14858
|
-
const ChoicePrompt = _ref => {
|
|
14859
|
-
let {
|
|
14860
|
-
event,
|
|
14861
|
-
children
|
|
14862
|
-
} = _ref,
|
|
14863
|
-
props = choice_prompt_objectWithoutProperties(_ref, choice_prompt_excluded);
|
|
14864
|
-
|
|
14865
|
-
const {
|
|
14866
|
-
t
|
|
14867
|
-
} = useI18n();
|
|
14868
|
-
const descriptorId = useGeneratedId();
|
|
14869
|
-
const {
|
|
14870
|
-
body,
|
|
14871
|
-
subEvent,
|
|
14872
|
-
showOptions,
|
|
14873
|
-
chooseAgain,
|
|
14874
|
-
onChoiceClickHandler,
|
|
14875
|
-
onChooseAgainClickHandler
|
|
14876
|
-
} = useChoicePrompt(event);
|
|
14877
|
-
return (0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
|
|
14878
|
-
children: [(0,external_preact_namespaceObject.toChildArray)(children).map(child => {
|
|
14879
|
-
child.props = choice_prompt_objectSpread(choice_prompt_objectSpread({}, child.props), {}, {
|
|
14880
|
-
event: subEvent,
|
|
14881
|
-
descriptorId,
|
|
14882
|
-
showTranslationToggle: false
|
|
14883
|
-
});
|
|
14884
|
-
return child;
|
|
14885
|
-
}), chooseAgain && (0,jsx_runtime_namespaceObject.jsxs)("button", {
|
|
14886
|
-
type: "button",
|
|
14887
|
-
className: css_className('button', 'button--secondary', 'button--choose-again'),
|
|
14888
|
-
"aria-expanded": showOptions ? 'true' : 'false',
|
|
14889
|
-
onClick: onChooseAgainClickHandler,
|
|
14890
|
-
"aria-describedby": descriptorId,
|
|
14891
|
-
children: [showOptions ? t('message.choicePrompts.cancelChooseAgain') : t('message.choicePrompts.chooseAgain'), (0,jsx_runtime_namespaceObject.jsx)(icon, {
|
|
14892
|
-
name: "chevronDown",
|
|
14893
|
-
size: "8"
|
|
14894
|
-
})]
|
|
14895
|
-
}), showOptions && (0,jsx_runtime_namespaceObject.jsx)(message_container, choice_prompt_objectSpread(choice_prompt_objectSpread({
|
|
14896
|
-
type: "choice-prompt",
|
|
14897
|
-
showParticipant: false,
|
|
14898
|
-
event: event
|
|
14899
|
-
}, props), {}, {
|
|
14900
|
-
children: (0,jsx_runtime_namespaceObject.jsx)("ul", {
|
|
14901
|
-
className: css_className('choice-prompt', 'choice-prompt--many'),
|
|
14902
|
-
children: body.choices.map(choice => (0,jsx_runtime_namespaceObject.jsx)("li", {
|
|
14903
|
-
className: css_className('choice-prompt__item', {
|
|
14904
|
-
[`choice-prompt__item--${choice.category}`]: choice.category
|
|
14905
|
-
}),
|
|
14906
|
-
children: (0,jsx_runtime_namespaceObject.jsx)("button", {
|
|
14907
|
-
type: "button",
|
|
14908
|
-
className: css_className('button', 'button--primary'),
|
|
14909
|
-
onClick: () => {
|
|
14910
|
-
onChoiceClickHandler(choice);
|
|
14911
|
-
},
|
|
14912
|
-
children: choice.text
|
|
14913
|
-
})
|
|
14914
|
-
}, choice.id))
|
|
14915
|
-
})
|
|
14916
|
-
}))]
|
|
14917
|
-
});
|
|
14918
|
-
};
|
|
14919
|
-
|
|
14920
|
-
/* harmony default export */ const choice_prompt = (ChoicePrompt);
|
|
14921
|
-
;// CONCATENATED MODULE: ./node_modules/marked/lib/marked.esm.js
|
|
14922
|
-
/**
|
|
14923
|
-
* marked - a markdown parser
|
|
14924
|
-
* Copyright (c) 2011-2022, Christopher Jeffrey. (MIT Licensed)
|
|
14925
|
-
* https://github.com/markedjs/marked
|
|
14926
|
-
*/
|
|
14927
|
-
|
|
14928
|
-
/**
|
|
14929
|
-
* DO NOT EDIT THIS FILE
|
|
14930
|
-
* The code in this file is generated from files in ./src/
|
|
14931
|
-
*/
|
|
14932
|
-
|
|
14933
|
-
function getDefaults() {
|
|
14934
|
-
return {
|
|
14935
|
-
baseUrl: null,
|
|
14936
|
-
breaks: false,
|
|
14937
|
-
extensions: null,
|
|
14938
|
-
gfm: true,
|
|
14939
|
-
headerIds: true,
|
|
14940
|
-
headerPrefix: '',
|
|
14941
|
-
highlight: null,
|
|
14942
|
-
langPrefix: 'language-',
|
|
14943
|
-
mangle: true,
|
|
14944
|
-
pedantic: false,
|
|
14945
|
-
renderer: null,
|
|
14946
|
-
sanitize: false,
|
|
14947
|
-
sanitizer: null,
|
|
14948
|
-
silent: false,
|
|
14949
|
-
smartLists: false,
|
|
14950
|
-
smartypants: false,
|
|
14951
|
-
tokenizer: null,
|
|
14952
|
-
walkTokens: null,
|
|
14953
|
-
xhtml: false
|
|
14954
|
-
};
|
|
14955
|
-
}
|
|
14956
|
-
|
|
14957
|
-
let defaults = getDefaults();
|
|
14958
|
-
|
|
14959
|
-
function changeDefaults(newDefaults) {
|
|
14960
|
-
defaults = newDefaults;
|
|
14961
|
-
}
|
|
14962
|
-
|
|
14963
|
-
/**
|
|
14964
|
-
* Helpers
|
|
14965
|
-
*/
|
|
14966
|
-
const escapeTest = /[&<>"']/;
|
|
14967
|
-
const escapeReplace = /[&<>"']/g;
|
|
14968
|
-
const escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
|
|
14969
|
-
const escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
|
|
14970
|
-
const escapeReplacements = {
|
|
14971
|
-
'&': '&',
|
|
14972
|
-
'<': '<',
|
|
14973
|
-
'>': '>',
|
|
14974
|
-
'"': '"',
|
|
14975
|
-
"'": '''
|
|
14976
|
-
};
|
|
14977
|
-
const getEscapeReplacement = (ch) => escapeReplacements[ch];
|
|
14978
|
-
function marked_esm_escape(html, encode) {
|
|
14979
|
-
if (encode) {
|
|
14980
|
-
if (escapeTest.test(html)) {
|
|
14981
|
-
return html.replace(escapeReplace, getEscapeReplacement);
|
|
14982
|
-
}
|
|
14983
|
-
} else {
|
|
14984
|
-
if (escapeTestNoEncode.test(html)) {
|
|
14985
|
-
return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
|
|
14986
|
-
}
|
|
14987
|
-
}
|
|
14988
|
-
|
|
14989
|
-
return html;
|
|
14990
|
-
}
|
|
14991
|
-
|
|
14992
|
-
const unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;
|
|
14993
|
-
|
|
14994
|
-
/**
|
|
14995
|
-
* @param {string} html
|
|
14996
|
-
*/
|
|
14997
|
-
function marked_esm_unescape(html) {
|
|
14998
|
-
// explicitly match decimal, hex, and named HTML entities
|
|
14999
|
-
return html.replace(unescapeTest, (_, n) => {
|
|
15000
|
-
n = n.toLowerCase();
|
|
15001
|
-
if (n === 'colon') return ':';
|
|
15002
|
-
if (n.charAt(0) === '#') {
|
|
15003
|
-
return n.charAt(1) === 'x'
|
|
15004
|
-
? String.fromCharCode(parseInt(n.substring(2), 16))
|
|
15005
|
-
: String.fromCharCode(+n.substring(1));
|
|
15006
|
-
}
|
|
15007
|
-
return '';
|
|
15008
|
-
});
|
|
15009
|
-
}
|
|
15010
|
-
|
|
15011
|
-
const caret = /(^|[^\[])\^/g;
|
|
15012
|
-
|
|
15013
|
-
/**
|
|
15014
|
-
* @param {string | RegExp} regex
|
|
15015
|
-
* @param {string} opt
|
|
15016
|
-
*/
|
|
15017
|
-
function edit(regex, opt) {
|
|
15018
|
-
regex = typeof regex === 'string' ? regex : regex.source;
|
|
15019
|
-
opt = opt || '';
|
|
15020
|
-
const obj = {
|
|
15021
|
-
replace: (name, val) => {
|
|
15022
|
-
val = val.source || val;
|
|
15023
|
-
val = val.replace(caret, '$1');
|
|
15024
|
-
regex = regex.replace(name, val);
|
|
15025
|
-
return obj;
|
|
15026
|
-
},
|
|
15027
|
-
getRegex: () => {
|
|
15028
|
-
return new RegExp(regex, opt);
|
|
15029
|
-
}
|
|
15030
|
-
};
|
|
15031
|
-
return obj;
|
|
15032
|
-
}
|
|
15033
|
-
|
|
15034
|
-
const nonWordAndColonTest = /[^\w:]/g;
|
|
15035
|
-
const originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
|
|
15036
|
-
|
|
15037
|
-
/**
|
|
15038
|
-
* @param {boolean} sanitize
|
|
15039
|
-
* @param {string} base
|
|
15040
|
-
* @param {string} href
|
|
15041
|
-
*/
|
|
15042
|
-
function cleanUrl(sanitize, base, href) {
|
|
15043
|
-
if (sanitize) {
|
|
15044
|
-
let prot;
|
|
15045
|
-
try {
|
|
15046
|
-
prot = decodeURIComponent(marked_esm_unescape(href))
|
|
15047
|
-
.replace(nonWordAndColonTest, '')
|
|
15048
|
-
.toLowerCase();
|
|
15049
|
-
} catch (e) {
|
|
15050
|
-
return null;
|
|
15051
|
-
}
|
|
15052
|
-
if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0 || prot.indexOf('data:') === 0) {
|
|
15053
|
-
return null;
|
|
15054
|
-
}
|
|
15055
|
-
}
|
|
15056
|
-
if (base && !originIndependentUrl.test(href)) {
|
|
15057
|
-
href = resolveUrl(base, href);
|
|
15058
|
-
}
|
|
15059
|
-
try {
|
|
15060
|
-
href = encodeURI(href).replace(/%25/g, '%');
|
|
15061
|
-
} catch (e) {
|
|
15062
|
-
return null;
|
|
15063
|
-
}
|
|
15064
|
-
return href;
|
|
15065
|
-
}
|
|
15066
|
-
|
|
15067
|
-
const baseUrls = {};
|
|
15068
|
-
const justDomain = /^[^:]+:\/*[^/]*$/;
|
|
15069
|
-
const protocol = /^([^:]+:)[\s\S]*$/;
|
|
15070
|
-
const domain = /^([^:]+:\/*[^/]*)[\s\S]*$/;
|
|
15071
|
-
|
|
15072
|
-
/**
|
|
15073
|
-
* @param {string} base
|
|
15074
|
-
* @param {string} href
|
|
15075
|
-
*/
|
|
15076
|
-
function resolveUrl(base, href) {
|
|
15077
|
-
if (!baseUrls[' ' + base]) {
|
|
15078
|
-
// we can ignore everything in base after the last slash of its path component,
|
|
15079
|
-
// but we might need to add _that_
|
|
15080
|
-
// https://tools.ietf.org/html/rfc3986#section-3
|
|
15081
|
-
if (justDomain.test(base)) {
|
|
15082
|
-
baseUrls[' ' + base] = base + '/';
|
|
15083
|
-
} else {
|
|
15084
|
-
baseUrls[' ' + base] = rtrim(base, '/', true);
|
|
15085
|
-
}
|
|
15086
|
-
}
|
|
15087
|
-
base = baseUrls[' ' + base];
|
|
15088
|
-
const relativeBase = base.indexOf(':') === -1;
|
|
15089
|
-
|
|
15090
|
-
if (href.substring(0, 2) === '//') {
|
|
15091
|
-
if (relativeBase) {
|
|
15092
|
-
return href;
|
|
15093
|
-
}
|
|
15094
|
-
return base.replace(protocol, '$1') + href;
|
|
15095
|
-
} else if (href.charAt(0) === '/') {
|
|
15096
|
-
if (relativeBase) {
|
|
15097
|
-
return href;
|
|
15098
|
-
}
|
|
15099
|
-
return base.replace(domain, '$1') + href;
|
|
15100
|
-
} else {
|
|
15101
|
-
return base + href;
|
|
15102
|
-
}
|
|
15103
|
-
}
|
|
15104
|
-
|
|
15105
|
-
const noopTest = { exec: function noopTest() {} };
|
|
15106
|
-
|
|
15107
|
-
function merge(obj) {
|
|
15108
|
-
let i = 1,
|
|
15109
|
-
target,
|
|
15110
|
-
key;
|
|
15111
|
-
|
|
15112
|
-
for (; i < arguments.length; i++) {
|
|
15113
|
-
target = arguments[i];
|
|
15114
|
-
for (key in target) {
|
|
15115
|
-
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
|
15116
|
-
obj[key] = target[key];
|
|
15117
|
-
}
|
|
15118
|
-
}
|
|
15119
|
-
}
|
|
15120
|
-
|
|
15121
|
-
return obj;
|
|
15122
|
-
}
|
|
15123
|
-
|
|
15124
|
-
function splitCells(tableRow, count) {
|
|
15125
|
-
// ensure that every cell-delimiting pipe has a space
|
|
15126
|
-
// before it to distinguish it from an escaped pipe
|
|
15127
|
-
const row = tableRow.replace(/\|/g, (match, offset, str) => {
|
|
15128
|
-
let escaped = false,
|
|
15129
|
-
curr = offset;
|
|
15130
|
-
while (--curr >= 0 && str[curr] === '\\') escaped = !escaped;
|
|
15131
|
-
if (escaped) {
|
|
15132
|
-
// odd number of slashes means | is escaped
|
|
15133
|
-
// so we leave it alone
|
|
15134
|
-
return '|';
|
|
15135
|
-
} else {
|
|
15136
|
-
// add space before unescaped |
|
|
15137
|
-
return ' |';
|
|
15138
|
-
}
|
|
15139
|
-
}),
|
|
15140
|
-
cells = row.split(/ \|/);
|
|
15141
|
-
let i = 0;
|
|
15142
|
-
|
|
15143
|
-
// First/last cell in a row cannot be empty if it has no leading/trailing pipe
|
|
15144
|
-
if (!cells[0].trim()) { cells.shift(); }
|
|
15145
|
-
if (cells.length > 0 && !cells[cells.length - 1].trim()) { cells.pop(); }
|
|
15146
|
-
|
|
15147
|
-
if (cells.length > count) {
|
|
15148
|
-
cells.splice(count);
|
|
15149
|
-
} else {
|
|
15150
|
-
while (cells.length < count) cells.push('');
|
|
15151
|
-
}
|
|
15152
|
-
|
|
15153
|
-
for (; i < cells.length; i++) {
|
|
15154
|
-
// leading or trailing whitespace is ignored per the gfm spec
|
|
15155
|
-
cells[i] = cells[i].trim().replace(/\\\|/g, '|');
|
|
15156
|
-
}
|
|
15157
|
-
return cells;
|
|
15158
|
-
}
|
|
15159
|
-
|
|
15160
|
-
/**
|
|
15161
|
-
* Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
|
|
15162
|
-
* /c*$/ is vulnerable to REDOS.
|
|
15163
|
-
*
|
|
15164
|
-
* @param {string} str
|
|
15165
|
-
* @param {string} c
|
|
15166
|
-
* @param {boolean} invert Remove suffix of non-c chars instead. Default falsey.
|
|
15167
|
-
*/
|
|
15168
|
-
function rtrim(str, c, invert) {
|
|
15169
|
-
const l = str.length;
|
|
15170
|
-
if (l === 0) {
|
|
15171
|
-
return '';
|
|
15172
|
-
}
|
|
15173
|
-
|
|
15174
|
-
// Length of suffix matching the invert condition.
|
|
15175
|
-
let suffLen = 0;
|
|
15176
|
-
|
|
15177
|
-
// Step left until we fail to match the invert condition.
|
|
15178
|
-
while (suffLen < l) {
|
|
15179
|
-
const currChar = str.charAt(l - suffLen - 1);
|
|
15180
|
-
if (currChar === c && !invert) {
|
|
15181
|
-
suffLen++;
|
|
15182
|
-
} else if (currChar !== c && invert) {
|
|
15183
|
-
suffLen++;
|
|
15184
|
-
} else {
|
|
15185
|
-
break;
|
|
15186
|
-
}
|
|
15187
|
-
}
|
|
15188
|
-
|
|
15189
|
-
return str.slice(0, l - suffLen);
|
|
15190
|
-
}
|
|
15191
|
-
|
|
15192
|
-
function marked_esm_findClosingBracket(str, b) {
|
|
15193
|
-
if (str.indexOf(b[1]) === -1) {
|
|
15194
|
-
return -1;
|
|
15195
|
-
}
|
|
15196
|
-
const l = str.length;
|
|
15197
|
-
let level = 0,
|
|
15198
|
-
i = 0;
|
|
15199
|
-
for (; i < l; i++) {
|
|
15200
|
-
if (str[i] === '\\') {
|
|
15201
|
-
i++;
|
|
15202
|
-
} else if (str[i] === b[0]) {
|
|
15203
|
-
level++;
|
|
15204
|
-
} else if (str[i] === b[1]) {
|
|
15205
|
-
level--;
|
|
15206
|
-
if (level < 0) {
|
|
15207
|
-
return i;
|
|
15208
|
-
}
|
|
15209
|
-
}
|
|
15210
|
-
}
|
|
15211
|
-
return -1;
|
|
15212
|
-
}
|
|
15213
|
-
|
|
15214
|
-
function checkSanitizeDeprecation(opt) {
|
|
15215
|
-
if (opt && opt.sanitize && !opt.silent) {
|
|
15216
|
-
console.warn('marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options');
|
|
15217
|
-
}
|
|
15218
|
-
}
|
|
15219
|
-
|
|
15220
|
-
// copied from https://stackoverflow.com/a/5450113/806777
|
|
15221
|
-
/**
|
|
15222
|
-
* @param {string} pattern
|
|
15223
|
-
* @param {number} count
|
|
15224
|
-
*/
|
|
15225
|
-
function repeatString(pattern, count) {
|
|
15226
|
-
if (count < 1) {
|
|
15227
|
-
return '';
|
|
15228
|
-
}
|
|
15229
|
-
let result = '';
|
|
15230
|
-
while (count > 1) {
|
|
15231
|
-
if (count & 1) {
|
|
15232
|
-
result += pattern;
|
|
15233
|
-
}
|
|
15234
|
-
count >>= 1;
|
|
15235
|
-
pattern += pattern;
|
|
15236
|
-
}
|
|
15237
|
-
return result + pattern;
|
|
15238
|
-
}
|
|
15239
|
-
|
|
15240
|
-
function outputLink(cap, link, raw, lexer) {
|
|
15241
|
-
const href = link.href;
|
|
15242
|
-
const title = link.title ? marked_esm_escape(link.title) : null;
|
|
15243
|
-
const text = cap[1].replace(/\\([\[\]])/g, '$1');
|
|
15244
|
-
|
|
15245
|
-
if (cap[0].charAt(0) !== '!') {
|
|
15246
|
-
lexer.state.inLink = true;
|
|
15247
|
-
const token = {
|
|
15248
|
-
type: 'link',
|
|
15249
|
-
raw,
|
|
15250
|
-
href,
|
|
15251
|
-
title,
|
|
15252
|
-
text,
|
|
15253
|
-
tokens: lexer.inlineTokens(text, [])
|
|
15254
|
-
};
|
|
15255
|
-
lexer.state.inLink = false;
|
|
15256
|
-
return token;
|
|
15257
|
-
}
|
|
15258
|
-
return {
|
|
15259
|
-
type: 'image',
|
|
15260
|
-
raw,
|
|
15261
|
-
href,
|
|
15262
|
-
title,
|
|
15263
|
-
text: marked_esm_escape(text)
|
|
15264
|
-
};
|
|
15265
|
-
}
|
|
15266
|
-
|
|
15267
|
-
function indentCodeCompensation(raw, text) {
|
|
15268
|
-
const matchIndentToCode = raw.match(/^(\s+)(?:```)/);
|
|
15269
|
-
|
|
15270
|
-
if (matchIndentToCode === null) {
|
|
15271
|
-
return text;
|
|
15272
|
-
}
|
|
15273
|
-
|
|
15274
|
-
const indentToCode = matchIndentToCode[1];
|
|
15275
|
-
|
|
15276
|
-
return text
|
|
15277
|
-
.split('\n')
|
|
15278
|
-
.map(node => {
|
|
15279
|
-
const matchIndentInNode = node.match(/^\s+/);
|
|
15280
|
-
if (matchIndentInNode === null) {
|
|
15281
|
-
return node;
|
|
15282
|
-
}
|
|
15283
|
-
|
|
15284
|
-
const [indentInNode] = matchIndentInNode;
|
|
15285
|
-
|
|
15286
|
-
if (indentInNode.length >= indentToCode.length) {
|
|
15287
|
-
return node.slice(indentToCode.length);
|
|
15288
|
-
}
|
|
15289
|
-
|
|
15290
|
-
return node;
|
|
15291
|
-
})
|
|
15292
|
-
.join('\n');
|
|
15293
|
-
}
|
|
15294
|
-
|
|
15295
|
-
/**
|
|
15296
|
-
* Tokenizer
|
|
15297
|
-
*/
|
|
15298
|
-
class Tokenizer {
|
|
15299
|
-
constructor(options) {
|
|
15300
|
-
this.options = options || defaults;
|
|
15301
|
-
}
|
|
15302
|
-
|
|
15303
|
-
space(src) {
|
|
15304
|
-
const cap = this.rules.block.newline.exec(src);
|
|
15305
|
-
if (cap && cap[0].length > 0) {
|
|
15306
|
-
return {
|
|
15307
|
-
type: 'space',
|
|
15308
|
-
raw: cap[0]
|
|
15309
|
-
};
|
|
15310
|
-
}
|
|
15311
|
-
}
|
|
15312
|
-
|
|
15313
|
-
code(src) {
|
|
15314
|
-
const cap = this.rules.block.code.exec(src);
|
|
15315
|
-
if (cap) {
|
|
15316
|
-
const text = cap[0].replace(/^ {1,4}/gm, '');
|
|
15317
|
-
return {
|
|
15318
|
-
type: 'code',
|
|
15319
|
-
raw: cap[0],
|
|
15320
|
-
codeBlockStyle: 'indented',
|
|
15321
|
-
text: !this.options.pedantic
|
|
15322
|
-
? rtrim(text, '\n')
|
|
15323
|
-
: text
|
|
15324
|
-
};
|
|
15325
|
-
}
|
|
15326
|
-
}
|
|
15327
|
-
|
|
15328
|
-
fences(src) {
|
|
15329
|
-
const cap = this.rules.block.fences.exec(src);
|
|
15330
|
-
if (cap) {
|
|
15331
|
-
const raw = cap[0];
|
|
15332
|
-
const text = indentCodeCompensation(raw, cap[3] || '');
|
|
15333
|
-
|
|
15334
|
-
return {
|
|
15335
|
-
type: 'code',
|
|
15336
|
-
raw,
|
|
15337
|
-
lang: cap[2] ? cap[2].trim() : cap[2],
|
|
15338
|
-
text
|
|
15339
|
-
};
|
|
15340
|
-
}
|
|
15341
|
-
}
|
|
15342
|
-
|
|
15343
|
-
heading(src) {
|
|
15344
|
-
const cap = this.rules.block.heading.exec(src);
|
|
15345
|
-
if (cap) {
|
|
15346
|
-
let text = cap[2].trim();
|
|
15347
|
-
|
|
15348
|
-
// remove trailing #s
|
|
15349
|
-
if (/#$/.test(text)) {
|
|
15350
|
-
const trimmed = rtrim(text, '#');
|
|
15351
|
-
if (this.options.pedantic) {
|
|
15352
|
-
text = trimmed.trim();
|
|
15353
|
-
} else if (!trimmed || / $/.test(trimmed)) {
|
|
15354
|
-
// CommonMark requires space before trailing #s
|
|
15355
|
-
text = trimmed.trim();
|
|
15356
|
-
}
|
|
15357
|
-
}
|
|
15358
|
-
|
|
15359
|
-
const token = {
|
|
15360
|
-
type: 'heading',
|
|
15361
|
-
raw: cap[0],
|
|
15362
|
-
depth: cap[1].length,
|
|
15363
|
-
text,
|
|
15364
|
-
tokens: []
|
|
15365
|
-
};
|
|
15366
|
-
this.lexer.inline(token.text, token.tokens);
|
|
15367
|
-
return token;
|
|
15368
|
-
}
|
|
15369
|
-
}
|
|
15370
|
-
|
|
15371
|
-
hr(src) {
|
|
15372
|
-
const cap = this.rules.block.hr.exec(src);
|
|
15373
|
-
if (cap) {
|
|
15374
|
-
return {
|
|
15375
|
-
type: 'hr',
|
|
15376
|
-
raw: cap[0]
|
|
15377
|
-
};
|
|
15378
|
-
}
|
|
15379
|
-
}
|
|
15380
|
-
|
|
15381
|
-
blockquote(src) {
|
|
15382
|
-
const cap = this.rules.block.blockquote.exec(src);
|
|
15383
|
-
if (cap) {
|
|
15384
|
-
const text = cap[0].replace(/^ *>[ \t]?/gm, '');
|
|
15385
|
-
|
|
15386
|
-
return {
|
|
15387
|
-
type: 'blockquote',
|
|
15388
|
-
raw: cap[0],
|
|
15389
|
-
tokens: this.lexer.blockTokens(text, []),
|
|
15390
|
-
text
|
|
15391
|
-
};
|
|
15392
|
-
}
|
|
15393
|
-
}
|
|
15394
|
-
|
|
15395
|
-
list(src) {
|
|
15396
|
-
let cap = this.rules.block.list.exec(src);
|
|
15397
|
-
if (cap) {
|
|
15398
|
-
let raw, istask, ischecked, indent, i, blankLine, endsWithBlankLine,
|
|
15399
|
-
line, nextLine, rawLine, itemContents, endEarly;
|
|
15400
|
-
|
|
15401
|
-
let bull = cap[1].trim();
|
|
15402
|
-
const isordered = bull.length > 1;
|
|
15403
|
-
|
|
15404
|
-
const list = {
|
|
15405
|
-
type: 'list',
|
|
15406
|
-
raw: '',
|
|
15407
|
-
ordered: isordered,
|
|
15408
|
-
start: isordered ? +bull.slice(0, -1) : '',
|
|
15409
|
-
loose: false,
|
|
15410
|
-
items: []
|
|
15411
|
-
};
|
|
15412
|
-
|
|
15413
|
-
bull = isordered ? `\\d{1,9}\\${bull.slice(-1)}` : `\\${bull}`;
|
|
15414
|
-
|
|
15415
|
-
if (this.options.pedantic) {
|
|
15416
|
-
bull = isordered ? bull : '[*+-]';
|
|
15417
|
-
}
|
|
15418
|
-
|
|
15419
|
-
// Get next list item
|
|
15420
|
-
const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`);
|
|
15421
|
-
|
|
15422
|
-
// Check if current bullet point can start a new List Item
|
|
15423
|
-
while (src) {
|
|
15424
|
-
endEarly = false;
|
|
15425
|
-
if (!(cap = itemRegex.exec(src))) {
|
|
15426
|
-
break;
|
|
15427
|
-
}
|
|
15428
|
-
|
|
15429
|
-
if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)
|
|
15430
|
-
break;
|
|
15431
|
-
}
|
|
15432
|
-
|
|
15433
|
-
raw = cap[0];
|
|
15434
|
-
src = src.substring(raw.length);
|
|
15435
|
-
|
|
15436
|
-
line = cap[2].split('\n', 1)[0];
|
|
15437
|
-
nextLine = src.split('\n', 1)[0];
|
|
15438
|
-
|
|
15439
|
-
if (this.options.pedantic) {
|
|
15440
|
-
indent = 2;
|
|
15441
|
-
itemContents = line.trimLeft();
|
|
15442
|
-
} else {
|
|
15443
|
-
indent = cap[2].search(/[^ ]/); // Find first non-space char
|
|
15444
|
-
indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent
|
|
15445
|
-
itemContents = line.slice(indent);
|
|
15446
|
-
indent += cap[1].length;
|
|
15447
|
-
}
|
|
15448
|
-
|
|
15449
|
-
blankLine = false;
|
|
15450
|
-
|
|
15451
|
-
if (!line && /^ *$/.test(nextLine)) { // Items begin with at most one blank line
|
|
15452
|
-
raw += nextLine + '\n';
|
|
15453
|
-
src = src.substring(nextLine.length + 1);
|
|
15454
|
-
endEarly = true;
|
|
15455
|
-
}
|
|
15456
|
-
|
|
15457
|
-
if (!endEarly) {
|
|
15458
|
-
const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?: [^\\n]*)?(?:\\n|$))`);
|
|
15459
|
-
const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`);
|
|
15460
|
-
const fencesBeginRegex = new RegExp(`^( {0,${Math.min(3, indent - 1)}})(\`\`\`|~~~)`);
|
|
15461
|
-
|
|
15462
|
-
// Check if following lines should be included in List Item
|
|
15463
|
-
while (src) {
|
|
15464
|
-
rawLine = src.split('\n', 1)[0];
|
|
15465
|
-
line = rawLine;
|
|
15466
|
-
|
|
15467
|
-
// Re-align to follow commonmark nesting rules
|
|
15468
|
-
if (this.options.pedantic) {
|
|
15469
|
-
line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' ');
|
|
15470
|
-
}
|
|
15471
|
-
|
|
15472
|
-
// End list item if found code fences
|
|
15473
|
-
if (fencesBeginRegex.test(line)) {
|
|
15474
|
-
break;
|
|
15475
|
-
}
|
|
15476
|
-
|
|
15477
|
-
// End list item if found start of new heading
|
|
15478
|
-
if (this.rules.block.heading.test(line)) {
|
|
15479
|
-
break;
|
|
15480
|
-
}
|
|
15481
|
-
|
|
15482
|
-
// End list item if found start of new bullet
|
|
15483
|
-
if (nextBulletRegex.test(line)) {
|
|
15484
|
-
break;
|
|
15485
|
-
}
|
|
15486
|
-
|
|
15487
|
-
// Horizontal rule found
|
|
15488
|
-
if (hrRegex.test(src)) {
|
|
15489
|
-
break;
|
|
15490
|
-
}
|
|
15491
|
-
|
|
15492
|
-
if (line.search(/[^ ]/) >= indent || !line.trim()) { // Dedent if possible
|
|
15493
|
-
itemContents += '\n' + line.slice(indent);
|
|
15494
|
-
} else if (!blankLine) { // Until blank line, item doesn't need indentation
|
|
15495
|
-
itemContents += '\n' + line;
|
|
15496
|
-
} else { // Otherwise, improper indentation ends this item
|
|
15497
|
-
break;
|
|
15498
|
-
}
|
|
15499
|
-
|
|
15500
|
-
if (!blankLine && !line.trim()) { // Check if current line is blank
|
|
15501
|
-
blankLine = true;
|
|
15502
|
-
}
|
|
15503
|
-
|
|
15504
|
-
raw += rawLine + '\n';
|
|
15505
|
-
src = src.substring(rawLine.length + 1);
|
|
15506
|
-
}
|
|
15507
|
-
}
|
|
15508
|
-
|
|
15509
|
-
if (!list.loose) {
|
|
15510
|
-
// If the previous item ended with a blank line, the list is loose
|
|
15511
|
-
if (endsWithBlankLine) {
|
|
15512
|
-
list.loose = true;
|
|
15513
|
-
} else if (/\n *\n *$/.test(raw)) {
|
|
15514
|
-
endsWithBlankLine = true;
|
|
15515
|
-
}
|
|
15516
|
-
}
|
|
15517
|
-
|
|
15518
|
-
// Check for task list items
|
|
15519
|
-
if (this.options.gfm) {
|
|
15520
|
-
istask = /^\[[ xX]\] /.exec(itemContents);
|
|
15521
|
-
if (istask) {
|
|
15522
|
-
ischecked = istask[0] !== '[ ] ';
|
|
15523
|
-
itemContents = itemContents.replace(/^\[[ xX]\] +/, '');
|
|
15524
|
-
}
|
|
15525
|
-
}
|
|
15526
|
-
|
|
15527
|
-
list.items.push({
|
|
15528
|
-
type: 'list_item',
|
|
15529
|
-
raw,
|
|
15530
|
-
task: !!istask,
|
|
15531
|
-
checked: ischecked,
|
|
15532
|
-
loose: false,
|
|
15533
|
-
text: itemContents
|
|
15534
|
-
});
|
|
15535
|
-
|
|
15536
|
-
list.raw += raw;
|
|
15537
|
-
}
|
|
15538
|
-
|
|
15539
|
-
// Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic
|
|
15540
|
-
list.items[list.items.length - 1].raw = raw.trimRight();
|
|
15541
|
-
list.items[list.items.length - 1].text = itemContents.trimRight();
|
|
15542
|
-
list.raw = list.raw.trimRight();
|
|
15543
|
-
|
|
15544
|
-
const l = list.items.length;
|
|
15545
|
-
|
|
15546
|
-
// Item child tokens handled here at end because we needed to have the final item to trim it first
|
|
15547
|
-
for (i = 0; i < l; i++) {
|
|
15548
|
-
this.lexer.state.top = false;
|
|
15549
|
-
list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);
|
|
15550
|
-
const spacers = list.items[i].tokens.filter(t => t.type === 'space');
|
|
15551
|
-
const hasMultipleLineBreaks = spacers.every(t => {
|
|
15552
|
-
const chars = t.raw.split('');
|
|
15553
|
-
let lineBreaks = 0;
|
|
15554
|
-
for (const char of chars) {
|
|
15555
|
-
if (char === '\n') {
|
|
15556
|
-
lineBreaks += 1;
|
|
15557
|
-
}
|
|
15558
|
-
if (lineBreaks > 1) {
|
|
15559
|
-
return true;
|
|
15560
|
-
}
|
|
15561
|
-
}
|
|
15562
|
-
|
|
15563
|
-
return false;
|
|
15564
|
-
});
|
|
15565
|
-
|
|
15566
|
-
if (!list.loose && spacers.length && hasMultipleLineBreaks) {
|
|
15567
|
-
// Having a single line break doesn't mean a list is loose. A single line break is terminating the last list item
|
|
15568
|
-
list.loose = true;
|
|
15569
|
-
list.items[i].loose = true;
|
|
15570
|
-
}
|
|
15571
|
-
}
|
|
15572
|
-
|
|
15573
|
-
return list;
|
|
15574
|
-
}
|
|
15575
|
-
}
|
|
15576
|
-
|
|
15577
|
-
html(src) {
|
|
15578
|
-
const cap = this.rules.block.html.exec(src);
|
|
15579
|
-
if (cap) {
|
|
15580
|
-
const token = {
|
|
15581
|
-
type: 'html',
|
|
15582
|
-
raw: cap[0],
|
|
15583
|
-
pre: !this.options.sanitizer
|
|
15584
|
-
&& (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
|
|
15585
|
-
text: cap[0]
|
|
15586
|
-
};
|
|
15587
|
-
if (this.options.sanitize) {
|
|
15588
|
-
token.type = 'paragraph';
|
|
15589
|
-
token.text = this.options.sanitizer ? this.options.sanitizer(cap[0]) : marked_esm_escape(cap[0]);
|
|
15590
|
-
token.tokens = [];
|
|
15591
|
-
this.lexer.inline(token.text, token.tokens);
|
|
15592
|
-
}
|
|
15593
|
-
return token;
|
|
15594
|
-
}
|
|
15595
|
-
}
|
|
15596
|
-
|
|
15597
|
-
def(src) {
|
|
15598
|
-
const cap = this.rules.block.def.exec(src);
|
|
15599
|
-
if (cap) {
|
|
15600
|
-
if (cap[3]) cap[3] = cap[3].substring(1, cap[3].length - 1);
|
|
15601
|
-
const tag = cap[1].toLowerCase().replace(/\s+/g, ' ');
|
|
15602
|
-
return {
|
|
15603
|
-
type: 'def',
|
|
15604
|
-
tag,
|
|
15605
|
-
raw: cap[0],
|
|
15606
|
-
href: cap[2],
|
|
15607
|
-
title: cap[3]
|
|
15608
|
-
};
|
|
15609
|
-
}
|
|
15610
|
-
}
|
|
15611
|
-
|
|
15612
|
-
table(src) {
|
|
15613
|
-
const cap = this.rules.block.table.exec(src);
|
|
15614
|
-
if (cap) {
|
|
15615
|
-
const item = {
|
|
15616
|
-
type: 'table',
|
|
15617
|
-
header: splitCells(cap[1]).map(c => { return { text: c }; }),
|
|
15618
|
-
align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
|
|
15619
|
-
rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : []
|
|
15620
|
-
};
|
|
15621
|
-
|
|
15622
|
-
if (item.header.length === item.align.length) {
|
|
15623
|
-
item.raw = cap[0];
|
|
15624
|
-
|
|
15625
|
-
let l = item.align.length;
|
|
15626
|
-
let i, j, k, row;
|
|
15627
|
-
for (i = 0; i < l; i++) {
|
|
15628
|
-
if (/^ *-+: *$/.test(item.align[i])) {
|
|
15629
|
-
item.align[i] = 'right';
|
|
15630
|
-
} else if (/^ *:-+: *$/.test(item.align[i])) {
|
|
15631
|
-
item.align[i] = 'center';
|
|
15632
|
-
} else if (/^ *:-+ *$/.test(item.align[i])) {
|
|
15633
|
-
item.align[i] = 'left';
|
|
15634
|
-
} else {
|
|
15635
|
-
item.align[i] = null;
|
|
15636
|
-
}
|
|
15637
|
-
}
|
|
15638
|
-
|
|
15639
|
-
l = item.rows.length;
|
|
15640
|
-
for (i = 0; i < l; i++) {
|
|
15641
|
-
item.rows[i] = splitCells(item.rows[i], item.header.length).map(c => { return { text: c }; });
|
|
15642
|
-
}
|
|
15643
|
-
|
|
15644
|
-
// parse child tokens inside headers and cells
|
|
15645
|
-
|
|
15646
|
-
// header child tokens
|
|
15647
|
-
l = item.header.length;
|
|
15648
|
-
for (j = 0; j < l; j++) {
|
|
15649
|
-
item.header[j].tokens = [];
|
|
15650
|
-
this.lexer.inline(item.header[j].text, item.header[j].tokens);
|
|
15651
|
-
}
|
|
15652
|
-
|
|
15653
|
-
// cell child tokens
|
|
15654
|
-
l = item.rows.length;
|
|
15655
|
-
for (j = 0; j < l; j++) {
|
|
15656
|
-
row = item.rows[j];
|
|
15657
|
-
for (k = 0; k < row.length; k++) {
|
|
15658
|
-
row[k].tokens = [];
|
|
15659
|
-
this.lexer.inline(row[k].text, row[k].tokens);
|
|
15660
|
-
}
|
|
15661
|
-
}
|
|
15662
|
-
|
|
15663
|
-
return item;
|
|
15664
|
-
}
|
|
15665
|
-
}
|
|
15666
|
-
}
|
|
15667
|
-
|
|
15668
|
-
lheading(src) {
|
|
15669
|
-
const cap = this.rules.block.lheading.exec(src);
|
|
15670
|
-
if (cap) {
|
|
15671
|
-
const token = {
|
|
15672
|
-
type: 'heading',
|
|
15673
|
-
raw: cap[0],
|
|
15674
|
-
depth: cap[2].charAt(0) === '=' ? 1 : 2,
|
|
15675
|
-
text: cap[1],
|
|
15676
|
-
tokens: []
|
|
15677
|
-
};
|
|
15678
|
-
this.lexer.inline(token.text, token.tokens);
|
|
15679
|
-
return token;
|
|
15680
|
-
}
|
|
15681
|
-
}
|
|
15682
|
-
|
|
15683
|
-
paragraph(src) {
|
|
15684
|
-
const cap = this.rules.block.paragraph.exec(src);
|
|
15685
|
-
if (cap) {
|
|
15686
|
-
const token = {
|
|
15687
|
-
type: 'paragraph',
|
|
15688
|
-
raw: cap[0],
|
|
15689
|
-
text: cap[1].charAt(cap[1].length - 1) === '\n'
|
|
15690
|
-
? cap[1].slice(0, -1)
|
|
15691
|
-
: cap[1],
|
|
15692
|
-
tokens: []
|
|
15693
|
-
};
|
|
15694
|
-
this.lexer.inline(token.text, token.tokens);
|
|
15695
|
-
return token;
|
|
15696
|
-
}
|
|
15697
|
-
}
|
|
15698
|
-
|
|
15699
|
-
text(src) {
|
|
15700
|
-
const cap = this.rules.block.text.exec(src);
|
|
15701
|
-
if (cap) {
|
|
15702
|
-
const token = {
|
|
15703
|
-
type: 'text',
|
|
15704
|
-
raw: cap[0],
|
|
15705
|
-
text: cap[0],
|
|
15706
|
-
tokens: []
|
|
15707
|
-
};
|
|
15708
|
-
this.lexer.inline(token.text, token.tokens);
|
|
15709
|
-
return token;
|
|
15710
|
-
}
|
|
15711
|
-
}
|
|
15712
|
-
|
|
15713
|
-
escape(src) {
|
|
15714
|
-
const cap = this.rules.inline.escape.exec(src);
|
|
15715
|
-
if (cap) {
|
|
15716
|
-
return {
|
|
15717
|
-
type: 'escape',
|
|
15718
|
-
raw: cap[0],
|
|
15719
|
-
text: marked_esm_escape(cap[1])
|
|
15720
|
-
};
|
|
15721
|
-
}
|
|
15722
|
-
}
|
|
15723
|
-
|
|
15724
|
-
tag(src) {
|
|
15725
|
-
const cap = this.rules.inline.tag.exec(src);
|
|
15726
|
-
if (cap) {
|
|
15727
|
-
if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {
|
|
15728
|
-
this.lexer.state.inLink = true;
|
|
15729
|
-
} else if (this.lexer.state.inLink && /^<\/a>/i.test(cap[0])) {
|
|
15730
|
-
this.lexer.state.inLink = false;
|
|
15731
|
-
}
|
|
15732
|
-
if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
|
|
15733
|
-
this.lexer.state.inRawBlock = true;
|
|
15734
|
-
} else if (this.lexer.state.inRawBlock && /^<\/(pre|code|kbd|script)(\s|>)/i.test(cap[0])) {
|
|
15735
|
-
this.lexer.state.inRawBlock = false;
|
|
15736
|
-
}
|
|
15737
|
-
|
|
15738
|
-
return {
|
|
15739
|
-
type: this.options.sanitize
|
|
15740
|
-
? 'text'
|
|
15741
|
-
: 'html',
|
|
15742
|
-
raw: cap[0],
|
|
15743
|
-
inLink: this.lexer.state.inLink,
|
|
15744
|
-
inRawBlock: this.lexer.state.inRawBlock,
|
|
15745
|
-
text: this.options.sanitize
|
|
15746
|
-
? (this.options.sanitizer
|
|
15747
|
-
? this.options.sanitizer(cap[0])
|
|
15748
|
-
: marked_esm_escape(cap[0]))
|
|
15749
|
-
: cap[0]
|
|
15750
|
-
};
|
|
15751
|
-
}
|
|
15752
|
-
}
|
|
15753
|
-
|
|
15754
|
-
link(src) {
|
|
15755
|
-
const cap = this.rules.inline.link.exec(src);
|
|
15756
|
-
if (cap) {
|
|
15757
|
-
const trimmedUrl = cap[2].trim();
|
|
15758
|
-
if (!this.options.pedantic && /^</.test(trimmedUrl)) {
|
|
15759
|
-
// commonmark requires matching angle brackets
|
|
15760
|
-
if (!(/>$/.test(trimmedUrl))) {
|
|
15761
|
-
return;
|
|
15762
|
-
}
|
|
15763
|
-
|
|
15764
|
-
// ending angle bracket cannot be escaped
|
|
15765
|
-
const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\');
|
|
15766
|
-
if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {
|
|
15767
|
-
return;
|
|
15768
|
-
}
|
|
15769
|
-
} else {
|
|
15770
|
-
// find closing parenthesis
|
|
15771
|
-
const lastParenIndex = marked_esm_findClosingBracket(cap[2], '()');
|
|
15772
|
-
if (lastParenIndex > -1) {
|
|
15773
|
-
const start = cap[0].indexOf('!') === 0 ? 5 : 4;
|
|
15774
|
-
const linkLen = start + cap[1].length + lastParenIndex;
|
|
15775
|
-
cap[2] = cap[2].substring(0, lastParenIndex);
|
|
15776
|
-
cap[0] = cap[0].substring(0, linkLen).trim();
|
|
15777
|
-
cap[3] = '';
|
|
15778
|
-
}
|
|
15779
|
-
}
|
|
15780
|
-
let href = cap[2];
|
|
15781
|
-
let title = '';
|
|
15782
|
-
if (this.options.pedantic) {
|
|
15783
|
-
// split pedantic href and title
|
|
15784
|
-
const link = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(href);
|
|
15785
|
-
|
|
15786
|
-
if (link) {
|
|
15787
|
-
href = link[1];
|
|
15788
|
-
title = link[3];
|
|
15789
|
-
}
|
|
15790
|
-
} else {
|
|
15791
|
-
title = cap[3] ? cap[3].slice(1, -1) : '';
|
|
15792
|
-
}
|
|
15793
|
-
|
|
15794
|
-
href = href.trim();
|
|
15795
|
-
if (/^</.test(href)) {
|
|
15796
|
-
if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {
|
|
15797
|
-
// pedantic allows starting angle bracket without ending angle bracket
|
|
15798
|
-
href = href.slice(1);
|
|
15799
|
-
} else {
|
|
15800
|
-
href = href.slice(1, -1);
|
|
15801
|
-
}
|
|
15802
|
-
}
|
|
15803
|
-
return outputLink(cap, {
|
|
15804
|
-
href: href ? href.replace(this.rules.inline._escapes, '$1') : href,
|
|
15805
|
-
title: title ? title.replace(this.rules.inline._escapes, '$1') : title
|
|
15806
|
-
}, cap[0], this.lexer);
|
|
15807
|
-
}
|
|
15808
|
-
}
|
|
15809
|
-
|
|
15810
|
-
reflink(src, links) {
|
|
15811
|
-
let cap;
|
|
15812
|
-
if ((cap = this.rules.inline.reflink.exec(src))
|
|
15813
|
-
|| (cap = this.rules.inline.nolink.exec(src))) {
|
|
15814
|
-
let link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
|
|
15815
|
-
link = links[link.toLowerCase()];
|
|
15816
|
-
if (!link || !link.href) {
|
|
15817
|
-
const text = cap[0].charAt(0);
|
|
15818
|
-
return {
|
|
15819
|
-
type: 'text',
|
|
15820
|
-
raw: text,
|
|
15821
|
-
text
|
|
15822
|
-
};
|
|
15823
|
-
}
|
|
15824
|
-
return outputLink(cap, link, cap[0], this.lexer);
|
|
15825
|
-
}
|
|
15826
|
-
}
|
|
15827
|
-
|
|
15828
|
-
emStrong(src, maskedSrc, prevChar = '') {
|
|
15829
|
-
let match = this.rules.inline.emStrong.lDelim.exec(src);
|
|
15830
|
-
if (!match) return;
|
|
15831
|
-
|
|
15832
|
-
// _ can't be between two alphanumerics. \p{L}\p{N} includes non-english alphabet/numbers as well
|
|
15833
|
-
if (match[3] && prevChar.match(/[\p{L}\p{N}]/u)) return;
|
|
15834
|
-
|
|
15835
|
-
const nextChar = match[1] || match[2] || '';
|
|
15836
|
-
|
|
15837
|
-
if (!nextChar || (nextChar && (prevChar === '' || this.rules.inline.punctuation.exec(prevChar)))) {
|
|
15838
|
-
const lLength = match[0].length - 1;
|
|
15839
|
-
let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;
|
|
15840
|
-
|
|
15841
|
-
const endReg = match[0][0] === '*' ? this.rules.inline.emStrong.rDelimAst : this.rules.inline.emStrong.rDelimUnd;
|
|
15842
|
-
endReg.lastIndex = 0;
|
|
15843
|
-
|
|
15844
|
-
// Clip maskedSrc to same section of string as src (move to lexer?)
|
|
15845
|
-
maskedSrc = maskedSrc.slice(-1 * src.length + lLength);
|
|
15846
|
-
|
|
15847
|
-
while ((match = endReg.exec(maskedSrc)) != null) {
|
|
15848
|
-
rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];
|
|
15849
|
-
|
|
15850
|
-
if (!rDelim) continue; // skip single * in __abc*abc__
|
|
15851
|
-
|
|
15852
|
-
rLength = rDelim.length;
|
|
15853
|
-
|
|
15854
|
-
if (match[3] || match[4]) { // found another Left Delim
|
|
15855
|
-
delimTotal += rLength;
|
|
15856
|
-
continue;
|
|
15857
|
-
} else if (match[5] || match[6]) { // either Left or Right Delim
|
|
15858
|
-
if (lLength % 3 && !((lLength + rLength) % 3)) {
|
|
15859
|
-
midDelimTotal += rLength;
|
|
15860
|
-
continue; // CommonMark Emphasis Rules 9-10
|
|
15861
|
-
}
|
|
15862
|
-
}
|
|
15863
|
-
|
|
15864
|
-
delimTotal -= rLength;
|
|
15865
|
-
|
|
15866
|
-
if (delimTotal > 0) continue; // Haven't found enough closing delimiters
|
|
15867
|
-
|
|
15868
|
-
// Remove extra characters. *a*** -> *a*
|
|
15869
|
-
rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);
|
|
15870
|
-
|
|
15871
|
-
// Create `em` if smallest delimiter has odd char count. *a***
|
|
15872
|
-
if (Math.min(lLength, rLength) % 2) {
|
|
15873
|
-
const text = src.slice(1, lLength + match.index + rLength);
|
|
15874
|
-
return {
|
|
15875
|
-
type: 'em',
|
|
15876
|
-
raw: src.slice(0, lLength + match.index + rLength + 1),
|
|
15877
|
-
text,
|
|
15878
|
-
tokens: this.lexer.inlineTokens(text, [])
|
|
15879
|
-
};
|
|
15880
|
-
}
|
|
15881
|
-
|
|
15882
|
-
// Create 'strong' if smallest delimiter has even char count. **a***
|
|
15883
|
-
const text = src.slice(2, lLength + match.index + rLength - 1);
|
|
15884
|
-
return {
|
|
15885
|
-
type: 'strong',
|
|
15886
|
-
raw: src.slice(0, lLength + match.index + rLength + 1),
|
|
15887
|
-
text,
|
|
15888
|
-
tokens: this.lexer.inlineTokens(text, [])
|
|
15889
|
-
};
|
|
15890
|
-
}
|
|
15891
|
-
}
|
|
15892
|
-
}
|
|
15893
|
-
|
|
15894
|
-
codespan(src) {
|
|
15895
|
-
const cap = this.rules.inline.code.exec(src);
|
|
15896
|
-
if (cap) {
|
|
15897
|
-
let text = cap[2].replace(/\n/g, ' ');
|
|
15898
|
-
const hasNonSpaceChars = /[^ ]/.test(text);
|
|
15899
|
-
const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);
|
|
15900
|
-
if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {
|
|
15901
|
-
text = text.substring(1, text.length - 1);
|
|
15902
|
-
}
|
|
15903
|
-
text = marked_esm_escape(text, true);
|
|
15904
|
-
return {
|
|
15905
|
-
type: 'codespan',
|
|
15906
|
-
raw: cap[0],
|
|
15907
|
-
text
|
|
15908
|
-
};
|
|
15909
|
-
}
|
|
15910
|
-
}
|
|
15911
|
-
|
|
15912
|
-
br(src) {
|
|
15913
|
-
const cap = this.rules.inline.br.exec(src);
|
|
15914
|
-
if (cap) {
|
|
15915
|
-
return {
|
|
15916
|
-
type: 'br',
|
|
15917
|
-
raw: cap[0]
|
|
15918
|
-
};
|
|
15919
|
-
}
|
|
15920
|
-
}
|
|
15921
|
-
|
|
15922
|
-
del(src) {
|
|
15923
|
-
const cap = this.rules.inline.del.exec(src);
|
|
15924
|
-
if (cap) {
|
|
15925
|
-
return {
|
|
15926
|
-
type: 'del',
|
|
15927
|
-
raw: cap[0],
|
|
15928
|
-
text: cap[2],
|
|
15929
|
-
tokens: this.lexer.inlineTokens(cap[2], [])
|
|
15930
|
-
};
|
|
15931
|
-
}
|
|
15932
|
-
}
|
|
15933
|
-
|
|
15934
|
-
autolink(src, mangle) {
|
|
15935
|
-
const cap = this.rules.inline.autolink.exec(src);
|
|
15936
|
-
if (cap) {
|
|
15937
|
-
let text, href;
|
|
15938
|
-
if (cap[2] === '@') {
|
|
15939
|
-
text = marked_esm_escape(this.options.mangle ? mangle(cap[1]) : cap[1]);
|
|
15940
|
-
href = 'mailto:' + text;
|
|
15941
|
-
} else {
|
|
15942
|
-
text = marked_esm_escape(cap[1]);
|
|
15943
|
-
href = text;
|
|
15944
|
-
}
|
|
15945
|
-
|
|
15946
|
-
return {
|
|
15947
|
-
type: 'link',
|
|
15948
|
-
raw: cap[0],
|
|
15949
|
-
text,
|
|
15950
|
-
href,
|
|
15951
|
-
tokens: [
|
|
15952
|
-
{
|
|
15953
|
-
type: 'text',
|
|
15954
|
-
raw: text,
|
|
15955
|
-
text
|
|
15956
|
-
}
|
|
15957
|
-
]
|
|
15958
|
-
};
|
|
15959
|
-
}
|
|
15960
|
-
}
|
|
15961
|
-
|
|
15962
|
-
url(src, mangle) {
|
|
15963
|
-
let cap;
|
|
15964
|
-
if (cap = this.rules.inline.url.exec(src)) {
|
|
15965
|
-
let text, href;
|
|
15966
|
-
if (cap[2] === '@') {
|
|
15967
|
-
text = marked_esm_escape(this.options.mangle ? mangle(cap[0]) : cap[0]);
|
|
15968
|
-
href = 'mailto:' + text;
|
|
15969
|
-
} else {
|
|
15970
|
-
// do extended autolink path validation
|
|
15971
|
-
let prevCapZero;
|
|
15972
|
-
do {
|
|
15973
|
-
prevCapZero = cap[0];
|
|
15974
|
-
cap[0] = this.rules.inline._backpedal.exec(cap[0])[0];
|
|
15975
|
-
} while (prevCapZero !== cap[0]);
|
|
15976
|
-
text = marked_esm_escape(cap[0]);
|
|
15977
|
-
if (cap[1] === 'www.') {
|
|
15978
|
-
href = 'http://' + text;
|
|
15979
|
-
} else {
|
|
15980
|
-
href = text;
|
|
15981
|
-
}
|
|
15982
|
-
}
|
|
15983
|
-
return {
|
|
15984
|
-
type: 'link',
|
|
15985
|
-
raw: cap[0],
|
|
15986
|
-
text,
|
|
15987
|
-
href,
|
|
15988
|
-
tokens: [
|
|
15989
|
-
{
|
|
15990
|
-
type: 'text',
|
|
15991
|
-
raw: text,
|
|
15992
|
-
text
|
|
15993
|
-
}
|
|
15994
|
-
]
|
|
15995
|
-
};
|
|
15996
|
-
}
|
|
15997
|
-
}
|
|
15998
|
-
|
|
15999
|
-
inlineText(src, smartypants) {
|
|
16000
|
-
const cap = this.rules.inline.text.exec(src);
|
|
16001
|
-
if (cap) {
|
|
16002
|
-
let text;
|
|
16003
|
-
if (this.lexer.state.inRawBlock) {
|
|
16004
|
-
text = this.options.sanitize ? (this.options.sanitizer ? this.options.sanitizer(cap[0]) : marked_esm_escape(cap[0])) : cap[0];
|
|
16005
|
-
} else {
|
|
16006
|
-
text = marked_esm_escape(this.options.smartypants ? smartypants(cap[0]) : cap[0]);
|
|
16007
|
-
}
|
|
16008
|
-
return {
|
|
16009
|
-
type: 'text',
|
|
16010
|
-
raw: cap[0],
|
|
16011
|
-
text
|
|
16012
|
-
};
|
|
16013
|
-
}
|
|
16014
|
-
}
|
|
16015
|
-
}
|
|
16016
|
-
|
|
16017
|
-
/**
|
|
16018
|
-
* Block-Level Grammar
|
|
16019
|
-
*/
|
|
16020
|
-
const block = {
|
|
16021
|
-
newline: /^(?: *(?:\n|$))+/,
|
|
16022
|
-
code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
|
|
16023
|
-
fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
|
|
16024
|
-
hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
|
|
16025
|
-
heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
|
|
16026
|
-
blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
|
|
16027
|
-
list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
|
|
16028
|
-
html: '^ {0,3}(?:' // optional indentation
|
|
16029
|
-
+ '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)' // (1)
|
|
16030
|
-
+ '|comment[^\\n]*(\\n+|$)' // (2)
|
|
16031
|
-
+ '|<\\?[\\s\\S]*?(?:\\?>\\n*|$)' // (3)
|
|
16032
|
-
+ '|<![A-Z][\\s\\S]*?(?:>\\n*|$)' // (4)
|
|
16033
|
-
+ '|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)' // (5)
|
|
16034
|
-
+ '|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (6)
|
|
16035
|
-
+ '|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) open tag
|
|
16036
|
-
+ '|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)' // (7) closing tag
|
|
16037
|
-
+ ')',
|
|
16038
|
-
def: /^ {0,3}\[(label)\]: *(?:\n *)?<?([^\s>]+)>?(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
|
|
16039
|
-
table: noopTest,
|
|
16040
|
-
lheading: /^([^\n]+)\n {0,3}(=+|-+) *(?:\n+|$)/,
|
|
16041
|
-
// regex template, placeholders will be replaced according to different paragraph
|
|
16042
|
-
// interruption rules of commonmark and the original markdown spec:
|
|
16043
|
-
_paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
|
|
16044
|
-
text: /^[^\n]+/
|
|
16045
|
-
};
|
|
16046
|
-
|
|
16047
|
-
block._label = /(?!\s*\])(?:\\.|[^\[\]\\])+/;
|
|
16048
|
-
block._title = /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;
|
|
16049
|
-
block.def = edit(block.def)
|
|
16050
|
-
.replace('label', block._label)
|
|
16051
|
-
.replace('title', block._title)
|
|
16052
|
-
.getRegex();
|
|
16053
|
-
|
|
16054
|
-
block.bullet = /(?:[*+-]|\d{1,9}[.)])/;
|
|
16055
|
-
block.listItemStart = edit(/^( *)(bull) */)
|
|
16056
|
-
.replace('bull', block.bullet)
|
|
16057
|
-
.getRegex();
|
|
16058
|
-
|
|
16059
|
-
block.list = edit(block.list)
|
|
16060
|
-
.replace(/bull/g, block.bullet)
|
|
16061
|
-
.replace('hr', '\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))')
|
|
16062
|
-
.replace('def', '\\n+(?=' + block.def.source + ')')
|
|
16063
|
-
.getRegex();
|
|
16064
|
-
|
|
16065
|
-
block._tag = 'address|article|aside|base|basefont|blockquote|body|caption'
|
|
16066
|
-
+ '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'
|
|
16067
|
-
+ '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'
|
|
16068
|
-
+ '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'
|
|
16069
|
-
+ '|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr'
|
|
16070
|
-
+ '|track|ul';
|
|
16071
|
-
block._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/;
|
|
16072
|
-
block.html = edit(block.html, 'i')
|
|
16073
|
-
.replace('comment', block._comment)
|
|
16074
|
-
.replace('tag', block._tag)
|
|
16075
|
-
.replace('attribute', / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/)
|
|
16076
|
-
.getRegex();
|
|
16077
|
-
|
|
16078
|
-
block.paragraph = edit(block._paragraph)
|
|
16079
|
-
.replace('hr', block.hr)
|
|
16080
|
-
.replace('heading', ' {0,3}#{1,6} ')
|
|
16081
|
-
.replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
|
|
16082
|
-
.replace('|table', '')
|
|
16083
|
-
.replace('blockquote', ' {0,3}>')
|
|
16084
|
-
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
16085
|
-
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
16086
|
-
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
16087
|
-
.replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
|
|
16088
|
-
.getRegex();
|
|
16089
|
-
|
|
16090
|
-
block.blockquote = edit(block.blockquote)
|
|
16091
|
-
.replace('paragraph', block.paragraph)
|
|
16092
|
-
.getRegex();
|
|
16093
|
-
|
|
16094
|
-
/**
|
|
16095
|
-
* Normal Block Grammar
|
|
16096
|
-
*/
|
|
16097
|
-
|
|
16098
|
-
block.normal = merge({}, block);
|
|
16099
|
-
|
|
16100
|
-
/**
|
|
16101
|
-
* GFM Block Grammar
|
|
16102
|
-
*/
|
|
16103
|
-
|
|
16104
|
-
block.gfm = merge({}, block.normal, {
|
|
16105
|
-
table: '^ *([^\\n ].*\\|.*)\\n' // Header
|
|
16106
|
-
+ ' {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?' // Align
|
|
16107
|
-
+ '(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)' // Cells
|
|
16108
|
-
});
|
|
16109
|
-
|
|
16110
|
-
block.gfm.table = edit(block.gfm.table)
|
|
16111
|
-
.replace('hr', block.hr)
|
|
16112
|
-
.replace('heading', ' {0,3}#{1,6} ')
|
|
16113
|
-
.replace('blockquote', ' {0,3}>')
|
|
16114
|
-
.replace('code', ' {4}[^\\n]')
|
|
16115
|
-
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
16116
|
-
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
16117
|
-
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
16118
|
-
.replace('tag', block._tag) // tables can be interrupted by type (6) html blocks
|
|
16119
|
-
.getRegex();
|
|
16120
|
-
|
|
16121
|
-
block.gfm.paragraph = edit(block._paragraph)
|
|
16122
|
-
.replace('hr', block.hr)
|
|
16123
|
-
.replace('heading', ' {0,3}#{1,6} ')
|
|
16124
|
-
.replace('|lheading', '') // setex headings don't interrupt commonmark paragraphs
|
|
16125
|
-
.replace('table', block.gfm.table) // interrupt paragraphs with table
|
|
16126
|
-
.replace('blockquote', ' {0,3}>')
|
|
16127
|
-
.replace('fences', ' {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n')
|
|
16128
|
-
.replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt
|
|
16129
|
-
.replace('html', '</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)')
|
|
16130
|
-
.replace('tag', block._tag) // pars can be interrupted by type (6) html blocks
|
|
16131
|
-
.getRegex();
|
|
16132
|
-
/**
|
|
16133
|
-
* Pedantic grammar (original John Gruber's loose markdown specification)
|
|
16134
|
-
*/
|
|
16135
|
-
|
|
16136
|
-
block.pedantic = merge({}, block.normal, {
|
|
16137
|
-
html: edit(
|
|
16138
|
-
'^ *(?:comment *(?:\\n|\\s*$)'
|
|
16139
|
-
+ '|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)' // closed tag
|
|
16140
|
-
+ '|<tag(?:"[^"]*"|\'[^\']*\'|\\s[^\'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))')
|
|
16141
|
-
.replace('comment', block._comment)
|
|
16142
|
-
.replace(/tag/g, '(?!(?:'
|
|
16143
|
-
+ 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'
|
|
16144
|
-
+ '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'
|
|
16145
|
-
+ '\\b)\\w+(?!:|[^\\w\\s@]*@)\\b')
|
|
16146
|
-
.getRegex(),
|
|
16147
|
-
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
|
|
16148
|
-
heading: /^(#{1,6})(.*)(?:\n+|$)/,
|
|
16149
|
-
fences: noopTest, // fences not supported
|
|
16150
|
-
paragraph: edit(block.normal._paragraph)
|
|
16151
|
-
.replace('hr', block.hr)
|
|
16152
|
-
.replace('heading', ' *#{1,6} *[^\n]')
|
|
16153
|
-
.replace('lheading', block.lheading)
|
|
16154
|
-
.replace('blockquote', ' {0,3}>')
|
|
16155
|
-
.replace('|fences', '')
|
|
16156
|
-
.replace('|list', '')
|
|
16157
|
-
.replace('|html', '')
|
|
16158
|
-
.getRegex()
|
|
16159
|
-
});
|
|
16160
|
-
|
|
16161
|
-
/**
|
|
16162
|
-
* Inline-Level Grammar
|
|
16163
|
-
*/
|
|
16164
|
-
const inline = {
|
|
16165
|
-
escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
|
|
16166
|
-
autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
|
|
16167
|
-
url: noopTest,
|
|
16168
|
-
tag: '^comment'
|
|
16169
|
-
+ '|^</[a-zA-Z][\\w:-]*\\s*>' // self-closing tag
|
|
16170
|
-
+ '|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>' // open tag
|
|
16171
|
-
+ '|^<\\?[\\s\\S]*?\\?>' // processing instruction, e.g. <?php ?>
|
|
16172
|
-
+ '|^<![a-zA-Z]+\\s[\\s\\S]*?>' // declaration, e.g. <!DOCTYPE html>
|
|
16173
|
-
+ '|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>', // CDATA section
|
|
16174
|
-
link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
|
|
16175
|
-
reflink: /^!?\[(label)\]\[(ref)\]/,
|
|
16176
|
-
nolink: /^!?\[(ref)\](?:\[\])?/,
|
|
16177
|
-
reflinkSearch: 'reflink|nolink(?!\\()',
|
|
16178
|
-
emStrong: {
|
|
16179
|
-
lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,
|
|
16180
|
-
// (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right.
|
|
16181
|
-
// () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a
|
|
16182
|
-
rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/,
|
|
16183
|
-
rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _
|
|
16184
|
-
},
|
|
16185
|
-
code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
|
|
16186
|
-
br: /^( {2,}|\\)\n(?!\s*$)/,
|
|
16187
|
-
del: noopTest,
|
|
16188
|
-
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
|
|
16189
|
-
punctuation: /^([\spunctuation])/
|
|
16190
|
-
};
|
|
16191
|
-
|
|
16192
|
-
// list of punctuation marks from CommonMark spec
|
|
16193
|
-
// without * and _ to handle the different emphasis markers * and _
|
|
16194
|
-
inline._punctuation = '!"#$%&\'()+\\-.,/:;<=>?@\\[\\]`^{|}~';
|
|
16195
|
-
inline.punctuation = edit(inline.punctuation).replace(/punctuation/g, inline._punctuation).getRegex();
|
|
16196
|
-
|
|
16197
|
-
// sequences em should skip over [title](link), `code`, <html>
|
|
16198
|
-
inline.blockSkip = /\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;
|
|
16199
|
-
inline.escapedEmSt = /\\\*|\\_/g;
|
|
16200
|
-
|
|
16201
|
-
inline._comment = edit(block._comment).replace('(?:-->|$)', '-->').getRegex();
|
|
16202
|
-
|
|
16203
|
-
inline.emStrong.lDelim = edit(inline.emStrong.lDelim)
|
|
16204
|
-
.replace(/punct/g, inline._punctuation)
|
|
16205
|
-
.getRegex();
|
|
16206
|
-
|
|
16207
|
-
inline.emStrong.rDelimAst = edit(inline.emStrong.rDelimAst, 'g')
|
|
16208
|
-
.replace(/punct/g, inline._punctuation)
|
|
16209
|
-
.getRegex();
|
|
16210
|
-
|
|
16211
|
-
inline.emStrong.rDelimUnd = edit(inline.emStrong.rDelimUnd, 'g')
|
|
16212
|
-
.replace(/punct/g, inline._punctuation)
|
|
16213
|
-
.getRegex();
|
|
16214
|
-
|
|
16215
|
-
inline._escapes = /\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;
|
|
16216
|
-
|
|
16217
|
-
inline._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;
|
|
16218
|
-
inline._email = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;
|
|
16219
|
-
inline.autolink = edit(inline.autolink)
|
|
16220
|
-
.replace('scheme', inline._scheme)
|
|
16221
|
-
.replace('email', inline._email)
|
|
16222
|
-
.getRegex();
|
|
16223
|
-
|
|
16224
|
-
inline._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;
|
|
16225
|
-
|
|
16226
|
-
inline.tag = edit(inline.tag)
|
|
16227
|
-
.replace('comment', inline._comment)
|
|
16228
|
-
.replace('attribute', inline._attribute)
|
|
16229
|
-
.getRegex();
|
|
16230
|
-
|
|
16231
|
-
inline._label = /(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;
|
|
16232
|
-
inline._href = /<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;
|
|
16233
|
-
inline._title = /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;
|
|
16234
|
-
|
|
16235
|
-
inline.link = edit(inline.link)
|
|
16236
|
-
.replace('label', inline._label)
|
|
16237
|
-
.replace('href', inline._href)
|
|
16238
|
-
.replace('title', inline._title)
|
|
16239
|
-
.getRegex();
|
|
16240
|
-
|
|
16241
|
-
inline.reflink = edit(inline.reflink)
|
|
16242
|
-
.replace('label', inline._label)
|
|
16243
|
-
.replace('ref', block._label)
|
|
16244
|
-
.getRegex();
|
|
16245
|
-
|
|
16246
|
-
inline.nolink = edit(inline.nolink)
|
|
16247
|
-
.replace('ref', block._label)
|
|
16248
|
-
.getRegex();
|
|
16249
|
-
|
|
16250
|
-
inline.reflinkSearch = edit(inline.reflinkSearch, 'g')
|
|
16251
|
-
.replace('reflink', inline.reflink)
|
|
16252
|
-
.replace('nolink', inline.nolink)
|
|
16253
|
-
.getRegex();
|
|
16254
|
-
|
|
16255
|
-
/**
|
|
16256
|
-
* Normal Inline Grammar
|
|
16257
|
-
*/
|
|
16258
|
-
|
|
16259
|
-
inline.normal = merge({}, inline);
|
|
16260
|
-
|
|
16261
|
-
/**
|
|
16262
|
-
* Pedantic Inline Grammar
|
|
16263
|
-
*/
|
|
16264
|
-
|
|
16265
|
-
inline.pedantic = merge({}, inline.normal, {
|
|
16266
|
-
strong: {
|
|
16267
|
-
start: /^__|\*\*/,
|
|
16268
|
-
middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
|
|
16269
|
-
endAst: /\*\*(?!\*)/g,
|
|
16270
|
-
endUnd: /__(?!_)/g
|
|
16271
|
-
},
|
|
16272
|
-
em: {
|
|
16273
|
-
start: /^_|\*/,
|
|
16274
|
-
middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
|
|
16275
|
-
endAst: /\*(?!\*)/g,
|
|
16276
|
-
endUnd: /_(?!_)/g
|
|
16277
|
-
},
|
|
16278
|
-
link: edit(/^!?\[(label)\]\((.*?)\)/)
|
|
16279
|
-
.replace('label', inline._label)
|
|
16280
|
-
.getRegex(),
|
|
16281
|
-
reflink: edit(/^!?\[(label)\]\s*\[([^\]]*)\]/)
|
|
16282
|
-
.replace('label', inline._label)
|
|
16283
|
-
.getRegex()
|
|
16284
|
-
});
|
|
16285
|
-
|
|
16286
|
-
/**
|
|
16287
|
-
* GFM Inline Grammar
|
|
16288
|
-
*/
|
|
16289
|
-
|
|
16290
|
-
inline.gfm = merge({}, inline.normal, {
|
|
16291
|
-
escape: edit(inline.escape).replace('])', '~|])').getRegex(),
|
|
16292
|
-
_extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
|
|
16293
|
-
url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
|
|
16294
|
-
_backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,
|
|
16295
|
-
del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
|
|
16296
|
-
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
|
|
16297
|
-
});
|
|
16298
|
-
|
|
16299
|
-
inline.gfm.url = edit(inline.gfm.url, 'i')
|
|
16300
|
-
.replace('email', inline.gfm._extended_email)
|
|
16301
|
-
.getRegex();
|
|
16302
|
-
/**
|
|
16303
|
-
* GFM + Line Breaks Inline Grammar
|
|
16304
|
-
*/
|
|
16305
|
-
|
|
16306
|
-
inline.breaks = merge({}, inline.gfm, {
|
|
16307
|
-
br: edit(inline.br).replace('{2,}', '*').getRegex(),
|
|
16308
|
-
text: edit(inline.gfm.text)
|
|
16309
|
-
.replace('\\b_', '\\b_| {2,}\\n')
|
|
16310
|
-
.replace(/\{2,\}/g, '*')
|
|
16311
|
-
.getRegex()
|
|
16312
|
-
});
|
|
16313
|
-
|
|
16314
|
-
/**
|
|
16315
|
-
* smartypants text replacement
|
|
16316
|
-
* @param {string} text
|
|
16317
|
-
*/
|
|
16318
|
-
function smartypants(text) {
|
|
16319
|
-
return text
|
|
16320
|
-
// em-dashes
|
|
16321
|
-
.replace(/---/g, '\u2014')
|
|
16322
|
-
// en-dashes
|
|
16323
|
-
.replace(/--/g, '\u2013')
|
|
16324
|
-
// opening singles
|
|
16325
|
-
.replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
|
|
16326
|
-
// closing singles & apostrophes
|
|
16327
|
-
.replace(/'/g, '\u2019')
|
|
16328
|
-
// opening doubles
|
|
16329
|
-
.replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
|
|
16330
|
-
// closing doubles
|
|
16331
|
-
.replace(/"/g, '\u201d')
|
|
16332
|
-
// ellipses
|
|
16333
|
-
.replace(/\.{3}/g, '\u2026');
|
|
16334
|
-
}
|
|
16335
|
-
|
|
16336
|
-
/**
|
|
16337
|
-
* mangle email addresses
|
|
16338
|
-
* @param {string} text
|
|
16339
|
-
*/
|
|
16340
|
-
function mangle(text) {
|
|
16341
|
-
let out = '',
|
|
16342
|
-
i,
|
|
16343
|
-
ch;
|
|
16344
|
-
|
|
16345
|
-
const l = text.length;
|
|
16346
|
-
for (i = 0; i < l; i++) {
|
|
16347
|
-
ch = text.charCodeAt(i);
|
|
16348
|
-
if (Math.random() > 0.5) {
|
|
16349
|
-
ch = 'x' + ch.toString(16);
|
|
16350
|
-
}
|
|
16351
|
-
out += '&#' + ch + ';';
|
|
16352
|
-
}
|
|
16353
|
-
|
|
16354
|
-
return out;
|
|
16355
|
-
}
|
|
16356
|
-
|
|
16357
|
-
/**
|
|
16358
|
-
* Block Lexer
|
|
16359
|
-
*/
|
|
16360
|
-
class Lexer {
|
|
16361
|
-
constructor(options) {
|
|
16362
|
-
this.tokens = [];
|
|
16363
|
-
this.tokens.links = Object.create(null);
|
|
16364
|
-
this.options = options || defaults;
|
|
16365
|
-
this.options.tokenizer = this.options.tokenizer || new Tokenizer();
|
|
16366
|
-
this.tokenizer = this.options.tokenizer;
|
|
16367
|
-
this.tokenizer.options = this.options;
|
|
16368
|
-
this.tokenizer.lexer = this;
|
|
16369
|
-
this.inlineQueue = [];
|
|
16370
|
-
this.state = {
|
|
16371
|
-
inLink: false,
|
|
16372
|
-
inRawBlock: false,
|
|
16373
|
-
top: true
|
|
16374
|
-
};
|
|
16375
|
-
|
|
16376
|
-
const rules = {
|
|
16377
|
-
block: block.normal,
|
|
16378
|
-
inline: inline.normal
|
|
16379
|
-
};
|
|
16380
|
-
|
|
16381
|
-
if (this.options.pedantic) {
|
|
16382
|
-
rules.block = block.pedantic;
|
|
16383
|
-
rules.inline = inline.pedantic;
|
|
16384
|
-
} else if (this.options.gfm) {
|
|
16385
|
-
rules.block = block.gfm;
|
|
16386
|
-
if (this.options.breaks) {
|
|
16387
|
-
rules.inline = inline.breaks;
|
|
16388
|
-
} else {
|
|
16389
|
-
rules.inline = inline.gfm;
|
|
16390
|
-
}
|
|
16391
|
-
}
|
|
16392
|
-
this.tokenizer.rules = rules;
|
|
16393
|
-
}
|
|
16394
|
-
|
|
16395
|
-
/**
|
|
16396
|
-
* Expose Rules
|
|
16397
|
-
*/
|
|
16398
|
-
static get rules() {
|
|
16399
|
-
return {
|
|
16400
|
-
block,
|
|
16401
|
-
inline
|
|
16402
|
-
};
|
|
16403
|
-
}
|
|
16404
|
-
|
|
16405
|
-
/**
|
|
16406
|
-
* Static Lex Method
|
|
16407
|
-
*/
|
|
16408
|
-
static lex(src, options) {
|
|
16409
|
-
const lexer = new Lexer(options);
|
|
16410
|
-
return lexer.lex(src);
|
|
16411
|
-
}
|
|
16412
|
-
|
|
16413
|
-
/**
|
|
16414
|
-
* Static Lex Inline Method
|
|
16415
|
-
*/
|
|
16416
|
-
static lexInline(src, options) {
|
|
16417
|
-
const lexer = new Lexer(options);
|
|
16418
|
-
return lexer.inlineTokens(src);
|
|
16419
|
-
}
|
|
16420
|
-
|
|
16421
|
-
/**
|
|
16422
|
-
* Preprocessing
|
|
16423
|
-
*/
|
|
16424
|
-
lex(src) {
|
|
16425
|
-
src = src
|
|
16426
|
-
.replace(/\r\n|\r/g, '\n');
|
|
16427
|
-
|
|
16428
|
-
this.blockTokens(src, this.tokens);
|
|
16429
|
-
|
|
16430
|
-
let next;
|
|
16431
|
-
while (next = this.inlineQueue.shift()) {
|
|
16432
|
-
this.inlineTokens(next.src, next.tokens);
|
|
16433
|
-
}
|
|
16434
|
-
|
|
16435
|
-
return this.tokens;
|
|
16436
|
-
}
|
|
16437
|
-
|
|
16438
|
-
/**
|
|
16439
|
-
* Lexing
|
|
16440
|
-
*/
|
|
16441
|
-
blockTokens(src, tokens = []) {
|
|
16442
|
-
if (this.options.pedantic) {
|
|
16443
|
-
src = src.replace(/\t/g, ' ').replace(/^ +$/gm, '');
|
|
16444
|
-
} else {
|
|
16445
|
-
src = src.replace(/^( *)(\t+)/gm, (_, leading, tabs) => {
|
|
16446
|
-
return leading + ' '.repeat(tabs.length);
|
|
16447
|
-
});
|
|
16448
|
-
}
|
|
16449
|
-
|
|
16450
|
-
let token, lastToken, cutSrc, lastParagraphClipped;
|
|
16451
|
-
|
|
16452
|
-
while (src) {
|
|
16453
|
-
if (this.options.extensions
|
|
16454
|
-
&& this.options.extensions.block
|
|
16455
|
-
&& this.options.extensions.block.some((extTokenizer) => {
|
|
16456
|
-
if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
|
|
16457
|
-
src = src.substring(token.raw.length);
|
|
16458
|
-
tokens.push(token);
|
|
16459
|
-
return true;
|
|
16460
|
-
}
|
|
16461
|
-
return false;
|
|
16462
|
-
})) {
|
|
16463
|
-
continue;
|
|
16464
|
-
}
|
|
16465
|
-
|
|
16466
|
-
// newline
|
|
16467
|
-
if (token = this.tokenizer.space(src)) {
|
|
16468
|
-
src = src.substring(token.raw.length);
|
|
16469
|
-
if (token.raw.length === 1 && tokens.length > 0) {
|
|
16470
|
-
// if there's a single \n as a spacer, it's terminating the last line,
|
|
16471
|
-
// so move it there so that we don't get unecessary paragraph tags
|
|
16472
|
-
tokens[tokens.length - 1].raw += '\n';
|
|
16473
|
-
} else {
|
|
16474
|
-
tokens.push(token);
|
|
16475
|
-
}
|
|
16476
|
-
continue;
|
|
16477
|
-
}
|
|
16478
|
-
|
|
16479
|
-
// code
|
|
16480
|
-
if (token = this.tokenizer.code(src)) {
|
|
16481
|
-
src = src.substring(token.raw.length);
|
|
16482
|
-
lastToken = tokens[tokens.length - 1];
|
|
16483
|
-
// An indented code block cannot interrupt a paragraph.
|
|
16484
|
-
if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
|
|
16485
|
-
lastToken.raw += '\n' + token.raw;
|
|
16486
|
-
lastToken.text += '\n' + token.text;
|
|
16487
|
-
this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
|
|
16488
|
-
} else {
|
|
16489
|
-
tokens.push(token);
|
|
16490
|
-
}
|
|
16491
|
-
continue;
|
|
16492
|
-
}
|
|
16493
|
-
|
|
16494
|
-
// fences
|
|
16495
|
-
if (token = this.tokenizer.fences(src)) {
|
|
16496
|
-
src = src.substring(token.raw.length);
|
|
16497
|
-
tokens.push(token);
|
|
16498
|
-
continue;
|
|
16499
|
-
}
|
|
16500
|
-
|
|
16501
|
-
// heading
|
|
16502
|
-
if (token = this.tokenizer.heading(src)) {
|
|
16503
|
-
src = src.substring(token.raw.length);
|
|
16504
|
-
tokens.push(token);
|
|
16505
|
-
continue;
|
|
16506
|
-
}
|
|
16507
|
-
|
|
16508
|
-
// hr
|
|
16509
|
-
if (token = this.tokenizer.hr(src)) {
|
|
16510
|
-
src = src.substring(token.raw.length);
|
|
16511
|
-
tokens.push(token);
|
|
16512
|
-
continue;
|
|
16513
|
-
}
|
|
16514
|
-
|
|
16515
|
-
// blockquote
|
|
16516
|
-
if (token = this.tokenizer.blockquote(src)) {
|
|
16517
|
-
src = src.substring(token.raw.length);
|
|
16518
|
-
tokens.push(token);
|
|
16519
|
-
continue;
|
|
16520
|
-
}
|
|
16521
|
-
|
|
16522
|
-
// list
|
|
16523
|
-
if (token = this.tokenizer.list(src)) {
|
|
16524
|
-
src = src.substring(token.raw.length);
|
|
16525
|
-
tokens.push(token);
|
|
16526
|
-
continue;
|
|
16527
|
-
}
|
|
16528
|
-
|
|
16529
|
-
// html
|
|
16530
|
-
if (token = this.tokenizer.html(src)) {
|
|
16531
|
-
src = src.substring(token.raw.length);
|
|
16532
|
-
tokens.push(token);
|
|
16533
|
-
continue;
|
|
16534
|
-
}
|
|
16535
|
-
|
|
16536
|
-
// def
|
|
16537
|
-
if (token = this.tokenizer.def(src)) {
|
|
16538
|
-
src = src.substring(token.raw.length);
|
|
16539
|
-
lastToken = tokens[tokens.length - 1];
|
|
16540
|
-
if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {
|
|
16541
|
-
lastToken.raw += '\n' + token.raw;
|
|
16542
|
-
lastToken.text += '\n' + token.raw;
|
|
16543
|
-
this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
|
|
16544
|
-
} else if (!this.tokens.links[token.tag]) {
|
|
16545
|
-
this.tokens.links[token.tag] = {
|
|
16546
|
-
href: token.href,
|
|
16547
|
-
title: token.title
|
|
16548
|
-
};
|
|
16549
|
-
}
|
|
16550
|
-
continue;
|
|
16551
|
-
}
|
|
16552
|
-
|
|
16553
|
-
// table (gfm)
|
|
16554
|
-
if (token = this.tokenizer.table(src)) {
|
|
16555
|
-
src = src.substring(token.raw.length);
|
|
16556
|
-
tokens.push(token);
|
|
16557
|
-
continue;
|
|
16558
|
-
}
|
|
16559
|
-
|
|
16560
|
-
// lheading
|
|
16561
|
-
if (token = this.tokenizer.lheading(src)) {
|
|
16562
|
-
src = src.substring(token.raw.length);
|
|
16563
|
-
tokens.push(token);
|
|
16564
|
-
continue;
|
|
16565
|
-
}
|
|
16566
|
-
|
|
16567
|
-
// top-level paragraph
|
|
16568
|
-
// prevent paragraph consuming extensions by clipping 'src' to extension start
|
|
16569
|
-
cutSrc = src;
|
|
16570
|
-
if (this.options.extensions && this.options.extensions.startBlock) {
|
|
16571
|
-
let startIndex = Infinity;
|
|
16572
|
-
const tempSrc = src.slice(1);
|
|
16573
|
-
let tempStart;
|
|
16574
|
-
this.options.extensions.startBlock.forEach(function(getStartIndex) {
|
|
16575
|
-
tempStart = getStartIndex.call({ lexer: this }, tempSrc);
|
|
16576
|
-
if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }
|
|
16577
|
-
});
|
|
16578
|
-
if (startIndex < Infinity && startIndex >= 0) {
|
|
16579
|
-
cutSrc = src.substring(0, startIndex + 1);
|
|
16580
|
-
}
|
|
16581
|
-
}
|
|
16582
|
-
if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {
|
|
16583
|
-
lastToken = tokens[tokens.length - 1];
|
|
16584
|
-
if (lastParagraphClipped && lastToken.type === 'paragraph') {
|
|
16585
|
-
lastToken.raw += '\n' + token.raw;
|
|
16586
|
-
lastToken.text += '\n' + token.text;
|
|
16587
|
-
this.inlineQueue.pop();
|
|
16588
|
-
this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
|
|
16589
|
-
} else {
|
|
16590
|
-
tokens.push(token);
|
|
16591
|
-
}
|
|
16592
|
-
lastParagraphClipped = (cutSrc.length !== src.length);
|
|
16593
|
-
src = src.substring(token.raw.length);
|
|
16594
|
-
continue;
|
|
16595
|
-
}
|
|
16596
|
-
|
|
16597
|
-
// text
|
|
16598
|
-
if (token = this.tokenizer.text(src)) {
|
|
16599
|
-
src = src.substring(token.raw.length);
|
|
16600
|
-
lastToken = tokens[tokens.length - 1];
|
|
16601
|
-
if (lastToken && lastToken.type === 'text') {
|
|
16602
|
-
lastToken.raw += '\n' + token.raw;
|
|
16603
|
-
lastToken.text += '\n' + token.text;
|
|
16604
|
-
this.inlineQueue.pop();
|
|
16605
|
-
this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;
|
|
16606
|
-
} else {
|
|
16607
|
-
tokens.push(token);
|
|
16608
|
-
}
|
|
16609
|
-
continue;
|
|
16610
|
-
}
|
|
16611
|
-
|
|
16612
|
-
if (src) {
|
|
16613
|
-
const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
|
|
16614
|
-
if (this.options.silent) {
|
|
16615
|
-
console.error(errMsg);
|
|
16616
|
-
break;
|
|
16617
|
-
} else {
|
|
16618
|
-
throw new Error(errMsg);
|
|
16619
|
-
}
|
|
16620
|
-
}
|
|
16621
|
-
}
|
|
16622
|
-
|
|
16623
|
-
this.state.top = true;
|
|
16624
|
-
return tokens;
|
|
16625
|
-
}
|
|
16626
|
-
|
|
16627
|
-
inline(src, tokens) {
|
|
16628
|
-
this.inlineQueue.push({ src, tokens });
|
|
16629
|
-
}
|
|
16630
|
-
|
|
16631
|
-
/**
|
|
16632
|
-
* Lexing/Compiling
|
|
16633
|
-
*/
|
|
16634
|
-
inlineTokens(src, tokens = []) {
|
|
16635
|
-
let token, lastToken, cutSrc;
|
|
16636
|
-
|
|
16637
|
-
// String with links masked to avoid interference with em and strong
|
|
16638
|
-
let maskedSrc = src;
|
|
16639
|
-
let match;
|
|
16640
|
-
let keepPrevChar, prevChar;
|
|
16641
|
-
|
|
16642
|
-
// Mask out reflinks
|
|
16643
|
-
if (this.tokens.links) {
|
|
16644
|
-
const links = Object.keys(this.tokens.links);
|
|
16645
|
-
if (links.length > 0) {
|
|
16646
|
-
while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {
|
|
16647
|
-
if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {
|
|
16648
|
-
maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);
|
|
16649
|
-
}
|
|
16650
|
-
}
|
|
16651
|
-
}
|
|
16652
|
-
}
|
|
16653
|
-
// Mask out other blocks
|
|
16654
|
-
while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {
|
|
16655
|
-
maskedSrc = maskedSrc.slice(0, match.index) + '[' + repeatString('a', match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
|
|
16656
|
-
}
|
|
16657
|
-
|
|
16658
|
-
// Mask out escaped em & strong delimiters
|
|
16659
|
-
while ((match = this.tokenizer.rules.inline.escapedEmSt.exec(maskedSrc)) != null) {
|
|
16660
|
-
maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex);
|
|
16661
|
-
}
|
|
16662
|
-
|
|
16663
|
-
while (src) {
|
|
16664
|
-
if (!keepPrevChar) {
|
|
16665
|
-
prevChar = '';
|
|
16666
|
-
}
|
|
16667
|
-
keepPrevChar = false;
|
|
16668
|
-
|
|
16669
|
-
// extensions
|
|
16670
|
-
if (this.options.extensions
|
|
16671
|
-
&& this.options.extensions.inline
|
|
16672
|
-
&& this.options.extensions.inline.some((extTokenizer) => {
|
|
16673
|
-
if (token = extTokenizer.call({ lexer: this }, src, tokens)) {
|
|
16674
|
-
src = src.substring(token.raw.length);
|
|
16675
|
-
tokens.push(token);
|
|
16676
|
-
return true;
|
|
16677
|
-
}
|
|
16678
|
-
return false;
|
|
16679
|
-
})) {
|
|
16680
|
-
continue;
|
|
16681
|
-
}
|
|
16682
|
-
|
|
16683
|
-
// escape
|
|
16684
|
-
if (token = this.tokenizer.escape(src)) {
|
|
16685
|
-
src = src.substring(token.raw.length);
|
|
16686
|
-
tokens.push(token);
|
|
16687
|
-
continue;
|
|
16688
|
-
}
|
|
16689
|
-
|
|
16690
|
-
// tag
|
|
16691
|
-
if (token = this.tokenizer.tag(src)) {
|
|
16692
|
-
src = src.substring(token.raw.length);
|
|
16693
|
-
lastToken = tokens[tokens.length - 1];
|
|
16694
|
-
if (lastToken && token.type === 'text' && lastToken.type === 'text') {
|
|
16695
|
-
lastToken.raw += token.raw;
|
|
16696
|
-
lastToken.text += token.text;
|
|
16697
|
-
} else {
|
|
16698
|
-
tokens.push(token);
|
|
16699
|
-
}
|
|
16700
|
-
continue;
|
|
16701
|
-
}
|
|
16702
|
-
|
|
16703
|
-
// link
|
|
16704
|
-
if (token = this.tokenizer.link(src)) {
|
|
16705
|
-
src = src.substring(token.raw.length);
|
|
16706
|
-
tokens.push(token);
|
|
16707
|
-
continue;
|
|
16708
|
-
}
|
|
16709
|
-
|
|
16710
|
-
// reflink, nolink
|
|
16711
|
-
if (token = this.tokenizer.reflink(src, this.tokens.links)) {
|
|
16712
|
-
src = src.substring(token.raw.length);
|
|
16713
|
-
lastToken = tokens[tokens.length - 1];
|
|
16714
|
-
if (lastToken && token.type === 'text' && lastToken.type === 'text') {
|
|
16715
|
-
lastToken.raw += token.raw;
|
|
16716
|
-
lastToken.text += token.text;
|
|
16717
|
-
} else {
|
|
16718
|
-
tokens.push(token);
|
|
16719
|
-
}
|
|
16720
|
-
continue;
|
|
16721
|
-
}
|
|
16722
|
-
|
|
16723
|
-
// em & strong
|
|
16724
|
-
if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {
|
|
16725
|
-
src = src.substring(token.raw.length);
|
|
16726
|
-
tokens.push(token);
|
|
16727
|
-
continue;
|
|
16728
|
-
}
|
|
16729
|
-
|
|
16730
|
-
// code
|
|
16731
|
-
if (token = this.tokenizer.codespan(src)) {
|
|
16732
|
-
src = src.substring(token.raw.length);
|
|
16733
|
-
tokens.push(token);
|
|
16734
|
-
continue;
|
|
16735
|
-
}
|
|
16736
|
-
|
|
16737
|
-
// br
|
|
16738
|
-
if (token = this.tokenizer.br(src)) {
|
|
16739
|
-
src = src.substring(token.raw.length);
|
|
16740
|
-
tokens.push(token);
|
|
16741
|
-
continue;
|
|
16742
|
-
}
|
|
16743
|
-
|
|
16744
|
-
// del (gfm)
|
|
16745
|
-
if (token = this.tokenizer.del(src)) {
|
|
16746
|
-
src = src.substring(token.raw.length);
|
|
16747
|
-
tokens.push(token);
|
|
16748
|
-
continue;
|
|
16749
|
-
}
|
|
16750
|
-
|
|
16751
|
-
// autolink
|
|
16752
|
-
if (token = this.tokenizer.autolink(src, mangle)) {
|
|
16753
|
-
src = src.substring(token.raw.length);
|
|
16754
|
-
tokens.push(token);
|
|
16755
|
-
continue;
|
|
16756
|
-
}
|
|
16757
|
-
|
|
16758
|
-
// url (gfm)
|
|
16759
|
-
if (!this.state.inLink && (token = this.tokenizer.url(src, mangle))) {
|
|
16760
|
-
src = src.substring(token.raw.length);
|
|
16761
|
-
tokens.push(token);
|
|
16762
|
-
continue;
|
|
16763
|
-
}
|
|
16764
|
-
|
|
16765
|
-
// text
|
|
16766
|
-
// prevent inlineText consuming extensions by clipping 'src' to extension start
|
|
16767
|
-
cutSrc = src;
|
|
16768
|
-
if (this.options.extensions && this.options.extensions.startInline) {
|
|
16769
|
-
let startIndex = Infinity;
|
|
16770
|
-
const tempSrc = src.slice(1);
|
|
16771
|
-
let tempStart;
|
|
16772
|
-
this.options.extensions.startInline.forEach(function(getStartIndex) {
|
|
16773
|
-
tempStart = getStartIndex.call({ lexer: this }, tempSrc);
|
|
16774
|
-
if (typeof tempStart === 'number' && tempStart >= 0) { startIndex = Math.min(startIndex, tempStart); }
|
|
16775
|
-
});
|
|
16776
|
-
if (startIndex < Infinity && startIndex >= 0) {
|
|
16777
|
-
cutSrc = src.substring(0, startIndex + 1);
|
|
16778
|
-
}
|
|
16779
|
-
}
|
|
16780
|
-
if (token = this.tokenizer.inlineText(cutSrc, smartypants)) {
|
|
16781
|
-
src = src.substring(token.raw.length);
|
|
16782
|
-
if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started
|
|
16783
|
-
prevChar = token.raw.slice(-1);
|
|
16784
|
-
}
|
|
16785
|
-
keepPrevChar = true;
|
|
16786
|
-
lastToken = tokens[tokens.length - 1];
|
|
16787
|
-
if (lastToken && lastToken.type === 'text') {
|
|
16788
|
-
lastToken.raw += token.raw;
|
|
16789
|
-
lastToken.text += token.text;
|
|
16790
|
-
} else {
|
|
16791
|
-
tokens.push(token);
|
|
16792
|
-
}
|
|
16793
|
-
continue;
|
|
16794
|
-
}
|
|
16795
|
-
|
|
16796
|
-
if (src) {
|
|
16797
|
-
const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);
|
|
16798
|
-
if (this.options.silent) {
|
|
16799
|
-
console.error(errMsg);
|
|
16800
|
-
break;
|
|
16801
|
-
} else {
|
|
16802
|
-
throw new Error(errMsg);
|
|
16803
|
-
}
|
|
16804
|
-
}
|
|
16805
|
-
}
|
|
16806
|
-
|
|
16807
|
-
return tokens;
|
|
16808
|
-
}
|
|
16809
|
-
}
|
|
16810
|
-
|
|
16811
|
-
/**
|
|
16812
|
-
* Renderer
|
|
16813
|
-
*/
|
|
16814
|
-
class Renderer {
|
|
16815
|
-
constructor(options) {
|
|
16816
|
-
this.options = options || defaults;
|
|
16817
|
-
}
|
|
16818
|
-
|
|
16819
|
-
code(code, infostring, escaped) {
|
|
16820
|
-
const lang = (infostring || '').match(/\S*/)[0];
|
|
16821
|
-
if (this.options.highlight) {
|
|
16822
|
-
const out = this.options.highlight(code, lang);
|
|
16823
|
-
if (out != null && out !== code) {
|
|
16824
|
-
escaped = true;
|
|
16825
|
-
code = out;
|
|
16826
|
-
}
|
|
16827
|
-
}
|
|
16828
|
-
|
|
16829
|
-
code = code.replace(/\n$/, '') + '\n';
|
|
16830
|
-
|
|
16831
|
-
if (!lang) {
|
|
16832
|
-
return '<pre><code>'
|
|
16833
|
-
+ (escaped ? code : marked_esm_escape(code, true))
|
|
16834
|
-
+ '</code></pre>\n';
|
|
16835
|
-
}
|
|
16836
|
-
|
|
16837
|
-
return '<pre><code class="'
|
|
16838
|
-
+ this.options.langPrefix
|
|
16839
|
-
+ marked_esm_escape(lang, true)
|
|
16840
|
-
+ '">'
|
|
16841
|
-
+ (escaped ? code : marked_esm_escape(code, true))
|
|
16842
|
-
+ '</code></pre>\n';
|
|
16843
|
-
}
|
|
16844
|
-
|
|
16845
|
-
/**
|
|
16846
|
-
* @param {string} quote
|
|
16847
|
-
*/
|
|
16848
|
-
blockquote(quote) {
|
|
16849
|
-
return `<blockquote>\n${quote}</blockquote>\n`;
|
|
16850
|
-
}
|
|
16851
|
-
|
|
16852
|
-
html(html) {
|
|
16853
|
-
return html;
|
|
16854
|
-
}
|
|
16855
|
-
|
|
16856
|
-
/**
|
|
16857
|
-
* @param {string} text
|
|
16858
|
-
* @param {string} level
|
|
16859
|
-
* @param {string} raw
|
|
16860
|
-
* @param {any} slugger
|
|
16861
|
-
*/
|
|
16862
|
-
heading(text, level, raw, slugger) {
|
|
16863
|
-
if (this.options.headerIds) {
|
|
16864
|
-
const id = this.options.headerPrefix + slugger.slug(raw);
|
|
16865
|
-
return `<h${level} id="${id}">${text}</h${level}>\n`;
|
|
16866
|
-
}
|
|
16867
|
-
|
|
16868
|
-
// ignore IDs
|
|
16869
|
-
return `<h${level}>${text}</h${level}>\n`;
|
|
16870
|
-
}
|
|
16871
|
-
|
|
16872
|
-
hr() {
|
|
16873
|
-
return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
|
|
16874
|
-
}
|
|
16875
|
-
|
|
16876
|
-
list(body, ordered, start) {
|
|
16877
|
-
const type = ordered ? 'ol' : 'ul',
|
|
16878
|
-
startatt = (ordered && start !== 1) ? (' start="' + start + '"') : '';
|
|
16879
|
-
return '<' + type + startatt + '>\n' + body + '</' + type + '>\n';
|
|
16880
|
-
}
|
|
16881
|
-
|
|
16882
|
-
/**
|
|
16883
|
-
* @param {string} text
|
|
16884
|
-
*/
|
|
16885
|
-
listitem(text) {
|
|
16886
|
-
return `<li>${text}</li>\n`;
|
|
16887
|
-
}
|
|
16888
|
-
|
|
16889
|
-
checkbox(checked) {
|
|
16890
|
-
return '<input '
|
|
16891
|
-
+ (checked ? 'checked="" ' : '')
|
|
16892
|
-
+ 'disabled="" type="checkbox"'
|
|
16893
|
-
+ (this.options.xhtml ? ' /' : '')
|
|
16894
|
-
+ '> ';
|
|
16895
|
-
}
|
|
16896
|
-
|
|
16897
|
-
/**
|
|
16898
|
-
* @param {string} text
|
|
16899
|
-
*/
|
|
16900
|
-
paragraph(text) {
|
|
16901
|
-
return `<p>${text}</p>\n`;
|
|
16902
|
-
}
|
|
16903
|
-
|
|
16904
|
-
/**
|
|
16905
|
-
* @param {string} header
|
|
16906
|
-
* @param {string} body
|
|
16907
|
-
*/
|
|
16908
|
-
table(header, body) {
|
|
16909
|
-
if (body) body = `<tbody>${body}</tbody>`;
|
|
16910
|
-
|
|
16911
|
-
return '<table>\n'
|
|
16912
|
-
+ '<thead>\n'
|
|
16913
|
-
+ header
|
|
16914
|
-
+ '</thead>\n'
|
|
16915
|
-
+ body
|
|
16916
|
-
+ '</table>\n';
|
|
16917
|
-
}
|
|
16918
|
-
|
|
16919
|
-
/**
|
|
16920
|
-
* @param {string} content
|
|
16921
|
-
*/
|
|
16922
|
-
tablerow(content) {
|
|
16923
|
-
return `<tr>\n${content}</tr>\n`;
|
|
16924
|
-
}
|
|
16925
|
-
|
|
16926
|
-
tablecell(content, flags) {
|
|
16927
|
-
const type = flags.header ? 'th' : 'td';
|
|
16928
|
-
const tag = flags.align
|
|
16929
|
-
? `<${type} align="${flags.align}">`
|
|
16930
|
-
: `<${type}>`;
|
|
16931
|
-
return tag + content + `</${type}>\n`;
|
|
16932
|
-
}
|
|
16933
|
-
|
|
16934
|
-
/**
|
|
16935
|
-
* span level renderer
|
|
16936
|
-
* @param {string} text
|
|
16937
|
-
*/
|
|
16938
|
-
strong(text) {
|
|
16939
|
-
return `<strong>${text}</strong>`;
|
|
16940
|
-
}
|
|
16941
|
-
|
|
16942
|
-
/**
|
|
16943
|
-
* @param {string} text
|
|
16944
|
-
*/
|
|
16945
|
-
em(text) {
|
|
16946
|
-
return `<em>${text}</em>`;
|
|
16947
|
-
}
|
|
16948
|
-
|
|
16949
|
-
/**
|
|
16950
|
-
* @param {string} text
|
|
16951
|
-
*/
|
|
16952
|
-
codespan(text) {
|
|
16953
|
-
return `<code>${text}</code>`;
|
|
16954
|
-
}
|
|
16955
|
-
|
|
16956
|
-
br() {
|
|
16957
|
-
return this.options.xhtml ? '<br/>' : '<br>';
|
|
16958
|
-
}
|
|
16959
|
-
|
|
16960
|
-
/**
|
|
16961
|
-
* @param {string} text
|
|
16962
|
-
*/
|
|
16963
|
-
del(text) {
|
|
16964
|
-
return `<del>${text}</del>`;
|
|
16965
|
-
}
|
|
16966
|
-
|
|
16967
|
-
/**
|
|
16968
|
-
* @param {string} href
|
|
16969
|
-
* @param {string} title
|
|
16970
|
-
* @param {string} text
|
|
16971
|
-
*/
|
|
16972
|
-
link(href, title, text) {
|
|
16973
|
-
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
|
16974
|
-
if (href === null) {
|
|
16975
|
-
return text;
|
|
16976
|
-
}
|
|
16977
|
-
let out = '<a href="' + marked_esm_escape(href) + '"';
|
|
16978
|
-
if (title) {
|
|
16979
|
-
out += ' title="' + title + '"';
|
|
16980
|
-
}
|
|
16981
|
-
out += '>' + text + '</a>';
|
|
16982
|
-
return out;
|
|
16983
|
-
}
|
|
16984
|
-
|
|
16985
|
-
/**
|
|
16986
|
-
* @param {string} href
|
|
16987
|
-
* @param {string} title
|
|
16988
|
-
* @param {string} text
|
|
16989
|
-
*/
|
|
16990
|
-
image(href, title, text) {
|
|
16991
|
-
href = cleanUrl(this.options.sanitize, this.options.baseUrl, href);
|
|
16992
|
-
if (href === null) {
|
|
16993
|
-
return text;
|
|
16994
|
-
}
|
|
16995
|
-
|
|
16996
|
-
let out = `<img src="${href}" alt="${text}"`;
|
|
16997
|
-
if (title) {
|
|
16998
|
-
out += ` title="${title}"`;
|
|
16999
|
-
}
|
|
17000
|
-
out += this.options.xhtml ? '/>' : '>';
|
|
17001
|
-
return out;
|
|
17002
|
-
}
|
|
17003
|
-
|
|
17004
|
-
text(text) {
|
|
17005
|
-
return text;
|
|
17006
|
-
}
|
|
17007
|
-
}
|
|
17008
|
-
|
|
17009
|
-
/**
|
|
17010
|
-
* TextRenderer
|
|
17011
|
-
* returns only the textual part of the token
|
|
17012
|
-
*/
|
|
17013
|
-
class TextRenderer {
|
|
17014
|
-
// no need for block level renderers
|
|
17015
|
-
strong(text) {
|
|
17016
|
-
return text;
|
|
17017
|
-
}
|
|
17018
|
-
|
|
17019
|
-
em(text) {
|
|
17020
|
-
return text;
|
|
17021
|
-
}
|
|
17022
|
-
|
|
17023
|
-
codespan(text) {
|
|
17024
|
-
return text;
|
|
17025
|
-
}
|
|
17026
|
-
|
|
17027
|
-
del(text) {
|
|
17028
|
-
return text;
|
|
17029
|
-
}
|
|
17030
|
-
|
|
17031
|
-
html(text) {
|
|
17032
|
-
return text;
|
|
17033
|
-
}
|
|
17034
|
-
|
|
17035
|
-
text(text) {
|
|
17036
|
-
return text;
|
|
17037
|
-
}
|
|
17038
|
-
|
|
17039
|
-
link(href, title, text) {
|
|
17040
|
-
return '' + text;
|
|
17041
|
-
}
|
|
17042
|
-
|
|
17043
|
-
image(href, title, text) {
|
|
17044
|
-
return '' + text;
|
|
17045
|
-
}
|
|
17046
|
-
|
|
17047
|
-
br() {
|
|
17048
|
-
return '';
|
|
17049
|
-
}
|
|
17050
|
-
}
|
|
17051
|
-
|
|
17052
|
-
/**
|
|
17053
|
-
* Slugger generates header id
|
|
17054
|
-
*/
|
|
17055
|
-
class Slugger {
|
|
17056
|
-
constructor() {
|
|
17057
|
-
this.seen = {};
|
|
17058
|
-
}
|
|
17059
|
-
|
|
17060
|
-
/**
|
|
17061
|
-
* @param {string} value
|
|
17062
|
-
*/
|
|
17063
|
-
serialize(value) {
|
|
17064
|
-
return value
|
|
17065
|
-
.toLowerCase()
|
|
17066
|
-
.trim()
|
|
17067
|
-
// remove html tags
|
|
17068
|
-
.replace(/<[!\/a-z].*?>/ig, '')
|
|
17069
|
-
// remove unwanted chars
|
|
17070
|
-
.replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '')
|
|
17071
|
-
.replace(/\s/g, '-');
|
|
17072
|
-
}
|
|
17073
|
-
|
|
17074
|
-
/**
|
|
17075
|
-
* Finds the next safe (unique) slug to use
|
|
17076
|
-
* @param {string} originalSlug
|
|
17077
|
-
* @param {boolean} isDryRun
|
|
17078
|
-
*/
|
|
17079
|
-
getNextSafeSlug(originalSlug, isDryRun) {
|
|
17080
|
-
let slug = originalSlug;
|
|
17081
|
-
let occurenceAccumulator = 0;
|
|
17082
|
-
if (this.seen.hasOwnProperty(slug)) {
|
|
17083
|
-
occurenceAccumulator = this.seen[originalSlug];
|
|
17084
|
-
do {
|
|
17085
|
-
occurenceAccumulator++;
|
|
17086
|
-
slug = originalSlug + '-' + occurenceAccumulator;
|
|
17087
|
-
} while (this.seen.hasOwnProperty(slug));
|
|
17088
|
-
}
|
|
17089
|
-
if (!isDryRun) {
|
|
17090
|
-
this.seen[originalSlug] = occurenceAccumulator;
|
|
17091
|
-
this.seen[slug] = 0;
|
|
17092
|
-
}
|
|
17093
|
-
return slug;
|
|
17094
|
-
}
|
|
17095
|
-
|
|
17096
|
-
/**
|
|
17097
|
-
* Convert string to unique id
|
|
17098
|
-
* @param {object} [options]
|
|
17099
|
-
* @param {boolean} [options.dryrun] Generates the next unique slug without
|
|
17100
|
-
* updating the internal accumulator.
|
|
17101
|
-
*/
|
|
17102
|
-
slug(value, options = {}) {
|
|
17103
|
-
const slug = this.serialize(value);
|
|
17104
|
-
return this.getNextSafeSlug(slug, options.dryrun);
|
|
17105
|
-
}
|
|
17106
|
-
}
|
|
17107
|
-
|
|
17108
|
-
/**
|
|
17109
|
-
* Parsing & Compiling
|
|
17110
|
-
*/
|
|
17111
|
-
class Parser {
|
|
17112
|
-
constructor(options) {
|
|
17113
|
-
this.options = options || defaults;
|
|
17114
|
-
this.options.renderer = this.options.renderer || new Renderer();
|
|
17115
|
-
this.renderer = this.options.renderer;
|
|
17116
|
-
this.renderer.options = this.options;
|
|
17117
|
-
this.textRenderer = new TextRenderer();
|
|
17118
|
-
this.slugger = new Slugger();
|
|
17119
|
-
}
|
|
17120
|
-
|
|
17121
|
-
/**
|
|
17122
|
-
* Static Parse Method
|
|
17123
|
-
*/
|
|
17124
|
-
static parse(tokens, options) {
|
|
17125
|
-
const parser = new Parser(options);
|
|
17126
|
-
return parser.parse(tokens);
|
|
17127
|
-
}
|
|
17128
|
-
|
|
17129
|
-
/**
|
|
17130
|
-
* Static Parse Inline Method
|
|
17131
|
-
*/
|
|
17132
|
-
static parseInline(tokens, options) {
|
|
17133
|
-
const parser = new Parser(options);
|
|
17134
|
-
return parser.parseInline(tokens);
|
|
17135
|
-
}
|
|
17136
|
-
|
|
17137
|
-
/**
|
|
17138
|
-
* Parse Loop
|
|
17139
|
-
*/
|
|
17140
|
-
parse(tokens, top = true) {
|
|
17141
|
-
let out = '',
|
|
17142
|
-
i,
|
|
17143
|
-
j,
|
|
17144
|
-
k,
|
|
17145
|
-
l2,
|
|
17146
|
-
l3,
|
|
17147
|
-
row,
|
|
17148
|
-
cell,
|
|
17149
|
-
header,
|
|
17150
|
-
body,
|
|
17151
|
-
token,
|
|
17152
|
-
ordered,
|
|
17153
|
-
start,
|
|
17154
|
-
loose,
|
|
17155
|
-
itemBody,
|
|
17156
|
-
item,
|
|
17157
|
-
checked,
|
|
17158
|
-
task,
|
|
17159
|
-
checkbox,
|
|
17160
|
-
ret;
|
|
17161
|
-
|
|
17162
|
-
const l = tokens.length;
|
|
17163
|
-
for (i = 0; i < l; i++) {
|
|
17164
|
-
token = tokens[i];
|
|
17165
|
-
|
|
17166
|
-
// Run any renderer extensions
|
|
17167
|
-
if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
|
|
17168
|
-
ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
|
|
17169
|
-
if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(token.type)) {
|
|
17170
|
-
out += ret || '';
|
|
17171
|
-
continue;
|
|
17172
|
-
}
|
|
17173
|
-
}
|
|
17174
|
-
|
|
17175
|
-
switch (token.type) {
|
|
17176
|
-
case 'space': {
|
|
17177
|
-
continue;
|
|
17178
|
-
}
|
|
17179
|
-
case 'hr': {
|
|
17180
|
-
out += this.renderer.hr();
|
|
17181
|
-
continue;
|
|
17182
|
-
}
|
|
17183
|
-
case 'heading': {
|
|
17184
|
-
out += this.renderer.heading(
|
|
17185
|
-
this.parseInline(token.tokens),
|
|
17186
|
-
token.depth,
|
|
17187
|
-
marked_esm_unescape(this.parseInline(token.tokens, this.textRenderer)),
|
|
17188
|
-
this.slugger);
|
|
17189
|
-
continue;
|
|
17190
|
-
}
|
|
17191
|
-
case 'code': {
|
|
17192
|
-
out += this.renderer.code(token.text,
|
|
17193
|
-
token.lang,
|
|
17194
|
-
token.escaped);
|
|
17195
|
-
continue;
|
|
17196
|
-
}
|
|
17197
|
-
case 'table': {
|
|
17198
|
-
header = '';
|
|
17199
|
-
|
|
17200
|
-
// header
|
|
17201
|
-
cell = '';
|
|
17202
|
-
l2 = token.header.length;
|
|
17203
|
-
for (j = 0; j < l2; j++) {
|
|
17204
|
-
cell += this.renderer.tablecell(
|
|
17205
|
-
this.parseInline(token.header[j].tokens),
|
|
17206
|
-
{ header: true, align: token.align[j] }
|
|
17207
|
-
);
|
|
17208
|
-
}
|
|
17209
|
-
header += this.renderer.tablerow(cell);
|
|
17210
|
-
|
|
17211
|
-
body = '';
|
|
17212
|
-
l2 = token.rows.length;
|
|
17213
|
-
for (j = 0; j < l2; j++) {
|
|
17214
|
-
row = token.rows[j];
|
|
17215
|
-
|
|
17216
|
-
cell = '';
|
|
17217
|
-
l3 = row.length;
|
|
17218
|
-
for (k = 0; k < l3; k++) {
|
|
17219
|
-
cell += this.renderer.tablecell(
|
|
17220
|
-
this.parseInline(row[k].tokens),
|
|
17221
|
-
{ header: false, align: token.align[k] }
|
|
17222
|
-
);
|
|
17223
|
-
}
|
|
17224
|
-
|
|
17225
|
-
body += this.renderer.tablerow(cell);
|
|
17226
|
-
}
|
|
17227
|
-
out += this.renderer.table(header, body);
|
|
17228
|
-
continue;
|
|
17229
|
-
}
|
|
17230
|
-
case 'blockquote': {
|
|
17231
|
-
body = this.parse(token.tokens);
|
|
17232
|
-
out += this.renderer.blockquote(body);
|
|
17233
|
-
continue;
|
|
17234
|
-
}
|
|
17235
|
-
case 'list': {
|
|
17236
|
-
ordered = token.ordered;
|
|
17237
|
-
start = token.start;
|
|
17238
|
-
loose = token.loose;
|
|
17239
|
-
l2 = token.items.length;
|
|
17240
|
-
|
|
17241
|
-
body = '';
|
|
17242
|
-
for (j = 0; j < l2; j++) {
|
|
17243
|
-
item = token.items[j];
|
|
17244
|
-
checked = item.checked;
|
|
17245
|
-
task = item.task;
|
|
17246
|
-
|
|
17247
|
-
itemBody = '';
|
|
17248
|
-
if (item.task) {
|
|
17249
|
-
checkbox = this.renderer.checkbox(checked);
|
|
17250
|
-
if (loose) {
|
|
17251
|
-
if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {
|
|
17252
|
-
item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;
|
|
17253
|
-
if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {
|
|
17254
|
-
item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;
|
|
17255
|
-
}
|
|
17256
|
-
} else {
|
|
17257
|
-
item.tokens.unshift({
|
|
17258
|
-
type: 'text',
|
|
17259
|
-
text: checkbox
|
|
17260
|
-
});
|
|
17261
|
-
}
|
|
17262
|
-
} else {
|
|
17263
|
-
itemBody += checkbox;
|
|
17264
|
-
}
|
|
17265
|
-
}
|
|
17266
|
-
|
|
17267
|
-
itemBody += this.parse(item.tokens, loose);
|
|
17268
|
-
body += this.renderer.listitem(itemBody, task, checked);
|
|
17269
|
-
}
|
|
17270
|
-
|
|
17271
|
-
out += this.renderer.list(body, ordered, start);
|
|
17272
|
-
continue;
|
|
17273
|
-
}
|
|
17274
|
-
case 'html': {
|
|
17275
|
-
// TODO parse inline content if parameter markdown=1
|
|
17276
|
-
out += this.renderer.html(token.text);
|
|
17277
|
-
continue;
|
|
17278
|
-
}
|
|
17279
|
-
case 'paragraph': {
|
|
17280
|
-
out += this.renderer.paragraph(this.parseInline(token.tokens));
|
|
17281
|
-
continue;
|
|
17282
|
-
}
|
|
17283
|
-
case 'text': {
|
|
17284
|
-
body = token.tokens ? this.parseInline(token.tokens) : token.text;
|
|
17285
|
-
while (i + 1 < l && tokens[i + 1].type === 'text') {
|
|
17286
|
-
token = tokens[++i];
|
|
17287
|
-
body += '\n' + (token.tokens ? this.parseInline(token.tokens) : token.text);
|
|
17288
|
-
}
|
|
17289
|
-
out += top ? this.renderer.paragraph(body) : body;
|
|
17290
|
-
continue;
|
|
17291
|
-
}
|
|
17292
|
-
|
|
17293
|
-
default: {
|
|
17294
|
-
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
17295
|
-
if (this.options.silent) {
|
|
17296
|
-
console.error(errMsg);
|
|
17297
|
-
return;
|
|
17298
|
-
} else {
|
|
17299
|
-
throw new Error(errMsg);
|
|
17300
|
-
}
|
|
17301
|
-
}
|
|
17302
|
-
}
|
|
17303
|
-
}
|
|
17304
|
-
|
|
17305
|
-
return out;
|
|
17306
|
-
}
|
|
17307
|
-
|
|
17308
|
-
/**
|
|
17309
|
-
* Parse Inline Tokens
|
|
17310
|
-
*/
|
|
17311
|
-
parseInline(tokens, renderer) {
|
|
17312
|
-
renderer = renderer || this.renderer;
|
|
17313
|
-
let out = '',
|
|
17314
|
-
i,
|
|
17315
|
-
token,
|
|
17316
|
-
ret;
|
|
17317
|
-
|
|
17318
|
-
const l = tokens.length;
|
|
17319
|
-
for (i = 0; i < l; i++) {
|
|
17320
|
-
token = tokens[i];
|
|
17321
|
-
|
|
17322
|
-
// Run any renderer extensions
|
|
17323
|
-
if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[token.type]) {
|
|
17324
|
-
ret = this.options.extensions.renderers[token.type].call({ parser: this }, token);
|
|
17325
|
-
if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(token.type)) {
|
|
17326
|
-
out += ret || '';
|
|
17327
|
-
continue;
|
|
17328
|
-
}
|
|
17329
|
-
}
|
|
17330
|
-
|
|
17331
|
-
switch (token.type) {
|
|
17332
|
-
case 'escape': {
|
|
17333
|
-
out += renderer.text(token.text);
|
|
17334
|
-
break;
|
|
17335
|
-
}
|
|
17336
|
-
case 'html': {
|
|
17337
|
-
out += renderer.html(token.text);
|
|
17338
|
-
break;
|
|
17339
|
-
}
|
|
17340
|
-
case 'link': {
|
|
17341
|
-
out += renderer.link(token.href, token.title, this.parseInline(token.tokens, renderer));
|
|
17342
|
-
break;
|
|
17343
|
-
}
|
|
17344
|
-
case 'image': {
|
|
17345
|
-
out += renderer.image(token.href, token.title, token.text);
|
|
17346
|
-
break;
|
|
17347
|
-
}
|
|
17348
|
-
case 'strong': {
|
|
17349
|
-
out += renderer.strong(this.parseInline(token.tokens, renderer));
|
|
17350
|
-
break;
|
|
17351
|
-
}
|
|
17352
|
-
case 'em': {
|
|
17353
|
-
out += renderer.em(this.parseInline(token.tokens, renderer));
|
|
17354
|
-
break;
|
|
17355
|
-
}
|
|
17356
|
-
case 'codespan': {
|
|
17357
|
-
out += renderer.codespan(token.text);
|
|
17358
|
-
break;
|
|
17359
|
-
}
|
|
17360
|
-
case 'br': {
|
|
17361
|
-
out += renderer.br();
|
|
17362
|
-
break;
|
|
17363
|
-
}
|
|
17364
|
-
case 'del': {
|
|
17365
|
-
out += renderer.del(this.parseInline(token.tokens, renderer));
|
|
17366
|
-
break;
|
|
17367
|
-
}
|
|
17368
|
-
case 'text': {
|
|
17369
|
-
out += renderer.text(token.text);
|
|
17370
|
-
break;
|
|
17371
|
-
}
|
|
17372
|
-
default: {
|
|
17373
|
-
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
17374
|
-
if (this.options.silent) {
|
|
17375
|
-
console.error(errMsg);
|
|
17376
|
-
return;
|
|
17377
|
-
} else {
|
|
17378
|
-
throw new Error(errMsg);
|
|
17379
|
-
}
|
|
17380
|
-
}
|
|
17381
|
-
}
|
|
17382
|
-
}
|
|
17383
|
-
return out;
|
|
17384
|
-
}
|
|
17385
|
-
}
|
|
17386
|
-
|
|
17387
|
-
/**
|
|
17388
|
-
* Marked
|
|
17389
|
-
*/
|
|
17390
|
-
function marked(src, opt, callback) {
|
|
17391
|
-
// throw error in case of non string input
|
|
17392
|
-
if (typeof src === 'undefined' || src === null) {
|
|
17393
|
-
throw new Error('marked(): input parameter is undefined or null');
|
|
17394
|
-
}
|
|
17395
|
-
if (typeof src !== 'string') {
|
|
17396
|
-
throw new Error('marked(): input parameter is of type '
|
|
17397
|
-
+ Object.prototype.toString.call(src) + ', string expected');
|
|
17398
|
-
}
|
|
17399
|
-
|
|
17400
|
-
if (typeof opt === 'function') {
|
|
17401
|
-
callback = opt;
|
|
17402
|
-
opt = null;
|
|
17403
|
-
}
|
|
17404
|
-
|
|
17405
|
-
opt = merge({}, marked.defaults, opt || {});
|
|
17406
|
-
checkSanitizeDeprecation(opt);
|
|
17407
|
-
|
|
17408
|
-
if (callback) {
|
|
17409
|
-
const highlight = opt.highlight;
|
|
17410
|
-
let tokens;
|
|
17411
|
-
|
|
17412
|
-
try {
|
|
17413
|
-
tokens = Lexer.lex(src, opt);
|
|
17414
|
-
} catch (e) {
|
|
17415
|
-
return callback(e);
|
|
17416
|
-
}
|
|
17417
|
-
|
|
17418
|
-
const done = function(err) {
|
|
17419
|
-
let out;
|
|
17420
|
-
|
|
17421
|
-
if (!err) {
|
|
17422
|
-
try {
|
|
17423
|
-
if (opt.walkTokens) {
|
|
17424
|
-
marked.walkTokens(tokens, opt.walkTokens);
|
|
17425
|
-
}
|
|
17426
|
-
out = Parser.parse(tokens, opt);
|
|
17427
|
-
} catch (e) {
|
|
17428
|
-
err = e;
|
|
17429
|
-
}
|
|
17430
|
-
}
|
|
17431
|
-
|
|
17432
|
-
opt.highlight = highlight;
|
|
17433
|
-
|
|
17434
|
-
return err
|
|
17435
|
-
? callback(err)
|
|
17436
|
-
: callback(null, out);
|
|
17437
|
-
};
|
|
17438
|
-
|
|
17439
|
-
if (!highlight || highlight.length < 3) {
|
|
17440
|
-
return done();
|
|
17441
|
-
}
|
|
17442
|
-
|
|
17443
|
-
delete opt.highlight;
|
|
17444
|
-
|
|
17445
|
-
if (!tokens.length) return done();
|
|
17446
|
-
|
|
17447
|
-
let pending = 0;
|
|
17448
|
-
marked.walkTokens(tokens, function(token) {
|
|
17449
|
-
if (token.type === 'code') {
|
|
17450
|
-
pending++;
|
|
17451
|
-
setTimeout(() => {
|
|
17452
|
-
highlight(token.text, token.lang, function(err, code) {
|
|
17453
|
-
if (err) {
|
|
17454
|
-
return done(err);
|
|
17455
|
-
}
|
|
17456
|
-
if (code != null && code !== token.text) {
|
|
17457
|
-
token.text = code;
|
|
17458
|
-
token.escaped = true;
|
|
17459
|
-
}
|
|
17460
|
-
|
|
17461
|
-
pending--;
|
|
17462
|
-
if (pending === 0) {
|
|
17463
|
-
done();
|
|
17464
|
-
}
|
|
17465
|
-
});
|
|
17466
|
-
}, 0);
|
|
17467
|
-
}
|
|
17468
|
-
});
|
|
17469
|
-
|
|
17470
|
-
if (pending === 0) {
|
|
17471
|
-
done();
|
|
17472
|
-
}
|
|
17473
|
-
|
|
17474
|
-
return;
|
|
17475
|
-
}
|
|
17476
|
-
|
|
17477
|
-
try {
|
|
17478
|
-
const tokens = Lexer.lex(src, opt);
|
|
17479
|
-
if (opt.walkTokens) {
|
|
17480
|
-
marked.walkTokens(tokens, opt.walkTokens);
|
|
17481
|
-
}
|
|
17482
|
-
return Parser.parse(tokens, opt);
|
|
17483
|
-
} catch (e) {
|
|
17484
|
-
e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
|
17485
|
-
if (opt.silent) {
|
|
17486
|
-
return '<p>An error occurred:</p><pre>'
|
|
17487
|
-
+ marked_esm_escape(e.message + '', true)
|
|
17488
|
-
+ '</pre>';
|
|
17489
|
-
}
|
|
17490
|
-
throw e;
|
|
17491
|
-
}
|
|
17492
|
-
}
|
|
17493
|
-
|
|
17494
|
-
/**
|
|
17495
|
-
* Options
|
|
17496
|
-
*/
|
|
17497
|
-
|
|
17498
|
-
marked.options =
|
|
17499
|
-
marked.setOptions = function(opt) {
|
|
17500
|
-
merge(marked.defaults, opt);
|
|
17501
|
-
changeDefaults(marked.defaults);
|
|
17502
|
-
return marked;
|
|
17503
|
-
};
|
|
17504
|
-
|
|
17505
|
-
marked.getDefaults = getDefaults;
|
|
17506
|
-
|
|
17507
|
-
marked.defaults = defaults;
|
|
17508
|
-
|
|
17509
|
-
/**
|
|
17510
|
-
* Use Extension
|
|
17511
|
-
*/
|
|
17512
|
-
|
|
17513
|
-
marked.use = function(...args) {
|
|
17514
|
-
const opts = merge({}, ...args);
|
|
17515
|
-
const extensions = marked.defaults.extensions || { renderers: {}, childTokens: {} };
|
|
17516
|
-
let hasExtensions;
|
|
17517
|
-
|
|
17518
|
-
args.forEach((pack) => {
|
|
17519
|
-
// ==-- Parse "addon" extensions --== //
|
|
17520
|
-
if (pack.extensions) {
|
|
17521
|
-
hasExtensions = true;
|
|
17522
|
-
pack.extensions.forEach((ext) => {
|
|
17523
|
-
if (!ext.name) {
|
|
17524
|
-
throw new Error('extension name required');
|
|
17525
|
-
}
|
|
17526
|
-
if (ext.renderer) { // Renderer extensions
|
|
17527
|
-
const prevRenderer = extensions.renderers ? extensions.renderers[ext.name] : null;
|
|
17528
|
-
if (prevRenderer) {
|
|
17529
|
-
// Replace extension with func to run new extension but fall back if false
|
|
17530
|
-
extensions.renderers[ext.name] = function(...args) {
|
|
17531
|
-
let ret = ext.renderer.apply(this, args);
|
|
17532
|
-
if (ret === false) {
|
|
17533
|
-
ret = prevRenderer.apply(this, args);
|
|
17534
|
-
}
|
|
17535
|
-
return ret;
|
|
17536
|
-
};
|
|
17537
|
-
} else {
|
|
17538
|
-
extensions.renderers[ext.name] = ext.renderer;
|
|
17539
|
-
}
|
|
17540
|
-
}
|
|
17541
|
-
if (ext.tokenizer) { // Tokenizer Extensions
|
|
17542
|
-
if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {
|
|
17543
|
-
throw new Error("extension level must be 'block' or 'inline'");
|
|
17544
|
-
}
|
|
17545
|
-
if (extensions[ext.level]) {
|
|
17546
|
-
extensions[ext.level].unshift(ext.tokenizer);
|
|
17547
|
-
} else {
|
|
17548
|
-
extensions[ext.level] = [ext.tokenizer];
|
|
17549
|
-
}
|
|
17550
|
-
if (ext.start) { // Function to check for start of token
|
|
17551
|
-
if (ext.level === 'block') {
|
|
17552
|
-
if (extensions.startBlock) {
|
|
17553
|
-
extensions.startBlock.push(ext.start);
|
|
17554
|
-
} else {
|
|
17555
|
-
extensions.startBlock = [ext.start];
|
|
17556
|
-
}
|
|
17557
|
-
} else if (ext.level === 'inline') {
|
|
17558
|
-
if (extensions.startInline) {
|
|
17559
|
-
extensions.startInline.push(ext.start);
|
|
17560
|
-
} else {
|
|
17561
|
-
extensions.startInline = [ext.start];
|
|
17562
|
-
}
|
|
17563
|
-
}
|
|
17564
|
-
}
|
|
17565
|
-
}
|
|
17566
|
-
if (ext.childTokens) { // Child tokens to be visited by walkTokens
|
|
17567
|
-
extensions.childTokens[ext.name] = ext.childTokens;
|
|
17568
|
-
}
|
|
17569
|
-
});
|
|
17570
|
-
}
|
|
17571
|
-
|
|
17572
|
-
// ==-- Parse "overwrite" extensions --== //
|
|
17573
|
-
if (pack.renderer) {
|
|
17574
|
-
const renderer = marked.defaults.renderer || new Renderer();
|
|
17575
|
-
for (const prop in pack.renderer) {
|
|
17576
|
-
const prevRenderer = renderer[prop];
|
|
17577
|
-
// Replace renderer with func to run extension, but fall back if false
|
|
17578
|
-
renderer[prop] = (...args) => {
|
|
17579
|
-
let ret = pack.renderer[prop].apply(renderer, args);
|
|
17580
|
-
if (ret === false) {
|
|
17581
|
-
ret = prevRenderer.apply(renderer, args);
|
|
17582
|
-
}
|
|
17583
|
-
return ret;
|
|
17584
|
-
};
|
|
17585
|
-
}
|
|
17586
|
-
opts.renderer = renderer;
|
|
17587
|
-
}
|
|
17588
|
-
if (pack.tokenizer) {
|
|
17589
|
-
const tokenizer = marked.defaults.tokenizer || new Tokenizer();
|
|
17590
|
-
for (const prop in pack.tokenizer) {
|
|
17591
|
-
const prevTokenizer = tokenizer[prop];
|
|
17592
|
-
// Replace tokenizer with func to run extension, but fall back if false
|
|
17593
|
-
tokenizer[prop] = (...args) => {
|
|
17594
|
-
let ret = pack.tokenizer[prop].apply(tokenizer, args);
|
|
17595
|
-
if (ret === false) {
|
|
17596
|
-
ret = prevTokenizer.apply(tokenizer, args);
|
|
17597
|
-
}
|
|
17598
|
-
return ret;
|
|
17599
|
-
};
|
|
17600
|
-
}
|
|
17601
|
-
opts.tokenizer = tokenizer;
|
|
17602
|
-
}
|
|
17603
|
-
|
|
17604
|
-
// ==-- Parse WalkTokens extensions --== //
|
|
17605
|
-
if (pack.walkTokens) {
|
|
17606
|
-
const walkTokens = marked.defaults.walkTokens;
|
|
17607
|
-
opts.walkTokens = function(token) {
|
|
17608
|
-
pack.walkTokens.call(this, token);
|
|
17609
|
-
if (walkTokens) {
|
|
17610
|
-
walkTokens.call(this, token);
|
|
17611
|
-
}
|
|
17612
|
-
};
|
|
17613
|
-
}
|
|
17614
|
-
|
|
17615
|
-
if (hasExtensions) {
|
|
17616
|
-
opts.extensions = extensions;
|
|
17617
|
-
}
|
|
17618
|
-
|
|
17619
|
-
marked.setOptions(opts);
|
|
17620
|
-
});
|
|
17621
|
-
};
|
|
17622
|
-
|
|
17623
|
-
/**
|
|
17624
|
-
* Run callback for every token
|
|
17625
|
-
*/
|
|
17626
|
-
|
|
17627
|
-
marked.walkTokens = function(tokens, callback) {
|
|
17628
|
-
for (const token of tokens) {
|
|
17629
|
-
callback.call(marked, token);
|
|
17630
|
-
switch (token.type) {
|
|
17631
|
-
case 'table': {
|
|
17632
|
-
for (const cell of token.header) {
|
|
17633
|
-
marked.walkTokens(cell.tokens, callback);
|
|
17634
|
-
}
|
|
17635
|
-
for (const row of token.rows) {
|
|
17636
|
-
for (const cell of row) {
|
|
17637
|
-
marked.walkTokens(cell.tokens, callback);
|
|
17638
|
-
}
|
|
17639
|
-
}
|
|
17640
|
-
break;
|
|
17641
|
-
}
|
|
17642
|
-
case 'list': {
|
|
17643
|
-
marked.walkTokens(token.items, callback);
|
|
17644
|
-
break;
|
|
17645
|
-
}
|
|
17646
|
-
default: {
|
|
17647
|
-
if (marked.defaults.extensions && marked.defaults.extensions.childTokens && marked.defaults.extensions.childTokens[token.type]) { // Walk any extensions
|
|
17648
|
-
marked.defaults.extensions.childTokens[token.type].forEach(function(childTokens) {
|
|
17649
|
-
marked.walkTokens(token[childTokens], callback);
|
|
17650
|
-
});
|
|
17651
|
-
} else if (token.tokens) {
|
|
17652
|
-
marked.walkTokens(token.tokens, callback);
|
|
17653
|
-
}
|
|
17654
|
-
}
|
|
17655
|
-
}
|
|
17656
|
-
}
|
|
17657
|
-
};
|
|
17658
|
-
|
|
17659
|
-
/**
|
|
17660
|
-
* Parse Inline
|
|
17661
|
-
* @param {string} src
|
|
17662
|
-
*/
|
|
17663
|
-
marked.parseInline = function(src, opt) {
|
|
17664
|
-
// throw error in case of non string input
|
|
17665
|
-
if (typeof src === 'undefined' || src === null) {
|
|
17666
|
-
throw new Error('marked.parseInline(): input parameter is undefined or null');
|
|
17667
|
-
}
|
|
17668
|
-
if (typeof src !== 'string') {
|
|
17669
|
-
throw new Error('marked.parseInline(): input parameter is of type '
|
|
17670
|
-
+ Object.prototype.toString.call(src) + ', string expected');
|
|
17671
|
-
}
|
|
17672
|
-
|
|
17673
|
-
opt = merge({}, marked.defaults, opt || {});
|
|
17674
|
-
checkSanitizeDeprecation(opt);
|
|
17675
|
-
|
|
17676
|
-
try {
|
|
17677
|
-
const tokens = Lexer.lexInline(src, opt);
|
|
17678
|
-
if (opt.walkTokens) {
|
|
17679
|
-
marked.walkTokens(tokens, opt.walkTokens);
|
|
17680
|
-
}
|
|
17681
|
-
return Parser.parseInline(tokens, opt);
|
|
17682
|
-
} catch (e) {
|
|
17683
|
-
e.message += '\nPlease report this to https://github.com/markedjs/marked.';
|
|
17684
|
-
if (opt.silent) {
|
|
17685
|
-
return '<p>An error occurred:</p><pre>'
|
|
17686
|
-
+ marked_esm_escape(e.message + '', true)
|
|
17687
|
-
+ '</pre>';
|
|
17688
|
-
}
|
|
17689
|
-
throw e;
|
|
17690
|
-
}
|
|
17691
|
-
};
|
|
17692
|
-
|
|
17693
|
-
/**
|
|
17694
|
-
* Expose
|
|
17695
|
-
*/
|
|
17696
|
-
marked.Parser = Parser;
|
|
17697
|
-
marked.parser = Parser.parse;
|
|
17698
|
-
marked.Renderer = Renderer;
|
|
17699
|
-
marked.TextRenderer = TextRenderer;
|
|
17700
|
-
marked.Lexer = Lexer;
|
|
17701
|
-
marked.lexer = Lexer.lex;
|
|
17702
|
-
marked.Tokenizer = Tokenizer;
|
|
17703
|
-
marked.Slugger = Slugger;
|
|
17704
|
-
marked.parse = marked;
|
|
17705
|
-
|
|
17706
|
-
const options = marked.options;
|
|
17707
|
-
const setOptions = marked.setOptions;
|
|
17708
|
-
const use = marked.use;
|
|
17709
|
-
const walkTokens = marked.walkTokens;
|
|
17710
|
-
const parseInline = marked.parseInline;
|
|
17711
|
-
const parse = (/* unused pure expression or super */ null && (marked));
|
|
17712
|
-
const parser = Parser.parse;
|
|
17713
|
-
const lexer = Lexer.lex;
|
|
17714
|
-
|
|
17715
|
-
|
|
17716
|
-
|
|
17717
|
-
;// CONCATENATED MODULE: ./src/javascripts/lib/parse-body.js
|
|
17718
|
-
|
|
17719
|
-
/* harmony default export */ const parse_body = (body => {
|
|
17720
|
-
try {
|
|
17721
|
-
return marked(body);
|
|
17722
|
-
} catch (e) {
|
|
17723
|
-
console.log('Could not parse message', body, e);
|
|
17724
|
-
return '';
|
|
17725
|
-
}
|
|
17726
|
-
});
|
|
17727
|
-
;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/hooks/use-event-link-click-handler.js
|
|
17728
|
-
|
|
17729
|
-
|
|
17730
|
-
|
|
17731
|
-
const useEventLinkClickHandler = eventId => {
|
|
17732
|
-
const {
|
|
17733
|
-
sendAction
|
|
17734
|
-
} = use_seamly_commands();
|
|
17735
|
-
|
|
17736
|
-
const eventClick = e => {
|
|
17737
|
-
if (e.target && e.target.dataset.linkId) {
|
|
17738
|
-
sendAction({
|
|
17739
|
-
type: actionTypes.navigate,
|
|
17740
|
-
originMessage: eventId,
|
|
17741
|
-
link: {
|
|
17742
|
-
id: e.target.dataset.linkId,
|
|
17743
|
-
url: e.target.getAttribute('href')
|
|
17744
|
-
}
|
|
17745
|
-
});
|
|
17746
|
-
}
|
|
17747
|
-
};
|
|
17748
|
-
|
|
17749
|
-
return eventClick;
|
|
17750
|
-
};
|
|
17751
|
-
|
|
17752
|
-
/* harmony default export */ const use_event_link_click_handler = (useEventLinkClickHandler);
|
|
17753
|
-
;// CONCATENATED MODULE: ./node_modules/mustache/mustache.mjs
|
|
17754
|
-
/*!
|
|
17755
|
-
* mustache.js - Logic-less {{mustache}} templates with JavaScript
|
|
17756
|
-
* http://github.com/janl/mustache.js
|
|
17757
|
-
*/
|
|
17758
|
-
|
|
17759
|
-
var objectToString = Object.prototype.toString;
|
|
17760
|
-
var isArray = Array.isArray || function isArrayPolyfill (object) {
|
|
17761
|
-
return objectToString.call(object) === '[object Array]';
|
|
17762
|
-
};
|
|
17763
|
-
|
|
17764
|
-
function isFunction (object) {
|
|
17765
|
-
return typeof object === 'function';
|
|
17766
|
-
}
|
|
17767
|
-
|
|
17768
|
-
/**
|
|
17769
|
-
* More correct typeof string handling array
|
|
17770
|
-
* which normally returns typeof 'object'
|
|
17771
|
-
*/
|
|
17772
|
-
function typeStr (obj) {
|
|
17773
|
-
return isArray(obj) ? 'array' : typeof obj;
|
|
17774
|
-
}
|
|
17775
|
-
|
|
17776
|
-
function escapeRegExp (string) {
|
|
17777
|
-
return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
|
|
17778
|
-
}
|
|
17779
|
-
|
|
17780
|
-
/**
|
|
17781
|
-
* Null safe way of checking whether or not an object,
|
|
17782
|
-
* including its prototype, has a given property
|
|
17783
|
-
*/
|
|
17784
|
-
function hasProperty (obj, propName) {
|
|
17785
|
-
return obj != null && typeof obj === 'object' && (propName in obj);
|
|
17786
|
-
}
|
|
17787
|
-
|
|
17788
|
-
/**
|
|
17789
|
-
* Safe way of detecting whether or not the given thing is a primitive and
|
|
17790
|
-
* whether it has the given property
|
|
17791
|
-
*/
|
|
17792
|
-
function primitiveHasOwnProperty (primitive, propName) {
|
|
17793
|
-
return (
|
|
17794
|
-
primitive != null
|
|
17795
|
-
&& typeof primitive !== 'object'
|
|
17796
|
-
&& primitive.hasOwnProperty
|
|
17797
|
-
&& primitive.hasOwnProperty(propName)
|
|
17798
|
-
);
|
|
17799
|
-
}
|
|
17800
|
-
|
|
17801
|
-
// Workaround for https://issues.apache.org/jira/browse/COUCHDB-577
|
|
17802
|
-
// See https://github.com/janl/mustache.js/issues/189
|
|
17803
|
-
var regExpTest = RegExp.prototype.test;
|
|
17804
|
-
function testRegExp (re, string) {
|
|
17805
|
-
return regExpTest.call(re, string);
|
|
17806
|
-
}
|
|
17807
|
-
|
|
17808
|
-
var nonSpaceRe = /\S/;
|
|
17809
|
-
function isWhitespace (string) {
|
|
17810
|
-
return !testRegExp(nonSpaceRe, string);
|
|
17811
|
-
}
|
|
17812
|
-
|
|
17813
|
-
var entityMap = {
|
|
17814
|
-
'&': '&',
|
|
17815
|
-
'<': '<',
|
|
17816
|
-
'>': '>',
|
|
17817
|
-
'"': '"',
|
|
17818
|
-
"'": ''',
|
|
17819
|
-
'/': '/',
|
|
17820
|
-
'`': '`',
|
|
17821
|
-
'=': '='
|
|
17822
|
-
};
|
|
17823
|
-
|
|
17824
|
-
function escapeHtml (string) {
|
|
17825
|
-
return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap (s) {
|
|
17826
|
-
return entityMap[s];
|
|
17827
|
-
});
|
|
17828
|
-
}
|
|
17829
|
-
|
|
17830
|
-
var whiteRe = /\s*/;
|
|
17831
|
-
var spaceRe = /\s+/;
|
|
17832
|
-
var equalsRe = /\s*=/;
|
|
17833
|
-
var curlyRe = /\s*\}/;
|
|
17834
|
-
var tagRe = /#|\^|\/|>|\{|&|=|!/;
|
|
17835
|
-
|
|
17836
|
-
/**
|
|
17837
|
-
* Breaks up the given `template` string into a tree of tokens. If the `tags`
|
|
17838
|
-
* argument is given here it must be an array with two string values: the
|
|
17839
|
-
* opening and closing tags used in the template (e.g. [ "<%", "%>" ]). Of
|
|
17840
|
-
* course, the default is to use mustaches (i.e. mustache.tags).
|
|
17841
|
-
*
|
|
17842
|
-
* A token is an array with at least 4 elements. The first element is the
|
|
17843
|
-
* mustache symbol that was used inside the tag, e.g. "#" or "&". If the tag
|
|
17844
|
-
* did not contain a symbol (i.e. {{myValue}}) this element is "name". For
|
|
17845
|
-
* all text that appears outside a symbol this element is "text".
|
|
17846
|
-
*
|
|
17847
|
-
* The second element of a token is its "value". For mustache tags this is
|
|
17848
|
-
* whatever else was inside the tag besides the opening symbol. For text tokens
|
|
17849
|
-
* this is the text itself.
|
|
17850
|
-
*
|
|
17851
|
-
* The third and fourth elements of the token are the start and end indices,
|
|
17852
|
-
* respectively, of the token in the original template.
|
|
17853
|
-
*
|
|
17854
|
-
* Tokens that are the root node of a subtree contain two more elements: 1) an
|
|
17855
|
-
* array of tokens in the subtree and 2) the index in the original template at
|
|
17856
|
-
* which the closing tag for that section begins.
|
|
17857
|
-
*
|
|
17858
|
-
* Tokens for partials also contain two more elements: 1) a string value of
|
|
17859
|
-
* indendation prior to that tag and 2) the index of that tag on that line -
|
|
17860
|
-
* eg a value of 2 indicates the partial is the third tag on this line.
|
|
17861
|
-
*/
|
|
17862
|
-
function parseTemplate (template, tags) {
|
|
17863
|
-
if (!template)
|
|
17864
|
-
return [];
|
|
17865
|
-
var lineHasNonSpace = false;
|
|
17866
|
-
var sections = []; // Stack to hold section tokens
|
|
17867
|
-
var tokens = []; // Buffer to hold the tokens
|
|
17868
|
-
var spaces = []; // Indices of whitespace tokens on the current line
|
|
17869
|
-
var hasTag = false; // Is there a {{tag}} on the current line?
|
|
17870
|
-
var nonSpace = false; // Is there a non-space char on the current line?
|
|
17871
|
-
var indentation = ''; // Tracks indentation for tags that use it
|
|
17872
|
-
var tagIndex = 0; // Stores a count of number of tags encountered on a line
|
|
17873
|
-
|
|
17874
|
-
// Strips all whitespace tokens array for the current line
|
|
17875
|
-
// if there was a {{#tag}} on it and otherwise only space.
|
|
17876
|
-
function stripSpace () {
|
|
17877
|
-
if (hasTag && !nonSpace) {
|
|
17878
|
-
while (spaces.length)
|
|
17879
|
-
delete tokens[spaces.pop()];
|
|
17880
|
-
} else {
|
|
17881
|
-
spaces = [];
|
|
17882
|
-
}
|
|
17883
|
-
|
|
17884
|
-
hasTag = false;
|
|
17885
|
-
nonSpace = false;
|
|
17886
|
-
}
|
|
17887
|
-
|
|
17888
|
-
var openingTagRe, closingTagRe, closingCurlyRe;
|
|
17889
|
-
function compileTags (tagsToCompile) {
|
|
17890
|
-
if (typeof tagsToCompile === 'string')
|
|
17891
|
-
tagsToCompile = tagsToCompile.split(spaceRe, 2);
|
|
17892
|
-
|
|
17893
|
-
if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)
|
|
17894
|
-
throw new Error('Invalid tags: ' + tagsToCompile);
|
|
17895
|
-
|
|
17896
|
-
openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + '\\s*');
|
|
17897
|
-
closingTagRe = new RegExp('\\s*' + escapeRegExp(tagsToCompile[1]));
|
|
17898
|
-
closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tagsToCompile[1]));
|
|
17899
|
-
}
|
|
17900
|
-
|
|
17901
|
-
compileTags(tags || mustache.tags);
|
|
17902
|
-
|
|
17903
|
-
var scanner = new Scanner(template);
|
|
17904
|
-
|
|
17905
|
-
var start, type, value, chr, token, openSection;
|
|
17906
|
-
while (!scanner.eos()) {
|
|
17907
|
-
start = scanner.pos;
|
|
17908
|
-
|
|
17909
|
-
// Match any text between tags.
|
|
17910
|
-
value = scanner.scanUntil(openingTagRe);
|
|
17911
|
-
|
|
17912
|
-
if (value) {
|
|
17913
|
-
for (var i = 0, valueLength = value.length; i < valueLength; ++i) {
|
|
17914
|
-
chr = value.charAt(i);
|
|
17915
|
-
|
|
17916
|
-
if (isWhitespace(chr)) {
|
|
17917
|
-
spaces.push(tokens.length);
|
|
17918
|
-
indentation += chr;
|
|
17919
|
-
} else {
|
|
17920
|
-
nonSpace = true;
|
|
17921
|
-
lineHasNonSpace = true;
|
|
17922
|
-
indentation += ' ';
|
|
17923
|
-
}
|
|
17924
|
-
|
|
17925
|
-
tokens.push([ 'text', chr, start, start + 1 ]);
|
|
17926
|
-
start += 1;
|
|
17927
|
-
|
|
17928
|
-
// Check for whitespace on the current line.
|
|
17929
|
-
if (chr === '\n') {
|
|
17930
|
-
stripSpace();
|
|
17931
|
-
indentation = '';
|
|
17932
|
-
tagIndex = 0;
|
|
17933
|
-
lineHasNonSpace = false;
|
|
17934
|
-
}
|
|
17935
|
-
}
|
|
17936
|
-
}
|
|
17937
|
-
|
|
17938
|
-
// Match the opening tag.
|
|
17939
|
-
if (!scanner.scan(openingTagRe))
|
|
17940
|
-
break;
|
|
17941
|
-
|
|
17942
|
-
hasTag = true;
|
|
17943
|
-
|
|
17944
|
-
// Get the tag type.
|
|
17945
|
-
type = scanner.scan(tagRe) || 'name';
|
|
17946
|
-
scanner.scan(whiteRe);
|
|
17947
|
-
|
|
17948
|
-
// Get the tag value.
|
|
17949
|
-
if (type === '=') {
|
|
17950
|
-
value = scanner.scanUntil(equalsRe);
|
|
17951
|
-
scanner.scan(equalsRe);
|
|
17952
|
-
scanner.scanUntil(closingTagRe);
|
|
17953
|
-
} else if (type === '{') {
|
|
17954
|
-
value = scanner.scanUntil(closingCurlyRe);
|
|
17955
|
-
scanner.scan(curlyRe);
|
|
17956
|
-
scanner.scanUntil(closingTagRe);
|
|
17957
|
-
type = '&';
|
|
17958
|
-
} else {
|
|
17959
|
-
value = scanner.scanUntil(closingTagRe);
|
|
17960
|
-
}
|
|
17961
|
-
|
|
17962
|
-
// Match the closing tag.
|
|
17963
|
-
if (!scanner.scan(closingTagRe))
|
|
17964
|
-
throw new Error('Unclosed tag at ' + scanner.pos);
|
|
17965
|
-
|
|
17966
|
-
if (type == '>') {
|
|
17967
|
-
token = [ type, value, start, scanner.pos, indentation, tagIndex, lineHasNonSpace ];
|
|
17968
|
-
} else {
|
|
17969
|
-
token = [ type, value, start, scanner.pos ];
|
|
17970
|
-
}
|
|
17971
|
-
tagIndex++;
|
|
17972
|
-
tokens.push(token);
|
|
17973
|
-
|
|
17974
|
-
if (type === '#' || type === '^') {
|
|
17975
|
-
sections.push(token);
|
|
17976
|
-
} else if (type === '/') {
|
|
17977
|
-
// Check section nesting.
|
|
17978
|
-
openSection = sections.pop();
|
|
17979
|
-
|
|
17980
|
-
if (!openSection)
|
|
17981
|
-
throw new Error('Unopened section "' + value + '" at ' + start);
|
|
17982
|
-
|
|
17983
|
-
if (openSection[1] !== value)
|
|
17984
|
-
throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
|
|
17985
|
-
} else if (type === 'name' || type === '{' || type === '&') {
|
|
17986
|
-
nonSpace = true;
|
|
17987
|
-
} else if (type === '=') {
|
|
17988
|
-
// Set the tags for the next time around.
|
|
17989
|
-
compileTags(value);
|
|
17990
|
-
}
|
|
17991
|
-
}
|
|
17992
|
-
|
|
17993
|
-
stripSpace();
|
|
17994
|
-
|
|
17995
|
-
// Make sure there are no open sections when we're done.
|
|
17996
|
-
openSection = sections.pop();
|
|
17997
|
-
|
|
17998
|
-
if (openSection)
|
|
17999
|
-
throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
|
|
18000
|
-
|
|
18001
|
-
return nestTokens(squashTokens(tokens));
|
|
18002
|
-
}
|
|
18003
|
-
|
|
18004
|
-
/**
|
|
18005
|
-
* Combines the values of consecutive text tokens in the given `tokens` array
|
|
18006
|
-
* to a single token.
|
|
18007
|
-
*/
|
|
18008
|
-
function squashTokens (tokens) {
|
|
18009
|
-
var squashedTokens = [];
|
|
18010
|
-
|
|
18011
|
-
var token, lastToken;
|
|
18012
|
-
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
|
|
18013
|
-
token = tokens[i];
|
|
18014
|
-
|
|
18015
|
-
if (token) {
|
|
18016
|
-
if (token[0] === 'text' && lastToken && lastToken[0] === 'text') {
|
|
18017
|
-
lastToken[1] += token[1];
|
|
18018
|
-
lastToken[3] = token[3];
|
|
18019
|
-
} else {
|
|
18020
|
-
squashedTokens.push(token);
|
|
18021
|
-
lastToken = token;
|
|
18022
|
-
}
|
|
18023
|
-
}
|
|
18024
|
-
}
|
|
18025
|
-
|
|
18026
|
-
return squashedTokens;
|
|
18027
|
-
}
|
|
18028
|
-
|
|
18029
|
-
/**
|
|
18030
|
-
* Forms the given array of `tokens` into a nested tree structure where
|
|
18031
|
-
* tokens that represent a section have two additional items: 1) an array of
|
|
18032
|
-
* all tokens that appear in that section and 2) the index in the original
|
|
18033
|
-
* template that represents the end of that section.
|
|
18034
|
-
*/
|
|
18035
|
-
function nestTokens (tokens) {
|
|
18036
|
-
var nestedTokens = [];
|
|
18037
|
-
var collector = nestedTokens;
|
|
18038
|
-
var sections = [];
|
|
18039
|
-
|
|
18040
|
-
var token, section;
|
|
18041
|
-
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
|
|
18042
|
-
token = tokens[i];
|
|
18043
|
-
|
|
18044
|
-
switch (token[0]) {
|
|
18045
|
-
case '#':
|
|
18046
|
-
case '^':
|
|
18047
|
-
collector.push(token);
|
|
18048
|
-
sections.push(token);
|
|
18049
|
-
collector = token[4] = [];
|
|
18050
|
-
break;
|
|
18051
|
-
case '/':
|
|
18052
|
-
section = sections.pop();
|
|
18053
|
-
section[5] = token[2];
|
|
18054
|
-
collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
|
|
18055
|
-
break;
|
|
18056
|
-
default:
|
|
18057
|
-
collector.push(token);
|
|
18058
|
-
}
|
|
18059
|
-
}
|
|
18060
|
-
|
|
18061
|
-
return nestedTokens;
|
|
18062
|
-
}
|
|
18063
|
-
|
|
18064
|
-
/**
|
|
18065
|
-
* A simple string scanner that is used by the template parser to find
|
|
18066
|
-
* tokens in template strings.
|
|
18067
|
-
*/
|
|
18068
|
-
function Scanner (string) {
|
|
18069
|
-
this.string = string;
|
|
18070
|
-
this.tail = string;
|
|
18071
|
-
this.pos = 0;
|
|
18072
|
-
}
|
|
18073
|
-
|
|
18074
|
-
/**
|
|
18075
|
-
* Returns `true` if the tail is empty (end of string).
|
|
18076
|
-
*/
|
|
18077
|
-
Scanner.prototype.eos = function eos () {
|
|
18078
|
-
return this.tail === '';
|
|
18079
|
-
};
|
|
18080
|
-
|
|
18081
|
-
/**
|
|
18082
|
-
* Tries to match the given regular expression at the current position.
|
|
18083
|
-
* Returns the matched text if it can match, the empty string otherwise.
|
|
18084
|
-
*/
|
|
18085
|
-
Scanner.prototype.scan = function scan (re) {
|
|
18086
|
-
var match = this.tail.match(re);
|
|
18087
|
-
|
|
18088
|
-
if (!match || match.index !== 0)
|
|
18089
|
-
return '';
|
|
18090
|
-
|
|
18091
|
-
var string = match[0];
|
|
18092
|
-
|
|
18093
|
-
this.tail = this.tail.substring(string.length);
|
|
18094
|
-
this.pos += string.length;
|
|
18095
|
-
|
|
18096
|
-
return string;
|
|
18097
|
-
};
|
|
18098
|
-
|
|
18099
|
-
/**
|
|
18100
|
-
* Skips all text until the given regular expression can be matched. Returns
|
|
18101
|
-
* the skipped string, which is the entire tail if no match can be made.
|
|
18102
|
-
*/
|
|
18103
|
-
Scanner.prototype.scanUntil = function scanUntil (re) {
|
|
18104
|
-
var index = this.tail.search(re), match;
|
|
18105
|
-
|
|
18106
|
-
switch (index) {
|
|
18107
|
-
case -1:
|
|
18108
|
-
match = this.tail;
|
|
18109
|
-
this.tail = '';
|
|
18110
|
-
break;
|
|
18111
|
-
case 0:
|
|
18112
|
-
match = '';
|
|
18113
|
-
break;
|
|
18114
|
-
default:
|
|
18115
|
-
match = this.tail.substring(0, index);
|
|
18116
|
-
this.tail = this.tail.substring(index);
|
|
18117
|
-
}
|
|
18118
|
-
|
|
18119
|
-
this.pos += match.length;
|
|
18120
|
-
|
|
18121
|
-
return match;
|
|
18122
|
-
};
|
|
18123
|
-
|
|
18124
|
-
/**
|
|
18125
|
-
* Represents a rendering context by wrapping a view object and
|
|
18126
|
-
* maintaining a reference to the parent context.
|
|
18127
|
-
*/
|
|
18128
|
-
function Context (view, parentContext) {
|
|
18129
|
-
this.view = view;
|
|
18130
|
-
this.cache = { '.': this.view };
|
|
18131
|
-
this.parent = parentContext;
|
|
18132
|
-
}
|
|
18133
|
-
|
|
18134
|
-
/**
|
|
18135
|
-
* Creates a new context using the given view with this context
|
|
18136
|
-
* as the parent.
|
|
18137
|
-
*/
|
|
18138
|
-
Context.prototype.push = function push (view) {
|
|
18139
|
-
return new Context(view, this);
|
|
18140
|
-
};
|
|
18141
|
-
|
|
18142
|
-
/**
|
|
18143
|
-
* Returns the value of the given name in this context, traversing
|
|
18144
|
-
* up the context hierarchy if the value is absent in this context's view.
|
|
18145
|
-
*/
|
|
18146
|
-
Context.prototype.lookup = function lookup (name) {
|
|
18147
|
-
var cache = this.cache;
|
|
18148
|
-
|
|
18149
|
-
var value;
|
|
18150
|
-
if (cache.hasOwnProperty(name)) {
|
|
18151
|
-
value = cache[name];
|
|
18152
|
-
} else {
|
|
18153
|
-
var context = this, intermediateValue, names, index, lookupHit = false;
|
|
18154
|
-
|
|
18155
|
-
while (context) {
|
|
18156
|
-
if (name.indexOf('.') > 0) {
|
|
18157
|
-
intermediateValue = context.view;
|
|
18158
|
-
names = name.split('.');
|
|
18159
|
-
index = 0;
|
|
18160
|
-
|
|
18161
|
-
/**
|
|
18162
|
-
* Using the dot notion path in `name`, we descend through the
|
|
18163
|
-
* nested objects.
|
|
18164
|
-
*
|
|
18165
|
-
* To be certain that the lookup has been successful, we have to
|
|
18166
|
-
* check if the last object in the path actually has the property
|
|
18167
|
-
* we are looking for. We store the result in `lookupHit`.
|
|
18168
|
-
*
|
|
18169
|
-
* This is specially necessary for when the value has been set to
|
|
18170
|
-
* `undefined` and we want to avoid looking up parent contexts.
|
|
18171
|
-
*
|
|
18172
|
-
* In the case where dot notation is used, we consider the lookup
|
|
18173
|
-
* to be successful even if the last "object" in the path is
|
|
18174
|
-
* not actually an object but a primitive (e.g., a string, or an
|
|
18175
|
-
* integer), because it is sometimes useful to access a property
|
|
18176
|
-
* of an autoboxed primitive, such as the length of a string.
|
|
18177
|
-
**/
|
|
18178
|
-
while (intermediateValue != null && index < names.length) {
|
|
18179
|
-
if (index === names.length - 1)
|
|
18180
|
-
lookupHit = (
|
|
18181
|
-
hasProperty(intermediateValue, names[index])
|
|
18182
|
-
|| primitiveHasOwnProperty(intermediateValue, names[index])
|
|
18183
|
-
);
|
|
18184
|
-
|
|
18185
|
-
intermediateValue = intermediateValue[names[index++]];
|
|
18186
|
-
}
|
|
18187
|
-
} else {
|
|
18188
|
-
intermediateValue = context.view[name];
|
|
18189
|
-
|
|
18190
|
-
/**
|
|
18191
|
-
* Only checking against `hasProperty`, which always returns `false` if
|
|
18192
|
-
* `context.view` is not an object. Deliberately omitting the check
|
|
18193
|
-
* against `primitiveHasOwnProperty` if dot notation is not used.
|
|
18194
|
-
*
|
|
18195
|
-
* Consider this example:
|
|
18196
|
-
* ```
|
|
18197
|
-
* Mustache.render("The length of a football field is {{#length}}{{length}}{{/length}}.", {length: "100 yards"})
|
|
18198
|
-
* ```
|
|
18199
|
-
*
|
|
18200
|
-
* If we were to check also against `primitiveHasOwnProperty`, as we do
|
|
18201
|
-
* in the dot notation case, then render call would return:
|
|
18202
|
-
*
|
|
18203
|
-
* "The length of a football field is 9."
|
|
18204
|
-
*
|
|
18205
|
-
* rather than the expected:
|
|
18206
|
-
*
|
|
18207
|
-
* "The length of a football field is 100 yards."
|
|
18208
|
-
**/
|
|
18209
|
-
lookupHit = hasProperty(context.view, name);
|
|
18210
|
-
}
|
|
18211
|
-
|
|
18212
|
-
if (lookupHit) {
|
|
18213
|
-
value = intermediateValue;
|
|
18214
|
-
break;
|
|
18215
|
-
}
|
|
18216
|
-
|
|
18217
|
-
context = context.parent;
|
|
18218
|
-
}
|
|
18219
|
-
|
|
18220
|
-
cache[name] = value;
|
|
18221
|
-
}
|
|
18222
|
-
|
|
18223
|
-
if (isFunction(value))
|
|
18224
|
-
value = value.call(this.view);
|
|
18225
|
-
|
|
18226
|
-
return value;
|
|
18227
|
-
};
|
|
18228
|
-
|
|
18229
|
-
/**
|
|
18230
|
-
* A Writer knows how to take a stream of tokens and render them to a
|
|
18231
|
-
* string, given a context. It also maintains a cache of templates to
|
|
18232
|
-
* avoid the need to parse the same template twice.
|
|
18233
|
-
*/
|
|
18234
|
-
function Writer () {
|
|
18235
|
-
this.templateCache = {
|
|
18236
|
-
_cache: {},
|
|
18237
|
-
set: function set (key, value) {
|
|
18238
|
-
this._cache[key] = value;
|
|
18239
|
-
},
|
|
18240
|
-
get: function get (key) {
|
|
18241
|
-
return this._cache[key];
|
|
18242
|
-
},
|
|
18243
|
-
clear: function clear () {
|
|
18244
|
-
this._cache = {};
|
|
18245
|
-
}
|
|
18246
|
-
};
|
|
14874
|
+
}))
|
|
14875
|
+
});
|
|
18247
14876
|
}
|
|
18248
14877
|
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
Writer.prototype.clearCache = function clearCache () {
|
|
18253
|
-
if (typeof this.templateCache !== 'undefined') {
|
|
18254
|
-
this.templateCache.clear();
|
|
18255
|
-
}
|
|
18256
|
-
};
|
|
14878
|
+
/* harmony default export */ const message_container = (MessageContainer);
|
|
14879
|
+
;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/choice-prompt.js
|
|
14880
|
+
const choice_prompt_excluded = ["event", "children"];
|
|
18257
14881
|
|
|
18258
|
-
|
|
18259
|
-
* Parses and caches the given `template` according to the given `tags` or
|
|
18260
|
-
* `mustache.tags` if `tags` is omitted, and returns the array of tokens
|
|
18261
|
-
* that is generated from the parse.
|
|
18262
|
-
*/
|
|
18263
|
-
Writer.prototype.parse = function parse (template, tags) {
|
|
18264
|
-
var cache = this.templateCache;
|
|
18265
|
-
var cacheKey = template + ':' + (tags || mustache.tags).join(':');
|
|
18266
|
-
var isCacheEnabled = typeof cache !== 'undefined';
|
|
18267
|
-
var tokens = isCacheEnabled ? cache.get(cacheKey) : undefined;
|
|
14882
|
+
function choice_prompt_objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = choice_prompt_objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
18268
14883
|
|
|
18269
|
-
|
|
18270
|
-
tokens = parseTemplate(template, tags);
|
|
18271
|
-
isCacheEnabled && cache.set(cacheKey, tokens);
|
|
18272
|
-
}
|
|
18273
|
-
return tokens;
|
|
18274
|
-
};
|
|
14884
|
+
function choice_prompt_objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
18275
14885
|
|
|
18276
|
-
|
|
18277
|
-
* High-level method that is used to render the given `template` with
|
|
18278
|
-
* the given `view`.
|
|
18279
|
-
*
|
|
18280
|
-
* The optional `partials` argument may be an object that contains the
|
|
18281
|
-
* names and templates of partials that are used in the template. It may
|
|
18282
|
-
* also be a function that is used to load partial templates on the fly
|
|
18283
|
-
* that takes a single argument: the name of the partial.
|
|
18284
|
-
*
|
|
18285
|
-
* If the optional `config` argument is given here, then it should be an
|
|
18286
|
-
* object with a `tags` attribute or an `escape` attribute or both.
|
|
18287
|
-
* If an array is passed, then it will be interpreted the same way as
|
|
18288
|
-
* a `tags` attribute on a `config` object.
|
|
18289
|
-
*
|
|
18290
|
-
* The `tags` attribute of a `config` object must be an array with two
|
|
18291
|
-
* string values: the opening and closing tags used in the template (e.g.
|
|
18292
|
-
* [ "<%", "%>" ]). The default is to mustache.tags.
|
|
18293
|
-
*
|
|
18294
|
-
* The `escape` attribute of a `config` object must be a function which
|
|
18295
|
-
* accepts a string as input and outputs a safely escaped string.
|
|
18296
|
-
* If an `escape` function is not provided, then an HTML-safe string
|
|
18297
|
-
* escaping function is used as the default.
|
|
18298
|
-
*/
|
|
18299
|
-
Writer.prototype.render = function render (template, view, partials, config) {
|
|
18300
|
-
var tags = this.getConfigTags(config);
|
|
18301
|
-
var tokens = this.parse(template, tags);
|
|
18302
|
-
var context = (view instanceof Context) ? view : new Context(view, undefined);
|
|
18303
|
-
return this.renderTokens(tokens, context, partials, template, config);
|
|
18304
|
-
};
|
|
14886
|
+
function choice_prompt_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
18305
14887
|
|
|
18306
|
-
|
|
18307
|
-
* Low-level method that renders the given array of `tokens` using
|
|
18308
|
-
* the given `context` and `partials`.
|
|
18309
|
-
*
|
|
18310
|
-
* Note: The `originalTemplate` is only ever used to extract the portion
|
|
18311
|
-
* of the original template that was contained in a higher-order section.
|
|
18312
|
-
* If the template doesn't use higher-order sections, this argument may
|
|
18313
|
-
* be omitted.
|
|
18314
|
-
*/
|
|
18315
|
-
Writer.prototype.renderTokens = function renderTokens (tokens, context, partials, originalTemplate, config) {
|
|
18316
|
-
var buffer = '';
|
|
14888
|
+
function choice_prompt_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? choice_prompt_ownKeys(Object(source), !0).forEach(function (key) { choice_prompt_defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : choice_prompt_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
18317
14889
|
|
|
18318
|
-
|
|
18319
|
-
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
|
|
18320
|
-
value = undefined;
|
|
18321
|
-
token = tokens[i];
|
|
18322
|
-
symbol = token[0];
|
|
14890
|
+
function choice_prompt_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
18323
14891
|
|
|
18324
|
-
if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate, config);
|
|
18325
|
-
else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate, config);
|
|
18326
|
-
else if (symbol === '>') value = this.renderPartial(token, context, partials, config);
|
|
18327
|
-
else if (symbol === '&') value = this.unescapedValue(token, context);
|
|
18328
|
-
else if (symbol === 'name') value = this.escapedValue(token, context, config);
|
|
18329
|
-
else if (symbol === 'text') value = this.rawValue(token);
|
|
18330
14892
|
|
|
18331
|
-
if (value !== undefined)
|
|
18332
|
-
buffer += value;
|
|
18333
|
-
}
|
|
18334
14893
|
|
|
18335
|
-
return buffer;
|
|
18336
|
-
};
|
|
18337
14894
|
|
|
18338
|
-
Writer.prototype.renderSection = function renderSection (token, context, partials, originalTemplate, config) {
|
|
18339
|
-
var self = this;
|
|
18340
|
-
var buffer = '';
|
|
18341
|
-
var value = context.lookup(token[1]);
|
|
18342
14895
|
|
|
18343
|
-
// This function is used to render an arbitrary template
|
|
18344
|
-
// in the current context by higher-order sections.
|
|
18345
|
-
function subRender (template) {
|
|
18346
|
-
return self.render(template, context, partials, config);
|
|
18347
|
-
}
|
|
18348
14896
|
|
|
18349
|
-
if (!value) return;
|
|
18350
14897
|
|
|
18351
|
-
if (isArray(value)) {
|
|
18352
|
-
for (var j = 0, valueLength = value.length; j < valueLength; ++j) {
|
|
18353
|
-
buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate, config);
|
|
18354
|
-
}
|
|
18355
|
-
} else if (typeof value === 'object' || typeof value === 'string' || typeof value === 'number') {
|
|
18356
|
-
buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate, config);
|
|
18357
|
-
} else if (isFunction(value)) {
|
|
18358
|
-
if (typeof originalTemplate !== 'string')
|
|
18359
|
-
throw new Error('Cannot use higher-order sections without the original template');
|
|
18360
14898
|
|
|
18361
|
-
// Extract the portion of the original template that the section contains.
|
|
18362
|
-
value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);
|
|
18363
14899
|
|
|
18364
|
-
if (value != null)
|
|
18365
|
-
buffer += value;
|
|
18366
|
-
} else {
|
|
18367
|
-
buffer += this.renderTokens(token[4], context, partials, originalTemplate, config);
|
|
18368
|
-
}
|
|
18369
|
-
return buffer;
|
|
18370
|
-
};
|
|
18371
14900
|
|
|
18372
|
-
Writer.prototype.renderInverted = function renderInverted (token, context, partials, originalTemplate, config) {
|
|
18373
|
-
var value = context.lookup(token[1]);
|
|
18374
14901
|
|
|
18375
|
-
// Use JavaScript's definition of falsy. Include empty arrays.
|
|
18376
|
-
// See https://github.com/janl/mustache.js/issues/186
|
|
18377
|
-
if (!value || (isArray(value) && value.length === 0))
|
|
18378
|
-
return this.renderTokens(token[4], context, partials, originalTemplate, config);
|
|
18379
|
-
};
|
|
18380
14902
|
|
|
18381
|
-
Writer.prototype.indentPartial = function indentPartial (partial, indentation, lineHasNonSpace) {
|
|
18382
|
-
var filteredIndentation = indentation.replace(/[^ \t]/g, '');
|
|
18383
|
-
var partialByNl = partial.split('\n');
|
|
18384
|
-
for (var i = 0; i < partialByNl.length; i++) {
|
|
18385
|
-
if (partialByNl[i].length && (i > 0 || !lineHasNonSpace)) {
|
|
18386
|
-
partialByNl[i] = filteredIndentation + partialByNl[i];
|
|
18387
|
-
}
|
|
18388
|
-
}
|
|
18389
|
-
return partialByNl.join('\n');
|
|
18390
|
-
};
|
|
18391
14903
|
|
|
18392
|
-
|
|
18393
|
-
|
|
18394
|
-
|
|
14904
|
+
const useChoicePrompt = event => {
|
|
14905
|
+
const {
|
|
14906
|
+
payload
|
|
14907
|
+
} = event;
|
|
14908
|
+
const [showOptions, setShowOptions] = (0,hooks_namespaceObject.useState)(false);
|
|
14909
|
+
const {
|
|
14910
|
+
sendAction,
|
|
14911
|
+
addMessageBubble,
|
|
14912
|
+
addDivider
|
|
14913
|
+
} = use_seamly_commands();
|
|
14914
|
+
const {
|
|
14915
|
+
activeServiceSessionId
|
|
14916
|
+
} = useSeamlyServiceInfo();
|
|
14917
|
+
const lastEventId = useLastMessageEventId();
|
|
14918
|
+
const [body] = useTranslatedEventData(event);
|
|
14919
|
+
const {
|
|
14920
|
+
service
|
|
14921
|
+
} = payload;
|
|
14922
|
+
const subEvent = (0,hooks_namespaceObject.useMemo)(() => {
|
|
14923
|
+
return choice_prompt_objectSpread(choice_prompt_objectSpread({}, event), {}, {
|
|
14924
|
+
payload: choice_prompt_objectSpread(choice_prompt_objectSpread({}, event.payload), {}, {
|
|
14925
|
+
body: event.payload.body?.prompt,
|
|
14926
|
+
translatedBody: event.payload.translatedBody && choice_prompt_objectSpread(choice_prompt_objectSpread({}, event.payload.translatedBody), {}, {
|
|
14927
|
+
data: event.payload.translatedBody.data.prompt
|
|
14928
|
+
})
|
|
14929
|
+
})
|
|
14930
|
+
});
|
|
14931
|
+
}, [event]);
|
|
14932
|
+
const chooseAgain = body.chooseAgain && activeServiceSessionId === service.serviceSessionId && payload.id !== lastEventId;
|
|
14933
|
+
(0,hooks_namespaceObject.useEffect)(() => {
|
|
14934
|
+
setShowOptions(payload.id === lastEventId);
|
|
14935
|
+
}, [payload, lastEventId]);
|
|
18395
14936
|
|
|
18396
|
-
|
|
18397
|
-
|
|
18398
|
-
|
|
18399
|
-
var tagIndex = token[5];
|
|
18400
|
-
var indentation = token[4];
|
|
18401
|
-
var indentedValue = value;
|
|
18402
|
-
if (tagIndex == 0 && indentation) {
|
|
18403
|
-
indentedValue = this.indentPartial(value, indentation, lineHasNonSpace);
|
|
14937
|
+
const onChoiceClickHandler = choice => {
|
|
14938
|
+
if (chooseAgain) {
|
|
14939
|
+
addDivider('new_topic');
|
|
18404
14940
|
}
|
|
18405
|
-
var tokens = this.parse(indentedValue, tags);
|
|
18406
|
-
return this.renderTokens(tokens, context, partials, indentedValue, config);
|
|
18407
|
-
}
|
|
18408
|
-
};
|
|
18409
|
-
|
|
18410
|
-
Writer.prototype.unescapedValue = function unescapedValue (token, context) {
|
|
18411
|
-
var value = context.lookup(token[1]);
|
|
18412
|
-
if (value != null)
|
|
18413
|
-
return value;
|
|
18414
|
-
};
|
|
18415
|
-
|
|
18416
|
-
Writer.prototype.escapedValue = function escapedValue (token, context, config) {
|
|
18417
|
-
var escape = this.getConfigEscape(config) || mustache.escape;
|
|
18418
|
-
var value = context.lookup(token[1]);
|
|
18419
|
-
if (value != null)
|
|
18420
|
-
return (typeof value === 'number' && escape === mustache.escape) ? String(value) : escape(value);
|
|
18421
|
-
};
|
|
18422
|
-
|
|
18423
|
-
Writer.prototype.rawValue = function rawValue (token) {
|
|
18424
|
-
return token[1];
|
|
18425
|
-
};
|
|
18426
|
-
|
|
18427
|
-
Writer.prototype.getConfigTags = function getConfigTags (config) {
|
|
18428
|
-
if (isArray(config)) {
|
|
18429
|
-
return config;
|
|
18430
|
-
}
|
|
18431
|
-
else if (config && typeof config === 'object') {
|
|
18432
|
-
return config.tags;
|
|
18433
|
-
}
|
|
18434
|
-
else {
|
|
18435
|
-
return undefined;
|
|
18436
|
-
}
|
|
18437
|
-
};
|
|
18438
|
-
|
|
18439
|
-
Writer.prototype.getConfigEscape = function getConfigEscape (config) {
|
|
18440
|
-
if (config && typeof config === 'object' && !isArray(config)) {
|
|
18441
|
-
return config.escape;
|
|
18442
|
-
}
|
|
18443
|
-
else {
|
|
18444
|
-
return undefined;
|
|
18445
|
-
}
|
|
18446
|
-
};
|
|
18447
|
-
|
|
18448
|
-
var mustache = {
|
|
18449
|
-
name: 'mustache.js',
|
|
18450
|
-
version: '4.2.0',
|
|
18451
|
-
tags: [ '{{', '}}' ],
|
|
18452
|
-
clearCache: undefined,
|
|
18453
|
-
escape: undefined,
|
|
18454
|
-
parse: undefined,
|
|
18455
|
-
render: undefined,
|
|
18456
|
-
Scanner: undefined,
|
|
18457
|
-
Context: undefined,
|
|
18458
|
-
Writer: undefined,
|
|
18459
|
-
/**
|
|
18460
|
-
* Allows a user to override the default caching strategy, by providing an
|
|
18461
|
-
* object with set, get and clear methods. This can also be used to disable
|
|
18462
|
-
* the cache by setting it to the literal `undefined`.
|
|
18463
|
-
*/
|
|
18464
|
-
set templateCache (cache) {
|
|
18465
|
-
defaultWriter.templateCache = cache;
|
|
18466
|
-
},
|
|
18467
|
-
/**
|
|
18468
|
-
* Gets the default or overridden caching object from the default writer.
|
|
18469
|
-
*/
|
|
18470
|
-
get templateCache () {
|
|
18471
|
-
return defaultWriter.templateCache;
|
|
18472
|
-
}
|
|
18473
|
-
};
|
|
18474
14941
|
|
|
18475
|
-
|
|
18476
|
-
|
|
14942
|
+
addMessageBubble(choice.text);
|
|
14943
|
+
sendAction({
|
|
14944
|
+
type: actionTypes.pickChoice,
|
|
14945
|
+
originMessage: payload.id,
|
|
14946
|
+
choice: {
|
|
14947
|
+
id: choice.id,
|
|
14948
|
+
text: choice.text,
|
|
14949
|
+
chooseAgain
|
|
14950
|
+
}
|
|
14951
|
+
});
|
|
14952
|
+
setShowOptions(false);
|
|
14953
|
+
};
|
|
18477
14954
|
|
|
18478
|
-
|
|
18479
|
-
|
|
18480
|
-
|
|
18481
|
-
mustache.clearCache = function clearCache () {
|
|
18482
|
-
return defaultWriter.clearCache();
|
|
18483
|
-
};
|
|
14955
|
+
const onChooseAgainClickHandler = () => {
|
|
14956
|
+
setShowOptions(s => !s);
|
|
14957
|
+
};
|
|
18484
14958
|
|
|
18485
|
-
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
|
|
18490
|
-
|
|
18491
|
-
|
|
14959
|
+
return {
|
|
14960
|
+
body,
|
|
14961
|
+
subEvent,
|
|
14962
|
+
showOptions,
|
|
14963
|
+
chooseAgain,
|
|
14964
|
+
onChoiceClickHandler,
|
|
14965
|
+
onChooseAgainClickHandler
|
|
14966
|
+
};
|
|
18492
14967
|
};
|
|
18493
14968
|
|
|
18494
|
-
|
|
18495
|
-
|
|
18496
|
-
|
|
18497
|
-
|
|
18498
|
-
|
|
18499
|
-
|
|
18500
|
-
throw new TypeError('Invalid template! Template should be a "string" ' +
|
|
18501
|
-
'but "' + typeStr(template) + '" was given as the first ' +
|
|
18502
|
-
'argument for mustache#render(template, view, partials)');
|
|
18503
|
-
}
|
|
14969
|
+
const ChoicePrompt = _ref => {
|
|
14970
|
+
let {
|
|
14971
|
+
event,
|
|
14972
|
+
children
|
|
14973
|
+
} = _ref,
|
|
14974
|
+
props = choice_prompt_objectWithoutProperties(_ref, choice_prompt_excluded);
|
|
18504
14975
|
|
|
18505
|
-
|
|
14976
|
+
const {
|
|
14977
|
+
t
|
|
14978
|
+
} = useI18n();
|
|
14979
|
+
const descriptorId = useGeneratedId();
|
|
14980
|
+
const {
|
|
14981
|
+
body,
|
|
14982
|
+
subEvent,
|
|
14983
|
+
showOptions,
|
|
14984
|
+
chooseAgain,
|
|
14985
|
+
onChoiceClickHandler,
|
|
14986
|
+
onChooseAgainClickHandler
|
|
14987
|
+
} = useChoicePrompt(event);
|
|
14988
|
+
return (0,jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
|
|
14989
|
+
children: [(0,external_preact_namespaceObject.toChildArray)(children).map(child => {
|
|
14990
|
+
child.props = choice_prompt_objectSpread(choice_prompt_objectSpread({}, child.props), {}, {
|
|
14991
|
+
event: subEvent,
|
|
14992
|
+
descriptorId,
|
|
14993
|
+
showTranslationToggle: false
|
|
14994
|
+
});
|
|
14995
|
+
return child;
|
|
14996
|
+
}), chooseAgain && (0,jsx_runtime_namespaceObject.jsxs)("button", {
|
|
14997
|
+
type: "button",
|
|
14998
|
+
className: css_className('button', 'button--secondary', 'button--choose-again'),
|
|
14999
|
+
"aria-expanded": showOptions ? 'true' : 'false',
|
|
15000
|
+
onClick: onChooseAgainClickHandler,
|
|
15001
|
+
"aria-describedby": descriptorId,
|
|
15002
|
+
children: [showOptions ? t('message.choicePrompts.cancelChooseAgain') : t('message.choicePrompts.chooseAgain'), (0,jsx_runtime_namespaceObject.jsx)(icon, {
|
|
15003
|
+
name: "chevronDown",
|
|
15004
|
+
size: "8"
|
|
15005
|
+
})]
|
|
15006
|
+
}), showOptions && (0,jsx_runtime_namespaceObject.jsx)(message_container, choice_prompt_objectSpread(choice_prompt_objectSpread({
|
|
15007
|
+
type: "choice-prompt",
|
|
15008
|
+
showParticipant: false,
|
|
15009
|
+
event: event
|
|
15010
|
+
}, props), {}, {
|
|
15011
|
+
children: (0,jsx_runtime_namespaceObject.jsx)("ul", {
|
|
15012
|
+
className: css_className('choice-prompt', 'choice-prompt--many'),
|
|
15013
|
+
children: body.choices.map(choice => (0,jsx_runtime_namespaceObject.jsx)("li", {
|
|
15014
|
+
className: css_className('choice-prompt__item', {
|
|
15015
|
+
[`choice-prompt__item--${choice.category}`]: choice.category
|
|
15016
|
+
}),
|
|
15017
|
+
children: (0,jsx_runtime_namespaceObject.jsx)("button", {
|
|
15018
|
+
type: "button",
|
|
15019
|
+
className: css_className('button', 'button--primary'),
|
|
15020
|
+
onClick: () => {
|
|
15021
|
+
onChoiceClickHandler(choice);
|
|
15022
|
+
},
|
|
15023
|
+
children: choice.text
|
|
15024
|
+
})
|
|
15025
|
+
}, choice.id))
|
|
15026
|
+
})
|
|
15027
|
+
}))]
|
|
15028
|
+
});
|
|
18506
15029
|
};
|
|
18507
15030
|
|
|
18508
|
-
|
|
18509
|
-
|
|
18510
|
-
mustache.escape = escapeHtml;
|
|
18511
|
-
|
|
18512
|
-
// Export these mainly for testing, but also for advanced usage.
|
|
18513
|
-
mustache.Scanner = Scanner;
|
|
18514
|
-
mustache.Context = Context;
|
|
18515
|
-
mustache.Writer = Writer;
|
|
18516
|
-
|
|
18517
|
-
/* harmony default export */ const mustache_mustache = (mustache);
|
|
18518
|
-
|
|
18519
|
-
;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/hooks/use-text-rendering.js
|
|
18520
|
-
|
|
15031
|
+
/* harmony default export */ const choice_prompt = (ChoicePrompt);
|
|
15032
|
+
;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/hooks/use-event-link-click-handler.js
|
|
18521
15033
|
|
|
18522
|
-
mustache_mustache.escape = function (escapeText) {
|
|
18523
|
-
return escapeText;
|
|
18524
|
-
};
|
|
18525
15034
|
|
|
18526
|
-
const parseLinkVariable = variable => {
|
|
18527
|
-
return `<a href='${variable.url}' data-link-id='${variable.id}' ${variable.newTab ? 'target="_blank"' : ''}>${variable.name}</a>`;
|
|
18528
|
-
};
|
|
18529
15035
|
|
|
18530
|
-
|
|
18531
|
-
const
|
|
18532
|
-
|
|
18533
|
-
|
|
18534
|
-
case 'link':
|
|
18535
|
-
view[key] = parseLinkVariable(variable);
|
|
18536
|
-
break;
|
|
15036
|
+
const useEventLinkClickHandler = eventId => {
|
|
15037
|
+
const {
|
|
15038
|
+
sendAction
|
|
15039
|
+
} = use_seamly_commands();
|
|
18537
15040
|
|
|
18538
|
-
|
|
18539
|
-
|
|
18540
|
-
|
|
15041
|
+
const eventClick = e => {
|
|
15042
|
+
if (e.target && e.target.dataset.linkId) {
|
|
15043
|
+
sendAction({
|
|
15044
|
+
type: actionTypes.navigate,
|
|
15045
|
+
originMessage: eventId,
|
|
15046
|
+
link: {
|
|
15047
|
+
id: e.target.dataset.linkId,
|
|
15048
|
+
url: e.target.getAttribute('href')
|
|
15049
|
+
}
|
|
15050
|
+
});
|
|
18541
15051
|
}
|
|
18542
|
-
}, {}); // Disable escaping as we'll be generating HTML
|
|
18543
|
-
|
|
18544
|
-
const oldEscape = mustache_mustache.escape;
|
|
18545
|
-
|
|
18546
|
-
mustache_mustache.escape = function (escapeText) {
|
|
18547
|
-
return escapeText;
|
|
18548
15052
|
};
|
|
18549
15053
|
|
|
18550
|
-
|
|
18551
|
-
|
|
18552
|
-
|
|
18553
|
-
|
|
15054
|
+
return eventClick;
|
|
15055
|
+
};
|
|
15056
|
+
|
|
15057
|
+
/* harmony default export */ const use_event_link_click_handler = (useEventLinkClickHandler);
|
|
18554
15058
|
;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/text.js
|
|
18555
15059
|
const text_excluded = ["event"];
|
|
18556
15060
|
|
|
@@ -18570,8 +15074,6 @@ function text_objectWithoutPropertiesLoose(source, excluded) { if (source == nul
|
|
|
18570
15074
|
|
|
18571
15075
|
|
|
18572
15076
|
|
|
18573
|
-
|
|
18574
|
-
|
|
18575
15077
|
const Text = _ref => {
|
|
18576
15078
|
let {
|
|
18577
15079
|
event
|
|
@@ -18581,20 +15083,20 @@ const Text = _ref => {
|
|
|
18581
15083
|
const [body] = useTranslatedEventData(event);
|
|
18582
15084
|
const eventClick = use_event_link_click_handler(event.payload.id);
|
|
18583
15085
|
const containerProps = (0,hooks_namespaceObject.useMemo)(() => {
|
|
18584
|
-
if (
|
|
15086
|
+
if (event.payload.optimisticallyInjected) {
|
|
18585
15087
|
return {
|
|
18586
|
-
|
|
18587
|
-
|
|
18588
|
-
|
|
18589
|
-
}
|
|
18590
|
-
}
|
|
15088
|
+
children: (0,jsx_runtime_namespaceObject.jsx)("p", {
|
|
15089
|
+
children: body.text
|
|
15090
|
+
})
|
|
18591
15091
|
};
|
|
18592
15092
|
}
|
|
18593
15093
|
|
|
18594
15094
|
return {
|
|
18595
|
-
|
|
18596
|
-
|
|
18597
|
-
|
|
15095
|
+
bodyProps: {
|
|
15096
|
+
dangerouslySetInnerHTML: {
|
|
15097
|
+
__html: body.text
|
|
15098
|
+
}
|
|
15099
|
+
}
|
|
18598
15100
|
};
|
|
18599
15101
|
}, [body, event]);
|
|
18600
15102
|
return (0,jsx_runtime_namespaceObject.jsx)(message_container, text_objectSpread(text_objectSpread({
|
|
@@ -20378,9 +16880,6 @@ const Translation = _ref => {
|
|
|
20378
16880
|
|
|
20379
16881
|
|
|
20380
16882
|
|
|
20381
|
-
|
|
20382
|
-
|
|
20383
|
-
|
|
20384
16883
|
const Participant = ({
|
|
20385
16884
|
event
|
|
20386
16885
|
}) => {
|
|
@@ -20388,11 +16887,8 @@ const Participant = ({
|
|
|
20388
16887
|
participant
|
|
20389
16888
|
} = event.payload;
|
|
20390
16889
|
const [introduction] = useTranslatedEventData(event);
|
|
20391
|
-
const intro = (0,hooks_namespaceObject.useMemo)(() => {
|
|
20392
|
-
return introduction ? mustache_mustache.render(parse_body(introduction), participant) : undefined;
|
|
20393
|
-
}, [introduction, participant]);
|
|
20394
16890
|
|
|
20395
|
-
if (!
|
|
16891
|
+
if (!introduction) {
|
|
20396
16892
|
return null;
|
|
20397
16893
|
}
|
|
20398
16894
|
|
|
@@ -20400,7 +16896,7 @@ const Participant = ({
|
|
|
20400
16896
|
graphicSrc: participant.avatar,
|
|
20401
16897
|
graphicType: participant.avatar ? 'avatar' : undefined,
|
|
20402
16898
|
iconName: !participant.avatar ? 'balloon' : undefined,
|
|
20403
|
-
childrenHTML:
|
|
16899
|
+
childrenHTML: introduction,
|
|
20404
16900
|
dividerType: "participant"
|
|
20405
16901
|
});
|
|
20406
16902
|
};
|
|
@@ -20424,8 +16920,6 @@ function splash_objectWithoutPropertiesLoose(source, excluded) { if (source == n
|
|
|
20424
16920
|
|
|
20425
16921
|
|
|
20426
16922
|
|
|
20427
|
-
|
|
20428
|
-
|
|
20429
16923
|
const Splash = _ref => {
|
|
20430
16924
|
let {
|
|
20431
16925
|
event
|
|
@@ -20444,7 +16938,7 @@ const Splash = _ref => {
|
|
|
20444
16938
|
}, props), {}, {
|
|
20445
16939
|
bodyProps: {
|
|
20446
16940
|
dangerouslySetInnerHTML: {
|
|
20447
|
-
__html:
|
|
16941
|
+
__html: body.text
|
|
20448
16942
|
}
|
|
20449
16943
|
}
|
|
20450
16944
|
}));
|
|
@@ -20544,7 +17038,6 @@ const Upload = _ref => {
|
|
|
20544
17038
|
|
|
20545
17039
|
|
|
20546
17040
|
|
|
20547
|
-
|
|
20548
17041
|
const Cta = ({
|
|
20549
17042
|
event
|
|
20550
17043
|
}) => {
|
|
@@ -20568,7 +17061,7 @@ const Cta = ({
|
|
|
20568
17061
|
className: css_className('cta__content'),
|
|
20569
17062
|
id: descriptionId,
|
|
20570
17063
|
dangerouslySetInnerHTML: {
|
|
20571
|
-
__html:
|
|
17064
|
+
__html: body.description
|
|
20572
17065
|
},
|
|
20573
17066
|
onClick: eventClick
|
|
20574
17067
|
}), (0,jsx_runtime_namespaceObject.jsx)("a", {
|
|
@@ -20598,7 +17091,6 @@ function card_component_defineProperty(obj, key, value) { if (key in obj) { Obje
|
|
|
20598
17091
|
|
|
20599
17092
|
|
|
20600
17093
|
|
|
20601
|
-
|
|
20602
17094
|
const CardComponent = ({
|
|
20603
17095
|
id,
|
|
20604
17096
|
action,
|
|
@@ -20682,7 +17174,7 @@ const CardComponent = ({
|
|
|
20682
17174
|
}), description && (0,jsx_runtime_namespaceObject.jsx)("div", {
|
|
20683
17175
|
className: css_className('card__description'),
|
|
20684
17176
|
dangerouslySetInnerHTML: {
|
|
20685
|
-
__html:
|
|
17177
|
+
__html: description
|
|
20686
17178
|
}
|
|
20687
17179
|
}), (0,jsx_runtime_namespaceObject.jsx)(CardActionComponent, card_component_objectSpread(card_component_objectSpread({
|
|
20688
17180
|
tabIndex: isCarouselItem && !hasFocus ? '-1' : undefined // disable to prevent tabbing through cards
|
|
@@ -21033,11 +17525,17 @@ const ConversationSuggestions = _ref => {
|
|
|
21033
17525
|
suggestions,
|
|
21034
17526
|
payload
|
|
21035
17527
|
} = useSuggestions(event);
|
|
17528
|
+
const events = useEvents();
|
|
21036
17529
|
const {
|
|
21037
17530
|
t
|
|
21038
17531
|
} = useI18n();
|
|
21039
17532
|
const headingText = t('suggestions.headingText');
|
|
21040
|
-
const footerText = t('suggestions.footerText');
|
|
17533
|
+
const footerText = t('suggestions.footerText'); // We check if there is at least one last transaction
|
|
17534
|
+
// to avoid rendering the suggestions before prior events are rendered.
|
|
17535
|
+
|
|
17536
|
+
const hasLastTransactionEvent = (0,hooks_namespaceObject.useMemo)(() => events.some(({
|
|
17537
|
+
payload: eventPayload
|
|
17538
|
+
}) => eventPayload?.transactionLast), [events]);
|
|
21041
17539
|
const handleClick = (0,hooks_namespaceObject.useCallback)(({
|
|
21042
17540
|
id,
|
|
21043
17541
|
question
|
|
@@ -21059,7 +17557,7 @@ const ConversationSuggestions = _ref => {
|
|
|
21059
17557
|
addMessageBubble(question);
|
|
21060
17558
|
}, [dispatch, sendAction, payload.id, addMessageBubble]);
|
|
21061
17559
|
|
|
21062
|
-
if (!isExpanded || userResponded) {
|
|
17560
|
+
if (!isExpanded || userResponded || !hasLastTransactionEvent) {
|
|
21063
17561
|
return null;
|
|
21064
17562
|
}
|
|
21065
17563
|
|
|
@@ -22417,7 +18915,7 @@ const Options = () => {
|
|
|
22417
18915
|
return RenderOption ? (0,jsx_runtime_namespaceObject.jsx)(RenderOption, {}) : null;
|
|
22418
18916
|
};
|
|
22419
18917
|
|
|
22420
|
-
/* harmony default export */ const
|
|
18918
|
+
/* harmony default export */ const options = (Options);
|
|
22421
18919
|
;// CONCATENATED MODULE: ./src/javascripts/ui/components/options/options-button.js
|
|
22422
18920
|
|
|
22423
18921
|
|
|
@@ -22581,7 +19079,7 @@ const OptionsButton = () => {
|
|
|
22581
19079
|
isActive: panelActive,
|
|
22582
19080
|
children: (0,jsx_runtime_namespaceObject.jsx)("div", {
|
|
22583
19081
|
className: css_className('options__dialog'),
|
|
22584
|
-
children: (0,jsx_runtime_namespaceObject.jsx)(
|
|
19082
|
+
children: (0,jsx_runtime_namespaceObject.jsx)(options, {})
|
|
22585
19083
|
})
|
|
22586
19084
|
}), multiMenu && (0,jsx_runtime_namespaceObject.jsx)(in_out_transition, {
|
|
22587
19085
|
isActive: menuIsOpen,
|
|
@@ -22808,6 +19306,10 @@ function inline_view_defineProperty(obj, key, value) { if (key in obj) { Object.
|
|
|
22808
19306
|
|
|
22809
19307
|
const InlineView = () => {
|
|
22810
19308
|
use_seamly_chat();
|
|
19309
|
+
const {
|
|
19310
|
+
showInlineView,
|
|
19311
|
+
containerRef
|
|
19312
|
+
} = useShowInlineView();
|
|
22811
19313
|
const {
|
|
22812
19314
|
isOpen
|
|
22813
19315
|
} = useVisibility();
|
|
@@ -22825,6 +19327,7 @@ const InlineView = () => {
|
|
|
22825
19327
|
isActive: !isOpen,
|
|
22826
19328
|
transitionStartState: transitionStartStates.rendered,
|
|
22827
19329
|
children: (0,jsx_runtime_namespaceObject.jsxs)("div", {
|
|
19330
|
+
ref: containerRef,
|
|
22828
19331
|
className: css_className('unstarted-wrapper', 'unstarted-wrapper--inline'),
|
|
22829
19332
|
children: [(0,jsx_runtime_namespaceObject.jsx)(PreChatMessages, {}), (0,jsx_runtime_namespaceObject.jsx)(suggestions, {})]
|
|
22830
19333
|
})
|
|
@@ -22832,7 +19335,8 @@ const InlineView = () => {
|
|
|
22832
19335
|
isActive: isOpen,
|
|
22833
19336
|
transitionStartState: transitionStartStates.rendered,
|
|
22834
19337
|
children: (0,jsx_runtime_namespaceObject.jsx)(chat, {
|
|
22835
|
-
|
|
19338
|
+
ref: containerRef,
|
|
19339
|
+
children: showInlineView && (0,jsx_runtime_namespaceObject.jsxs)(chat_frame, {
|
|
22836
19340
|
interruptComponent: interrupt,
|
|
22837
19341
|
children: [isOpen && (0,jsx_runtime_namespaceObject.jsx)(conversation, {}), (0,jsx_runtime_namespaceObject.jsx)(entry_container, {})]
|
|
22838
19342
|
})
|
|
@@ -25841,6 +22345,7 @@ class API {
|
|
|
25841
22345
|
this.configReady = false;
|
|
25842
22346
|
this.externalId = config.externalId;
|
|
25843
22347
|
this.layoutMode = layoutMode;
|
|
22348
|
+
this.userResponded = false;
|
|
25844
22349
|
this.internalProducer = new EventProducer('API');
|
|
25845
22350
|
this.internal$ = xstream_default().create(this.internalProducer).flatten();
|
|
25846
22351
|
this.connection$ = this.internal$.filter(event => event.type === 'connection');
|
|
@@ -25853,7 +22358,14 @@ class API {
|
|
|
25853
22358
|
this.ready = ready;
|
|
25854
22359
|
}
|
|
25855
22360
|
});
|
|
25856
|
-
this.URLS = {};
|
|
22361
|
+
this.URLS = {}; // We want to reconnect whenever the page is loaded from cache (bfcache).
|
|
22362
|
+
// Older browsers don't support 'pageshow' and 'bfcache' so this will be ignored and work as usual.
|
|
22363
|
+
|
|
22364
|
+
window.addEventListener('pageshow', event => {
|
|
22365
|
+
if (event.persisted && this.connected) {
|
|
22366
|
+
this.connect();
|
|
22367
|
+
}
|
|
22368
|
+
});
|
|
25857
22369
|
}
|
|
25858
22370
|
|
|
25859
22371
|
getAccessToken() {
|
|
@@ -25886,6 +22398,8 @@ class API {
|
|
|
25886
22398
|
this.store.set('channelTopic', topic);
|
|
25887
22399
|
}
|
|
25888
22400
|
|
|
22401
|
+
getLocale = locale => locale || this.locale;
|
|
22402
|
+
|
|
25889
22403
|
clearStore() {
|
|
25890
22404
|
this.store.delete('accessToken');
|
|
25891
22405
|
this.store.delete('conversationUrl'); // TODO: Remove `channelName` when all clients have been upgraded past v20.
|
|
@@ -25950,6 +22464,8 @@ class API {
|
|
|
25950
22464
|
this.setChannelTopic(conversation.channelTopic);
|
|
25951
22465
|
this.updateUrls(body);
|
|
25952
22466
|
this.setConversationUrl(this.URLS.conversation);
|
|
22467
|
+
this.locale = conversation.translation?.locale;
|
|
22468
|
+
this.userResponded = conversation.userResponded;
|
|
25953
22469
|
return initialState;
|
|
25954
22470
|
} catch (error) {
|
|
25955
22471
|
if (error.status >= 500) {
|
|
@@ -26095,6 +22611,7 @@ class API {
|
|
|
26095
22611
|
body
|
|
26096
22612
|
}) => {
|
|
26097
22613
|
this.updateUrls(body);
|
|
22614
|
+
this.userResponded = body.conversation.userResponded;
|
|
26098
22615
|
return omit(body.conversation, ['accessToken', 'channelTopic']);
|
|
26099
22616
|
}).catch(error => {
|
|
26100
22617
|
if (error.status === 401) {
|
|
@@ -26115,7 +22632,7 @@ class API {
|
|
|
26115
22632
|
|
|
26116
22633
|
async getTranslations(locale) {
|
|
26117
22634
|
try {
|
|
26118
|
-
const url = `${this.getUrlPrefix('http')}${this.URLS.translations}`.replace('{version}', String(TRANSLATIONS_VERSION)).replace('{locale}', locale);
|
|
22635
|
+
const url = `${this.getUrlPrefix('http')}${this.URLS.translations}`.replace('{version}', String(TRANSLATIONS_VERSION)).replace('{locale}', this.getLocale(locale));
|
|
26119
22636
|
const request = client_default().get(url);
|
|
26120
22637
|
const {
|
|
26121
22638
|
body
|
|
@@ -26182,7 +22699,7 @@ class API {
|
|
|
26182
22699
|
return {
|
|
26183
22700
|
clientName: "@seamly/web-ui",
|
|
26184
22701
|
clientVariant: this.layoutMode,
|
|
26185
|
-
clientVersion: "20.
|
|
22702
|
+
clientVersion: "20.5.0",
|
|
26186
22703
|
currentUrl: window.location.toString(),
|
|
26187
22704
|
screenResolution: `${window.screen.width}x${window.screen.height}`,
|
|
26188
22705
|
timezone: getTimeZone(),
|
|
@@ -27196,16 +23713,23 @@ const DeprecatedView = () => {
|
|
|
27196
23713
|
openChat,
|
|
27197
23714
|
closeChat
|
|
27198
23715
|
} = use_seamly_chat();
|
|
27199
|
-
|
|
27200
|
-
|
|
27201
|
-
|
|
27202
|
-
|
|
27203
|
-
|
|
27204
|
-
|
|
27205
|
-
|
|
27206
|
-
|
|
27207
|
-
|
|
27208
|
-
|
|
23716
|
+
const {
|
|
23717
|
+
showInlineView,
|
|
23718
|
+
containerRef
|
|
23719
|
+
} = useShowInlineView();
|
|
23720
|
+
return isVisible && (0,jsx_runtime_namespaceObject.jsx)("div", {
|
|
23721
|
+
ref: containerRef,
|
|
23722
|
+
children: showInlineView && (0,jsx_runtime_namespaceObject.jsxs)(deprecated_app_frame, {
|
|
23723
|
+
children: [(0,jsx_runtime_namespaceObject.jsx)(deprecated_toggle_button, {
|
|
23724
|
+
onOpenChat: openChat
|
|
23725
|
+
}), (0,jsx_runtime_namespaceObject.jsx)(header, {
|
|
23726
|
+
onCloseChat: closeChat,
|
|
23727
|
+
children: (0,jsx_runtime_namespaceObject.jsx)(agent_info, {})
|
|
23728
|
+
}), (0,jsx_runtime_namespaceObject.jsxs)(chat_frame, {
|
|
23729
|
+
interruptComponent: interrupt,
|
|
23730
|
+
children: [(0,jsx_runtime_namespaceObject.jsx)(conversation, {}), (0,jsx_runtime_namespaceObject.jsx)(entry_container, {})]
|
|
23731
|
+
})]
|
|
23732
|
+
})
|
|
27209
23733
|
});
|
|
27210
23734
|
};
|
|
27211
23735
|
|