blob: 805156a3cae2f2deb2857cccef9f318165da210d [file] [log] [blame]
Daniel Veillard10a2c651999-12-12 13:03:50 +00001/*
2 * xlink.c : implementation of the hyperlinks detection module
3 * This version supports both XML XLinks and HTML simple links
4 *
5 * See Copyright for the status of this software.
6 *
7 * Daniel.Veillard@w3.org
8 */
9
10
11#ifdef WIN32
12#define HAVE_FCNTL_H
13#include <io.h>
14#else
15#include "config.h"
16#endif
17
18#include <stdio.h>
19#include <string.h> /* for memset() only */
20#ifdef HAVE_CTYPE_H
21#include <ctype.h>
22#endif
23#ifdef HAVE_STDLIB_H
24#include <stdlib.h>
25#endif
26#ifdef HAVE_SYS_STAT_H
27#include <sys/stat.h>
28#endif
29#ifdef HAVE_FCNTL_H
30#include <fcntl.h>
31#endif
32#ifdef HAVE_UNISTD_H
33#include <unistd.h>
34#endif
35#ifdef HAVE_ZLIB_H
36#include <zlib.h>
37#endif
38
39#include "xmlmemory.h"
40#include "tree.h"
41#include "parser.h"
42#include "valid.h"
43#include "xlink.h"
44
45#define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/")
46#define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/")
47
48/****************************************************************
49 * *
50 * Default setting and related functions *
51 * *
52 ****************************************************************/
53
54xlinkHandlerPtr xlinkDefaultHandler = NULL;
55xlinkNodeDetectFunc xlinkDefaultDetect = NULL;
56
57/**
58 * xlinkGetDefaultHandler:
59 *
60 * Get the default xlink handler.
61 *
62 * Returns the current xlinkHandlerPtr value.
63 */
64xlinkHandlerPtr
65xlinkGetDefaultHandler(void) {
66 return(xlinkDefaultHandler);
67}
68
69
70/**
71 * xlinkGetDefaultHandler:
72 * @handler: the new value for the xlink handler block
73 *
74 * Set the default xlink handlers
75 */
76void
77xlinkSetDefaultHandler(xlinkHandlerPtr handler) {
78 xlinkDefaultHandler = handler;
79}
80
81/**
82 * xlinkGetDefaultDetect:
83 *
84 * Get the default xlink detection routine
85 *
86 * Returns the current function or NULL;
87 */
88xlinkNodeDetectFunc
89xlinkGetDefaultDetect (void) {
90 return(xlinkDefaultDetect);
91}
92
93/**
94 * xlinkSetDefaultDetect:
95 * @func: pointer to the new detction routine.
96 *
97 * Set the default xlink detection routine
98 */
99void
100xlinkSetDefaultDetect (xlinkNodeDetectFunc func) {
101 xlinkDefaultDetect = func;
102}
103
104/****************************************************************
105 * *
106 * The detection routines *
107 * *
108 ****************************************************************/
109
110
111/**
112 * xlinkIsLink:
113 * @doc: the document containing the node
114 * @node: the node pointer itself
115 *
116 * Check whether the given node carries the attributes needed
117 * to be a link element (or is one of the linking elements issued
118 * from the (X)HTML DtDs).
119 * This routine don't try to do full checking of the link validity
120 * but tries to detect and return the appropriate link type.
121 *
122 * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no
123 * link detected.
124 */
125xlinkType
126xlinkIsLink (xmlDocPtr doc, xmlNodePtr node) {
127 xmlChar *type = NULL, *role = NULL;
128 xlinkType ret = XLINK_TYPE_NONE;
129
130 if (node == NULL) return(XLINK_TYPE_NONE);
131 if (doc == NULL) doc = node->doc;
132 if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
133 /*
134 * This is an HTML document.
135 */
136 } else if ((node->ns != NULL) &&
137 (!xmlStrcmp(node->ns->href, XHTML_NAMESPACE))) {
138 /*
139 * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@
140 */
141 /*
142 * This is an XHTML element within an XML document
143 * Check whether it's one of the element able to carry links
144 * and in that case if it holds the attributes.
145 */
146 }
147
148 /*
149 * We don't prevent a-priori having XML Linking constructs on
150 * XHTML elements
151 */
152 type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE);
153 if (type != NULL) {
154 if (xmlStrcmp(type, BAD_CAST "simple")) {
155 ret = XLINK_TYPE_SIMPLE;
156 } if (xmlStrcmp(type, BAD_CAST "extended")) {
157 role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
158 if (role != NULL) {
159 xmlNsPtr xlink;
160 xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE);
161 if (xlink == NULL) {
162 /* Humm, fallback method */
163 if (!xmlStrcmp(role, BAD_CAST"xlink:external-linkset"))
164 ret = XLINK_TYPE_EXTENDED_SET;
165 } else {
166 xmlChar buf[200];
167#ifdef HAVE_SNPRINTF
168 snprintf((char *) buf, 199, "%s:external-linkset",
169 (char *) xlink->prefix);
170#else
171 sprintf((char *) buf, "%s:external-linkset",
172 (char *) xlink->prefix);
173#endif
174 if (!xmlStrcmp(role, buf))
175 ret = XLINK_TYPE_EXTENDED_SET;
176
177 }
178
179 }
180 ret = XLINK_TYPE_EXTENDED;
181 }
182 }
183
184 if (type != NULL) xmlFree(type);
185 if (role != NULL) xmlFree(role);
186 return(ret);
187}