use std::{
os::raw::c_void,
ptr::null_mut,
sync::atomic::{AtomicPtr, Ordering},
};
use crate::tree::{XmlDocPtr, XmlElementType, XmlNodePtr};
use super::xmlstring::XmlChar;
pub type XlinkHRef = *mut XmlChar;
pub type XlinkRole = *mut XmlChar;
pub type XlinkTitle = *mut XmlChar;
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum XlinkType {
XlinkTypeNone = 0,
XlinkTypeSimple,
XlinkTypeExtended,
XlinkTypeExtendedSet,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum XlinkShow {
XlinkShowNone = 0,
XlinkShowNew,
XlinkShowEmbed,
XlinkShowReplace,
}
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum XlinkActuate {
XlinkActuateNone = 0,
XlinkActuateAuto,
XlinkActuateOnrequest,
}
#[doc(alias = "xlinkNodeDetectFunc")]
pub type XlinkNodeDetectFunc = unsafe fn(ctx: *mut c_void, node: XmlNodePtr);
#[doc(alias = "xlinkSimpleLinkFunk")]
pub type XlinkSimpleLinkFunk = unsafe fn(
ctx: *mut c_void,
node: XmlNodePtr,
href: *const XmlChar,
role: *const XmlChar,
title: *const XmlChar,
);
#[doc(alias = "xlinkExtendedLinkFunk")]
pub type XlinkExtendedLinkFunk = unsafe fn(
ctx: *mut c_void,
node: XmlNodePtr,
nbLocators: i32,
hrefs: *mut *const XmlChar,
roles: *mut *const XmlChar,
nbArcs: i32,
from: *mut *const XmlChar,
to: *mut *const XmlChar,
show: *mut XlinkShow,
actuate: *mut XlinkActuate,
nbTitles: i32,
titles: *mut *const XmlChar,
langs: *mut *const XmlChar,
);
#[doc(alias = "xlinkExtendedLinkSetFunk")]
pub type XlinkExtendedLinkSetFunk = unsafe fn(
ctx: *mut c_void,
node: XmlNodePtr,
nbLocators: i32,
hrefs: *mut *const XmlChar,
roles: *mut *const XmlChar,
nbTitles: i32,
titles: *mut *const XmlChar,
langs: *mut *const XmlChar,
);
pub type XlinkHandlerPtr = *mut XlinkHandler;
#[repr(C)]
pub struct XlinkHandler {
simple: XlinkSimpleLinkFunk,
extended: XlinkExtendedLinkFunk,
set: XlinkExtendedLinkSetFunk,
}
static XLINK_DEFAULT_HANDLER: AtomicPtr<XlinkHandler> = AtomicPtr::new(null_mut());
static mut XLINK_DEFAULT_DETECT: Option<XlinkNodeDetectFunc> = None;
#[doc(alias = "xlinkGetDefaultDetect")]
pub unsafe fn xlink_get_default_detect() -> Option<XlinkNodeDetectFunc> {
unsafe { XLINK_DEFAULT_DETECT }
}
#[doc(alias = "xlinkSetDefaultDetect")]
pub unsafe fn xlink_set_default_detect(func: Option<XlinkNodeDetectFunc>) {
unsafe {
XLINK_DEFAULT_DETECT = func;
}
}
#[doc(alias = "xlinkGetDefaultHandler")]
pub unsafe fn xlink_get_default_handler() -> XlinkHandlerPtr {
XLINK_DEFAULT_HANDLER.load(Ordering::Acquire)
}
#[doc(alias = "xlinkSetDefaultHandler")]
pub unsafe fn xlink_set_default_handler(handler: XlinkHandlerPtr) {
XLINK_DEFAULT_HANDLER.store(handler, Ordering::Release);
}
const XLINK_NAMESPACE: &str = "http://www.w3.org/1999/xlink/namespace/";
const XHTML_NAMESPACE: &str = "http://www.w3.org/1999/xhtml/";
#[doc(alias = "xlinkIsLink")]
pub fn xlink_is_link(doc: Option<XmlDocPtr>, mut node: XmlNodePtr) -> XlinkType {
let mut ret: XlinkType = XlinkType::XlinkTypeNone;
let doc = doc.or(node.doc);
if let Some(_doc) = doc.filter(|doc| doc.typ == XmlElementType::XmlHTMLDocumentNode) {
} else if node
.ns
.is_some_and(|ns| ns.href().as_deref() == Some(XHTML_NAMESPACE))
{
}
if let Some(typ) = node.get_ns_prop("type", Some(XLINK_NAMESPACE)) {
if typ == "simple" {
ret = XlinkType::XlinkTypeSimple;
} else if typ == "extended" {
if let Some(role) = node.get_ns_prop("role", Some(XLINK_NAMESPACE)) {
if let Some(xlink) = node.search_ns(doc, Some(XLINK_NAMESPACE)) {
let buf = format!("{}:external-linkset", (*xlink).prefix().unwrap());
if role == buf {
}
} else {
if role == "xlink:external-linkset" {
}
}
}
ret = XlinkType::XlinkTypeExtended;
}
}
ret
}