X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fvcard_edit.c;h=067362a5f6559d428544981cf8c0f4521d9752b1;hb=f638dfd082af857e57f1d3d3fc1b923151fe0c33;hp=47c04c724a5863fa2610caa84e7ff94e14bb40eb;hpb=12419374c8266f3855a119e3676a38ec812fc158;p=citadel.git diff --git a/webcit/vcard_edit.c b/webcit/vcard_edit.c index 47c04c724..067362a5f 100644 --- a/webcit/vcard_edit.c +++ b/webcit/vcard_edit.c @@ -15,6 +15,7 @@ #include "calendar.h" CtxType CTX_VCARD = CTX_NONE; +CtxType CTX_VCARD_TYPE = CTX_NONE; long VCEnumCounter = 0; typedef enum _VCStrEnum { @@ -22,6 +23,7 @@ typedef enum _VCStrEnum { StringCluster, PhoneNumber, EmailAddr, + Address, Street, Number, AliasFor, @@ -34,48 +36,48 @@ struct vcField { VCStrEnum Type; vcField *Sub; long cval; - const char *Str; + ConstStr Name; }; vcField VCStr_Ns [] = { - {{HKEY("last")}, FlatString, NULL, 0, "Last Name"}, - {{HKEY("first")}, FlatString, NULL, 0, "First Name"}, - {{HKEY("middle")}, FlatString, NULL, 0, "Middle Name"}, - {{HKEY("prefix")}, FlatString, NULL, 0, "Prefix"}, - {{HKEY("suffix")}, FlatString, NULL, 0, "Suffix"}, - {{HKEY("")}, TerminateList, NULL, 0, ""} + {{HKEY("last")}, FlatString, NULL, 0, {HKEY("Last Name")}}, + {{HKEY("first")}, FlatString, NULL, 0, {HKEY("First Name")}}, + {{HKEY("middle")}, FlatString, NULL, 0, {HKEY("Middle Name")}}, + {{HKEY("prefix")}, FlatString, NULL, 0, {HKEY("Prefix")}}, + {{HKEY("suffix")}, FlatString, NULL, 0, {HKEY("Suffix")}}, + {{HKEY("")}, TerminateList, NULL, 0, {HKEY("")}} }; vcField VCStr_Addrs [] = { - {{HKEY("POBox")}, FlatString, NULL, 0, "PO box"}, - {{HKEY("address")}, FlatString, NULL, 0, "Address"}, - {{HKEY("address2")}, FlatString, NULL, 0, ""}, - {{HKEY("city")}, FlatString, NULL, 0, "City"}, - {{HKEY("state")}, FlatString, NULL, 0, "State"}, - {{HKEY("zip")}, FlatString, NULL, 0, "ZIP code"}, - {{HKEY("country")}, FlatString, NULL, 0, "Country"}, - {{HKEY("")}, TerminateList, NULL, 0, ""} + {{HKEY("POBox")}, Address, NULL, 0, {HKEY("PO box")}}, + {{HKEY("address")}, Address, NULL, 0, {HKEY("Address")}}, + {{HKEY("address2")}, Address, NULL, 0, {HKEY("")}}, + {{HKEY("city")}, Address, NULL, 0, {HKEY("City")}}, + {{HKEY("state")}, Address, NULL, 0, {HKEY("State")}}, + {{HKEY("zip")}, Address, NULL, 0, {HKEY("ZIP code")}}, + {{HKEY("country")}, Address, NULL, 0, {HKEY("Country")}}, + {{HKEY("")}, TerminateList, NULL, 0, {HKEY("")}} }; vcField VCStrE [] = { - {{HKEY("version")}, Number, NULL, 0, ""}, - {{HKEY("rev")}, Number, NULL, 0, ""}, - {{HKEY("label")}, FlatString, NULL, 0, ""}, - {{HKEY("uid")}, FlatString, NULL, 0, ""}, - {{HKEY("n")}, StringCluster, VCStr_Ns, 0, ""}, /* N is name, but only if there's no FN already there */ - {{HKEY("fn")}, FlatString, NULL, 0, ""}, /* FN (full name) is a true 'display name' field */ - {{HKEY("title")}, FlatString, NULL, 0, "Title:"}, - {{HKEY("org")}, FlatString, NULL, 0, "Organization:"},/* organization */ - {{HKEY("email")}, EmailAddr, NULL, 0, "E-mail:"}, - {{HKEY("tel")}, PhoneNumber, NULL, 0, "Telephone:"}, - {{HKEY("adr")}, StringCluster, VCStr_Addrs, 0, "Address:"}, - {{HKEY("photo")}, Base64BinaryAttachment, NULL, 0, "Photo:"}, - {{HKEY("tel;home")}, PhoneNumber, NULL, 0, " (home)"}, - {{HKEY("tel;work")}, PhoneNumber, NULL, 0, " (work)"}, - {{HKEY("tel;fax")}, PhoneNumber, NULL, 0, " (fax)"}, - {{HKEY("tel;cell")}, PhoneNumber, NULL, 0, " (cell)"}, - {{HKEY("email;internet")}, EmailAddr, NULL, 0, "E-mail:"}, - {{HKEY("")}, TerminateList, NULL, 0, ""} + {{HKEY("version")}, Number, NULL, 0, {HKEY("")}}, + {{HKEY("rev")}, Number, NULL, 0, {HKEY("")}}, + {{HKEY("label")}, FlatString, NULL, 0, {HKEY("")}}, + {{HKEY("uid")}, FlatString, NULL, 0, {HKEY("")}}, + {{HKEY("n")}, StringCluster, VCStr_Ns, 0, {HKEY("")}}, /* N is name, but only if there's no FN already there */ + {{HKEY("fn")}, FlatString, NULL, 0, {HKEY("")}}, /* FN (full name) is a true 'display name' field */ + {{HKEY("title")}, FlatString, NULL, 0, {HKEY("Title:")}}, + {{HKEY("org")}, FlatString, NULL, 0, {HKEY("Organization:")}},/* organization */ + {{HKEY("email")}, EmailAddr, NULL, 0, {HKEY("E-mail:")}}, + {{HKEY("tel")}, PhoneNumber, NULL, 0, {HKEY("Telephone:")}}, + {{HKEY("adr")}, StringCluster, VCStr_Addrs, 0, {HKEY("Address:")}}, + {{HKEY("photo")}, Base64BinaryAttachment, NULL, 0, {HKEY("Photo:")}}, + {{HKEY("tel;home")}, PhoneNumber, NULL, 0, {HKEY(" (home)")}}, + {{HKEY("tel;work")}, PhoneNumber, NULL, 0, {HKEY(" (work)")}}, + {{HKEY("tel;fax")}, PhoneNumber, NULL, 0, {HKEY(" (fax)")}}, + {{HKEY("tel;cell")}, PhoneNumber, NULL, 0, {HKEY(" (cell)")}}, + {{HKEY("email;internet")}, EmailAddr, NULL, 0, {HKEY("E-mail:")}}, + {{HKEY("")}, TerminateList, NULL, 0, {HKEY("")}} }; ConstStr VCStr [] = { @@ -107,6 +109,7 @@ void RegisterVCardToken(vcField* vf, StrBuf *name, int inTokenCount) { RegisterTokenParamDefine(SKEY(name), vf->cval); Put(DefineToToken, LKEY(vf->cval), vf, reference_free_handler); + Put(vcNames, LKEY(vf->cval), NewStrBufPlain(CKEY(vf->Name)), HFreeStrBuf); syslog(LOG_DEBUG, "Token: %s -> %ld, %d", ChrPtr(name), @@ -118,8 +121,9 @@ void RegisterVCardToken(vcField* vf, StrBuf *name, int inTokenCount) void autoRegisterTokens(long *enumCounter, vcField* vf, StrBuf *BaseStr, int layer) { int i = 0; + StrBuf *subStr = NewStrBuf(); while (vf[i].STR.len > 0) { - StrBuf *subStr = NewStrBuf(); + FlushStrBuf(subStr); vf[i].cval = (*enumCounter) ++; StrBufAppendBuf(subStr, BaseStr, 0); if (StrLength(subStr) > 0) { @@ -153,10 +157,13 @@ void autoRegisterTokens(long *enumCounter, vcField* vf, StrBuf *BaseStr, int lay break; case TerminateList: break; + case Address: + break; } RegisterVCardToken(&vf[i], subStr, i); i++; } + FreeStrBuf(&subStr); } int preeval_vcard_item(WCTemplateToken *Token) @@ -188,6 +195,26 @@ void tmpl_vcard_item(StrBuf *Target, WCTemplputParams *TP) } } +void tmpl_vcard_context_item(StrBuf *Target, WCTemplputParams *TP) +{ + void *vItem; + vcField *t = (vcField*) CTX(CTX_VCARD_TYPE); + HashList *vc = (HashList*) CTX(CTX_VCARD); + + if (t == NULL) { + LogTemplateError(NULL, "VCard item", ERR_NAME, TP, + "Missing context"); + return; + } + + if (GetHash(vc, LKEY(t->cval), &vItem) && (vItem != NULL)) { + StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 0); + } + else { + LogTemplateError(NULL, "VCard item", ERR_NAME, TP, + "Doesn't have that key - did you miss to filter in advance?"); + } +} int preeval_vcard_name_str(WCTemplateToken *Token) { WCTemplputParams TPP; @@ -215,29 +242,86 @@ void tmpl_vcard_name_str(StrBuf *Target, WCTemplputParams *TP) if (GetHash(vcNames, LKEY(searchFieldNo), &vItem) && (vItem != NULL)) { StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1); } + else { + LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, + "No i18n string for this."); + return; + } +} + +void tmpl_vcard_context_name_str(StrBuf *Target, WCTemplputParams *TP) +{ + void *vItem; + vcField *t = (vcField*) CTX(CTX_VCARD_TYPE); + + if (t == NULL) { + LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, + "Missing context"); + return; + } + + if (GetHash(vcNames, LKEY(t->cval), &vItem) && (vItem != NULL)) { + StrBufAppendTemplate(Target, TP, (StrBuf*) vItem, 1); + } + else { + LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, + "No i18n string for this."); + return; + } } int filter_VC_ByType(const char* key, long len, void *Context, StrBuf *Target, WCTemplputParams *TP) { long searchType; long type = 0; - void *vvcField; + void *v; int rc = 0; + vcField *vf = (vcField*) Context; - memcpy(type, key, sizeof(long)); - searchType = GetTemplateTokenNumber(Target, TP, 3, 0);/// todo: which? + memcpy(&type, key, sizeof(long)); + searchType = GetTemplateTokenNumber(Target, TP, IT_ADDT_PARAM(0), 0); - if (GetHash(DefineToToken, LKEY(type), &vvcField) && - (vvcField != NULL)) - { - vcField *t = (vcField*) vvcField; - if (t && t->Type == searchType) { - rc = 1; - } + if (vf->Type == searchType) { + HashList *vc = (HashList*) CTX(CTX_VCARD); + if (GetHash(vc, LKEY(vf->cval), &v) && v != NULL) + return 1; } return rc; } + + + +HashList *getContextVcard(StrBuf *Target, WCTemplputParams *TP) +{ + vcField *vf = (vcField*) CTX(CTX_VCARD_TYPE); + HashList *vc = (HashList*) CTX(CTX_VCARD); + + if ((vf == NULL) || (vc == NULL)) { + LogTemplateError(NULL, "VCard item type", ERR_NAME, TP, + "Need VCard and Vcard type in context"); + + return NULL; + } + return vc; +} + +int filter_VC_ByContextType(const char* key, long len, void *Context, StrBuf *Target, WCTemplputParams *TP) +{ + long searchType; + vcField *vf = (vcField*) CTX(CTX_VCARD_TYPE); + + memcpy(&searchType, key, sizeof(long)); + + if (vf->cval == searchType) { + return 1; + } + else { + return 0; + } +} + + int conditional_VC_Havetype(StrBuf *Target, WCTemplputParams *TP) { HashList *vc = (HashList*) CTX(CTX_VCARD); @@ -489,265 +573,8 @@ void fetchname_parsed_vcard(struct vCard *v, char **storename) { -/* - * html print a vcard - * display_vcard() calls this after parsing the textual vCard into - * our 'struct vCard' data object. - * - * Set 'full' to nonzero to display the full card, otherwise it will only - * show a summary line. - * - * This code is a bit ugly, so perhaps an explanation is due: we do this - * in two passes through the vCard fields. On the first pass, we process - * fields we understand, and then render them in a pretty fashion at the - * end. Then we make a second pass, outputting all the fields we don't - * understand in a simple two-column name/value format. - * v the vCard to display - * full display all items of the vcard? - * msgnum Citadel message pointer - */ -void display_parsed_vcard(StrBuf *Target, struct vCard *v, int full, wc_mime_attachment *Mime) -{ - int i, j; - char buf[SIZ]; - char *name; - int is_qp = 0; - int is_b64 = 0; - char *thisname, *thisvalue; - char firsttoken[SIZ]; - int pass; - - char fullname[SIZ]; - char title[SIZ]; - char org[SIZ]; - char phone[SIZ]; - char mailto[SIZ]; - - strcpy(fullname, ""); - strcpy(phone, ""); - strcpy(mailto, ""); - strcpy(title, ""); - strcpy(org, ""); - - if (!full) { - StrBufAppendPrintf(Target, ""); - name = vcard_get_prop(v, "fn", 1, 0, 0); - if (name != NULL) { - StrEscAppend(Target, NULL, name, 0, 0); - } - else if (name = vcard_get_prop(v, "n", 1, 0, 0), name != NULL) { - strcpy(fullname, name); - vcard_n_prettyize(fullname); - StrEscAppend(Target, NULL, fullname, 0, 0); - } - else { - StrBufAppendPrintf(Target, " "); - } - StrBufAppendPrintf(Target, ""); - return; - } - - StrBufAppendPrintf(Target, "
" - ""); - for (pass=1; pass<=2; ++pass) { - - if (v->numprops) for (i=0; i<(v->numprops); ++i) { - int len; - thisname = strdup(v->prop[i].name); - extract_token(firsttoken, thisname, 0, ';', sizeof firsttoken); - - for (j=0; jprop[i].value); - /* if we have some untagged QP, detect it here. */ - if (!is_qp && (strstr(v->prop[i].value, "=?")!=NULL)) - utf8ify_rfc822_string(&v->prop[i].value); - - if (is_qp) { - /* %ff can become 6 bytes in utf8 */ - thisvalue = malloc(len * 2 + 3); - j = CtdlDecodeQuotedPrintable( - thisvalue, v->prop[i].value, - len); - thisvalue[j] = 0; - } - else if (is_b64) { - /* ff will become one byte.. */ - thisvalue = malloc(len + 50); - CtdlDecodeBase64( - thisvalue, v->prop[i].value, - strlen(v->prop[i].value) ); - } - else { - thisvalue = strdup(v->prop[i].value); - } - - /* Various fields we may encounter ***/ - - /* N is name, but only if there's no FN already there */ - if (!strcasecmp(firsttoken, "n")) { - if (IsEmptyStr(fullname)) { - strcpy(fullname, thisvalue); - vcard_n_prettyize(fullname); - } - } - - /* FN (full name) is a true 'display name' field */ - else if (!strcasecmp(firsttoken, "fn")) { - strcpy(fullname, thisvalue); - } - - /* title */ - else if (!strcasecmp(firsttoken, "title")) { - strcpy(title, thisvalue); - } - - /* organization */ - else if (!strcasecmp(firsttoken, "org")) { - strcpy(org, thisvalue); - } - - else if (!strcasecmp(firsttoken, "email")) { - size_t len; - if (!IsEmptyStr(mailto)) strcat(mailto, "
"); - strcat(mailto, - ""); - - strcat(mailto, "\">"); - len = strlen(mailto); - stresc(mailto+len, SIZ - len, thisvalue, 1, 1); - strcat(mailto, ""); - } - else if (!strcasecmp(firsttoken, "tel")) { - if (!IsEmptyStr(phone)) strcat(phone, "
"); - strcat(phone, thisvalue); - for (j=0; j
\n"); - } - } - /* else if (!strcasecmp(firsttoken, "photo") && full && pass == 2) { - // Only output on second pass - StrBufAppendPrintf(Target, "\n"); - } */ - else if (!strcasecmp(firsttoken, "version")) { - /* ignore */ - } - else if (!strcasecmp(firsttoken, "rev")) { - /* ignore */ - } - else if (!strcasecmp(firsttoken, "label")) { - /* ignore */ - } - else { - - /*** Don't show extra fields. They're ugly. - if (pass == 2) { - StrBufAppendPrintf(Target, "\n"); - } - ***/ - } - - free(thisname); - free(thisvalue); - } - - if (pass == 1) { - StrBufAppendPrintf(Target, "" - "\n"); - - if (!IsEmptyStr(phone)) { - StrBufAppendPrintf(Target, "\n", phone); - } - if (!IsEmptyStr(mailto)) { - StrBufAppendPrintf(Target, "\n", mailto); - } - } - - } - - StrBufAppendPrintf(Target, "
"); - StrBufAppendPrintf(Target, _("Address:")); - StrBufAppendPrintf(Target, ""); - for (j=0; j"); - else StrBufAppendPrintf(Target, " "); - } - } - StrBufAppendPrintf(Target, "
"); - StrBufAppendPrintf(Target, _("Photo:")); - StrBufAppendPrintf(Target, ""); - StrBufAppendPrintf(Target, "\"Contact",msgnum); - StrBufAppendPrintf(Target, "
"); - StrEscAppend(Target, NULL, thisname, 0, 0); - StrBufAppendPrintf(Target, ""); - StrEscAppend(Target, NULL, thisvalue, 0, 0); - StrBufAppendPrintf(Target, "
" - "" - ""); - StrEscAppend(Target, NULL, fullname, 0, 0); - StrBufAppendPrintf(Target, ""); - if (!IsEmptyStr(title)) { - StrBufAppendPrintf(Target, "
\""); - StrEscAppend(Target, NULL, title, 0, 0); - StrBufAppendPrintf(Target, "
"); - } - if (!IsEmptyStr(org)) { - StrBufAppendPrintf(Target, "
"); - StrEscAppend(Target, NULL, org, 0, 0); - StrBufAppendPrintf(Target, "
"); - } - StrBufAppendPrintf(Target, "
"); - StrBufAppendPrintf(Target, _("Telephone:")); - StrBufAppendPrintf(Target, "%s
"); - StrBufAppendPrintf(Target, _("E-mail:")); - StrBufAppendPrintf(Target, "%s
\n"); -} - -void PutVcardItem(vcField *thisField, HashList *thisVC, StrBuf *ThisFieldStr, int is_qp, StrBuf *Swap) +void PutVcardItem(HashList *thisVC, vcField *thisField, StrBuf *ThisFieldStr, int is_qp, StrBuf *Swap) { /* if we have some untagged QP, detect it here. */ if (is_qp || (strstr(ChrPtr(ThisFieldStr), "=?")!=NULL)){ @@ -788,12 +615,10 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, int full, wc_mim int ntokens, len; StrBuf *thisname = NULL; char firsttoken[20]; ///SIZ]; - void *V; - HashList *thisVC; + //void *V; StrBuf *thisVCToken; void *vField = NULL; - thisVC = NewHash(1, lFlathash); Swap = NewStrBuf (); thisname = NewStrBuf(); thisVCToken = NewStrBufPlain(NULL, 63); @@ -808,7 +633,7 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, int full, wc_mim /*len = */extract_token(firsttoken, ChrPtr(thisname), 0, ';', sizeof firsttoken); ntokens = num_tokens(ChrPtr(thisname), ';'); for (j=0, k=0; j < ntokens && k < 10; ++j) { - int evc[10]; + ///int evc[10]; len = extract_token(buf, ChrPtr(thisname), j, ';', sizeof buf); if (!strcasecmp(buf, "encoding=quoted-printable")) { @@ -856,11 +681,14 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, int full, wc_mim StrBufExtract_NextToken(Buf, thisArray, &Pos, ';'); ThisFieldStr = NewStrBufDup(Buf); - PutVcardItem(&thisField->Sub[j], thisVC, ThisFieldStr, is_qp, Swap); + PutVcardItem(VC, &thisField->Sub[j], ThisFieldStr, is_qp, Swap); j++; } + FreeStrBuf(&thisArray); + FreeStrBuf(&Buf); } break; + case Address: case FlatString: case PhoneNumber: case EmailAddr: @@ -869,7 +697,7 @@ void parse_vcard(StrBuf *Target, struct vCard *v, HashList *VC, int full, wc_mim case AliasFor: /* copy over the payload into a StrBuf */ ThisFieldStr = NewStrBufPlain(v->prop[i].value, -1); - PutVcardItem(thisField, thisVC, ThisFieldStr, is_qp, Swap); + PutVcardItem(VC, thisField, ThisFieldStr, is_qp, Swap); break; case Base64BinaryAttachment: @@ -943,21 +771,9 @@ TODO: check for layer II ////free(thisname); /// thisname = NULL; } - - - { - WCTemplputParams *TP = NULL; - WCTemplputParams SubTP; - FlushStrBuf(Target); - StackContext(TP, &SubTP, thisVC, CTX_VCARD, 0, NULL); - { - DoTemplate(HKEY("test_vcard"), Target, &SubTP); - } - UnStackContext(&SubTP); - } - printf("%s\n", ChrPtr(Target)); + FreeStrBuf(&thisname); + FreeStrBuf(&Swap); FreeStrBuf(&thisVCToken); - DeleteHash(&thisVC);/// todo } void tmplput_VCARD_ITEM(StrBuf *Target, WCTemplputParams *TP) @@ -979,21 +795,24 @@ void tmplput_VCARD_ITEM(StrBuf *Target, WCTemplputParams *TP) } -void new_vcard (StrBuf *Target, struct vCard *v, int full, wc_mime_attachment *Mime) +void display_one_vcard (StrBuf *Target, struct vCard *v, int full, wc_mime_attachment *Mime) { - HashList *VC; - WCTemplputParams SubTP; + HashList *VC; WCTemplputParams SubTP; memset(&SubTP, 0, sizeof(WCTemplputParams)); - VC = NewHash(0, Flathash); + VC = NewHash(0, lFlathash); parse_vcard(Target, v, VC, full, Mime); - SubTP.Filter.ContextType = CTX_VCARD; - SubTP.Context = VC; + { + WCTemplputParams *TP = NULL; + WCTemplputParams SubTP; + StackContext(TP, &SubTP, VC, CTX_VCARD, 0, NULL); - DoTemplate(HKEY("test_vcard"), Target, &SubTP); + DoTemplate(HKEY("vcard_msg_display"), Target, &SubTP); + UnStackContext(&SubTP); + } DeleteHash(&VC); } @@ -1047,12 +866,7 @@ void display_vcard(StrBuf *Target, ((!isalpha(alpha)) && (!isalpha(this_alpha))) ) { -#define XXX_XXX 1 -#ifdef XXX_XXX - new_vcard (Target, v, full, Mime); -#else - display_parsed_vcard(Target, v, full, Mime); -#endif + display_one_vcard (Target, v, full, Mime); } vcard_free(v); @@ -1816,6 +1630,9 @@ void ServerShutdownModule_VCARD (void) { + DeleteHash(&DefineToToken); + DeleteHash(&vcNames); + DeleteHash(&VCTokenToDefine); /// DeleteHash(&VCToEnum); } @@ -1824,6 +1641,7 @@ InitModule_VCARD (void) { RegisterCTX(CTX_VCARD); + RegisterCTX(CTX_VCARD_TYPE); RegisterReadLoopHandlerset( VIEW_ADDRESSBOOK, vcard_GetParamsGetServerCall, @@ -1874,13 +1692,16 @@ InitModule_VCARD { StrBuf *Prefix = NewStrBufPlain(HKEY("VC:")); DefineToToken = NewHash(1, lFlathash); + vcNames = NewHash(1, lFlathash); VCTokenToDefine = NewHash(1, NULL); autoRegisterTokens(&VCEnumCounter, VCStrE, Prefix, 0); FreeStrBuf(&Prefix); } RegisterCTX(CTX_VCARD); RegisterNamespace("VC:ITEM", 2, 2, tmpl_vcard_item, preeval_vcard_item, CTX_VCARD); + RegisterNamespace("VC:CTXITEM", 1, 1, tmpl_vcard_context_item, NULL, CTX_VCARD_TYPE); RegisterNamespace("VC:NAME", 1, 1, tmpl_vcard_name_str, preeval_vcard_name_str, CTX_VCARD); + RegisterNamespace("VC:CTXNAME", 1, 1, tmpl_vcard_context_name_str, NULL, CTX_VCARD_TYPE); REGISTERTokenParamDefine(FlatString); REGISTERTokenParamDefine(StringCluster); REGISTERTokenParamDefine(PhoneNumber); @@ -1890,8 +1711,10 @@ InitModule_VCARD REGISTERTokenParamDefine(AliasFor); REGISTERTokenParamDefine(Base64BinaryAttachment); REGISTERTokenParamDefine(TerminateList); + REGISTERTokenParamDefine(Address); RegisterConditional("VC:HAVE:TYPE", 1, conditional_VC_Havetype, CTX_VCARD); - RegisterFilteredIterator("VC:TYPE", 1, NULL, NULL, NULL, NULL, filter_VC_ByType, CTX_STRBUF, CTX_VCARD, IT_NOFLAG); + RegisterFilteredIterator("VC:TYPE", 1, DefineToToken, NULL, NULL, NULL, filter_VC_ByType, CTX_VCARD_TYPE, CTX_VCARD, IT_NOFLAG); + RegisterFilteredIterator("VC:TYPE:ITEMS", 0, NULL, getContextVcard, NULL, NULL, filter_VC_ByContextType, CTX_STRBUF, CTX_VCARD_TYPE, IT_NOFLAG); }