feat: Initial clean release of CHM
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
这个提交包含在:
@@ -0,0 +1,102 @@
|
||||
|
||||
|
||||
import * as utils from '../utils';
|
||||
import { AllHtmlEntities as Entities } from 'html-entities';
|
||||
const htmlentities = new Entities().encode;
|
||||
|
||||
|
||||
export interface Options {
|
||||
enableLongPress: boolean;
|
||||
postMessageSyntax: string;
|
||||
|
||||
enableEditPopup: boolean;
|
||||
createEditPopupSyntax?: string;
|
||||
destroyEditPopupSyntax?: string;
|
||||
}
|
||||
|
||||
// longPressTouchStart and clearLongPressTimeout are turned into strings before being called.
|
||||
// Thus, they should not reference any other non-builtin functions.
|
||||
const longPressTouchStartFnString = `(onLongPress, longPressDelay) => {
|
||||
// if touchTimeout is set when ontouchstart is called it means the user has already touched
|
||||
// the screen once and this is the 2nd touch in this case we assume the user is trying
|
||||
// to zoom and we don't want to show the menu
|
||||
if (!!window.touchTimeout) {
|
||||
clearTimeout(window.touchTimeout);
|
||||
window.touchTimeout = null;
|
||||
} else {
|
||||
window.touchTimeout = setTimeout(() => {
|
||||
window.touchTimeout = null;
|
||||
onLongPress();
|
||||
}, longPressDelay);
|
||||
}
|
||||
}`;
|
||||
|
||||
const clearLongPressTimeoutFnString = `() => {
|
||||
if (window.touchTimeout) {
|
||||
clearTimeout(window.touchTimeout);
|
||||
window.touchTimeout = null;
|
||||
}
|
||||
}`;
|
||||
|
||||
// Helper for createEventHandlingAttrs. Exported to facilitate testing.
|
||||
export const createEventHandlingListeners = (resourceId: string, options: Options, onClickAction: string|null) => {
|
||||
const eventHandlers = {
|
||||
ontouchstart: '',
|
||||
ontouchmove: '',
|
||||
ontouchend: '',
|
||||
ontouchcancel: '',
|
||||
onmouseenter: '',
|
||||
onmouseleave: '',
|
||||
onclick: '',
|
||||
};
|
||||
|
||||
if (options.enableLongPress) {
|
||||
const longPressHandler = `(() => ${options.postMessageSyntax}(${JSON.stringify(`longclick:${resourceId}`)}))`;
|
||||
const touchStart = `(${longPressTouchStartFnString})(${longPressHandler}, ${utils.longPressDelay}); `;
|
||||
|
||||
const callClearLongPressTimeout = `(${clearLongPressTimeoutFnString})(); `;
|
||||
const touchCancel = callClearLongPressTimeout;
|
||||
const touchEnd = callClearLongPressTimeout;
|
||||
|
||||
eventHandlers.ontouchstart += touchStart;
|
||||
eventHandlers.ontouchcancel += touchCancel;
|
||||
eventHandlers.ontouchmove += touchCancel;
|
||||
eventHandlers.ontouchend += touchEnd;
|
||||
}
|
||||
|
||||
if (options.enableEditPopup) {
|
||||
const editPopupClick = `(() => ${options.postMessageSyntax}(${JSON.stringify(`edit:${resourceId}`)}))`;
|
||||
const createEditPopup = ` (${options.createEditPopupSyntax})(this, ${JSON.stringify(resourceId)}, ${editPopupClick}); `;
|
||||
eventHandlers.ontouchstart += createEditPopup;
|
||||
|
||||
eventHandlers.onclick += createEditPopup;
|
||||
}
|
||||
|
||||
if (onClickAction) {
|
||||
eventHandlers.onclick += onClickAction;
|
||||
}
|
||||
|
||||
return eventHandlers;
|
||||
};
|
||||
|
||||
// Adds event-handling (e.g. long press) code to images and links.
|
||||
// resourceId is the ID of the image resource or link.
|
||||
const createEventHandlingAttrs = (resourceId: string, options: Options, onClickAction: string|null) => {
|
||||
const eventHandlers = createEventHandlingListeners(resourceId, options, onClickAction);
|
||||
|
||||
// Build onfoo="listener" strings and add them to the result.
|
||||
let result = '';
|
||||
for (const listenerType in eventHandlers) {
|
||||
const eventHandlersDict = eventHandlers as Record<string, string>;
|
||||
|
||||
// Only create code for non-empty listeners.
|
||||
if (eventHandlersDict[listenerType].length > 0) {
|
||||
const listener = htmlentities(eventHandlersDict[listenerType]);
|
||||
result += ` ${listenerType}="${listener}" `;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export default createEventHandlingAttrs;
|
||||
在新工单中引用
屏蔽一个用户