+2005-03-28 Stephane Corthesy <stephane@sente.ch>
+
+ * v4.5.23
+
+ * JSAlertPanel: added new bindings, escapeJS and framework;
+ fixed html 'onclick' attribute
+
+ * JSConfirmPanel: added new bindings, escapeJS and framework; replaced
+ deprecated 'language' html attribute by 'type'
+
+ * JSImageFlyover.m: replaced deprecated 'language' html attribute by
+ 'type'
+
+ * JSModalWindow: added 'framework' binding
+
+ * JSValidatedField: added new binding, escapeJS; replaced deprecated
+ 'language' html attribute by 'type'
+
+ * JSImageFlyover.api, WOCollapsibleComponentContent.api: added
+ defaults to framework binding
+
+2005-03-28 Helge Hess <helge.hess@opengroupware.org>
+
+ * JSValidatedField.m, JSModalWindow.m, JSAlertPanel.m,
+ JSConfirmPanel.m, JSImageFlyover.m, WOCheckBoxMatrix.m,
+ WORadioButtonMatrix.m, WOTabPanel.m: minor code cleanups, added some
+ support for non-xml style elements
+
2005-01-04 Marcus Mueller <znek@mulle-kybernetik.com>
* common.h, JSConfirmPanel.m, JSAlertPanel.m, JSImageFlyover.m,
<binding name="targetWindow"/>
<binding name="string"/>
+ <!-- SOPE -->
+ <binding name="escapeJS" defaults="YES/NO" />
+ <binding name="framework" defaults="Frameworks"/>
+
<validation message="either one of 'action', 'pageName', or 'javaScriptFunction' may be bound">
<count test="!=1">
<bound name="action"/>
WOAssociation *targetWindow;
WOAssociation *string;
+ /* non WO */
WOElement *template;
+ WOAssociation *escapeJS;
+ WOAssociation *framework;
}
@end
self->filename = WOExtGetProperty(_config,@"filename");
self->targetWindow = WOExtGetProperty(_config,@"targetWindow");
self->string = WOExtGetProperty(_config,@"string");
+ self->escapeJS = WOExtGetProperty(_config,@"escapeJS");
+ self->framework = WOExtGetProperty(_config,@"framework");
funcCount = 0;
if (self->action) funcCount++;
RELEASE(self->targetWindow);
RELEASE(self->string);
RELEASE(self->template);
+ RELEASE(self->escapeJS);
+ RELEASE(self->framework);
[super dealloc];
}
comp = [_ctx component];
// link
- [_response appendContentString:@"<a onClick=\"javascript:alert('"];
+ [_response appendContentString:@"<a onclick=\"javascript:alert('"];
tmp = (self->alertMessage)
? [self->alertMessage stringValueInComponent: comp]
: @"Press OK.";
+ if (self->escapeJS != nil && [self->escapeJS boolValueInComponent: comp]) {
+ tmp = [tmp stringByApplyingJavaScriptEscaping];
+ }
[_response appendContentHTMLString:tmp];
[_response appendContentString:@"');\""];
[_response appendContentString:@" href=\""];
[_response appendContentString:@" >"];
// link content
- if (self->filename) {
+ if (self->filename != nil) {
WOResourceManager *rm;
+ NSString *frameworkName;
+ frameworkName = (self->framework != nil)
+ ? [self->framework stringValueInComponent:comp]
+ : [comp frameworkName];
+
rm = [[_ctx application] resourceManager];
languages = [_ctx resourceLookupLanguages];
tmp = [rm urlForResourceNamed:[self->filename stringValueInComponent:comp]
- inFramework:[comp frameworkName]
+ inFramework:frameworkName
languages:languages
request:[_ctx request]];
[_response appendContentString:tmp];
[_response appendContentString:@"\""];
- if (self->altTag) {
+ if (self->altTag != nil) {
[_response appendContentString:@" alt=\""];
[_response appendContentString:
[self->altTag stringValueInComponent:comp]];
[_response appendContentString:@"\" "];
}
- [_response appendContentString:@" />"];
+
+ [_response appendContentString:
+ (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
}
+
[self->template appendToResponse:_response inContext:_ctx];
- if (self->string)
+
+ if (self->string != nil)
[_response appendContentString:[self->string stringValueInComponent:comp]];
/* close link */
<!-- SOPE -->
<binding name="showPanel" defaults="YES/NO" />
+ <binding name="escapeJS" defaults="YES/NO" />
+ <binding name="framework" defaults="Frameworks"/>
<validation message="either one of 'action', 'pageName', or 'javaScriptFunction' may be bound">
<count test="!=1">
/* non WO */
WOAssociation *showPanel;
WOElement *template;
+ WOAssociation *escapeJS;
+ WOAssociation *framework;
}
@end
self->targetWindow = WOExtGetProperty(_config,@"targetWindow");
self->string = WOExtGetProperty(_config,@"string");
self->showPanel = WOExtGetProperty(_config,@"showPanel");
+ self->escapeJS = WOExtGetProperty(_config,@"escapeJS");
+ self->framework = WOExtGetProperty(_config,@"framework");
funcCount = 0;
if (self->action) funcCount++;
[self->string release];
[self->template release];
[self->showPanel release];
+ [self->escapeJS release];
+ [self->framework release];
[super dealloc];
}
return nil;
}
- if (self->pageName) {
- name = [self->pageName stringValueInComponent: [_ctx component]];
+ if (self->pageName != nil) {
+ name = [self->pageName stringValueInComponent: [_ctx component]];
result = [[_ctx application] pageWithName:name inContext:_ctx];
}
- else if (self->action) {
+ else if (self->action != nil) {
result = [self->action valueInComponent:[_ctx component]];
}
else {
return;
[_response appendContentString:
- @"<script language=\"javascript\">\nvar res = confirm(\""];
+ @"<script type=\"text/javascript\">\nvar res = confirm(\""];
[_response appendContentHTMLString:_msg];
[_response appendContentString:@"\");\n if (res) {\n"];
[_response appendContentString:@" >"];
/* link content */
- if (self->filename) { /* image */
- WOResourceManager *rm;
+ if (self->filename != nil) { /* image */
+ WOResourceManager *rm;
+ NSString *frameworkName;
- rm = [[_ctx application] resourceManager];
- languages = [_ctx resourceLookupLanguages];
+ frameworkName = (self->framework != nil)
+ ? [self->framework stringValueInComponent:comp]
+ : [comp frameworkName];
- tmp = [rm urlForResourceNamed:[self->filename stringValueInComponent:comp]
- inFramework:[comp frameworkName]
- languages:languages
- request:[_ctx request]];
+ rm = [[_ctx application] resourceManager];
+ languages = [_ctx resourceLookupLanguages];
+
+ tmp = [rm urlForResourceNamed:[self->filename stringValueInComponent:comp]
+ inFramework:frameworkName
+ languages:languages
+ request:[_ctx request]];
- [_response appendContentString:@"<img border=\"0\" src=\""];
- [_response appendContentString:tmp];
- [_response appendContentString:@"\" "];
+ [_response appendContentString:@"<img border=\"0\" src=\""];
+ [_response appendContentString:tmp];
+ [_response appendContentString:@"\" "];
- if (self->altTag) {
- [_response appendContentString:@"alt=\""];
- [_response appendContentString:
+ if (self->altTag != nil) {
+ [_response appendContentString:@"alt=\""];
+ [_response appendContentString:
[self->altTag stringValueInComponent:comp]];
- [_response appendContentString:@"\" "];
- }
- [_response appendContentString:@" />"];
+ [_response appendContentString:@"\" "];
+ }
+
+ [_response appendContentString:
+ (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
}
[self->template appendToResponse:_response inContext:_ctx];
- if (self->string) {
+ if (self->string != nil) {
[_response appendContentString:
[self->string stringValueInComponent:comp]];
}
}
- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
- NSString *msg;
+ NSString *msg;
+ WOComponent *comp;
+ comp = [_ctx component];
msg = (self->confirmMessage)
- ? [self->confirmMessage stringValueInComponent:[_ctx component]]
+ ? [self->confirmMessage stringValueInComponent:comp]
: @"Really?";
-
+ if (self->escapeJS != nil && [self->escapeJS boolValueInComponent:comp]) {
+ msg = [msg stringByApplyingJavaScriptEscaping];
+ }
+
if (self->showPanel)
[self _appendPanelToResponse:_response message:msg inContext:_ctx];
else
<binding name="selectedImage" required="YES"/>
<binding name="unselectedImage" required="YES" />
- <binding name="framework"/>
+ <binding name="framework" defaults="Frameworks"/>
<binding name="targetWindow"/>
<!-- SOPE -->
associations:(NSDictionary *)_config
template:(WOElement *)_subs
{
- if ((self = [super initWithName:_name associations:_config template:_subs]))
- {
+ if ((self = [super initWithName:_name associations:_config template:_subs])){
int funcCount;
WOAssociation *sidInUrlAssoc;
-
self->action = WOExtGetProperty(_config, @"action");
self->javaScriptFunction = WOExtGetProperty(_config, @"javaScriptFunction");
: YES;
- self->template = RETAIN(_subs);
+ self->template = [_subs retain];
}
return self;
}
- (void)dealloc {
- RELEASE(self->action);
- RELEASE(self->javaScriptFunction);
- RELEASE(self->pageName);
- RELEASE(self->selectedImage);
- RELEASE(self->unselectedImage);
- RELEASE(self->framework);
- RELEASE(self->targetWindow);
- RELEASE(self->template);
-
- RELEASE(self->directActionName);
- RELEASE(self->actionClass);
- RELEASE(self->queryDictionary);
- RELEASE(self->queryParameters);
+ [self->action release];
+ [self->javaScriptFunction release];
+ [self->pageName release];
+ [self->selectedImage release];
+ [self->unselectedImage release];
+ [self->framework release];
+ [self->targetWindow release];
+ [self->template release];
+
+ [self->directActionName release];
+ [self->actionClass release];
+ [self->queryDictionary release];
+ [self->queryParameters release];
[super dealloc];
}
-- (void)takeValuesFromRequest:(WORequest *)_request
- inContext:(WOContext *)_ctx
-{
- [self->template takeValuesFromRequest:_request inContext:_ctx];
+/* handle requests */
+
+- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
+ [self->template takeValuesFromRequest:_rq inContext:_ctx];
}
-- (id)invokeActionForRequest:(WORequest *)_request
- inContext:(WOContext *)_ctx
-{
+- (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
id result;
NSString *name;
result = [self->action valueInComponent:[_ctx component]];
}
else {
- result = [self->template invokeActionForRequest:_request inContext:_ctx];
+ result = [self->template invokeActionForRequest:_rq inContext:_ctx];
}
return result;
}
+/* generate response */
- (NSString *)imageByFilename:(NSString *)_name
inContext:(WOContext *)_ctx
[self->template appendToResponse:_response inContext:_ctx];
/* script */
- [_response appendContentString:@"<script language=\"JavaScript\">\n<!--\n"];
+ [_response appendContentString:@"<script type=\"text/javascript\">\n<!--\n"];
if (![_ctx valueForKey:@"JSImageFlyoverScriptDone"]) {
tmp = @"var JSImageFlyoverImages = new Array();\n"
}
[_response appendContentString:@" >"];
- /* image itself */
+ /* the image itself */
+
[_response appendContentString:@"<img border='0' src=\""];
[_response appendContentString:tunselected];
[_response appendContentString:@"\" name=\""];
[_response appendContentString:elID];
[_response appendContentString:@"\" "];
[self appendExtraAttributesToResponse:_response inContext:_ctx];
- [_response appendContentString:@" />"];
+
+ [_response appendContentString:
+ (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
/* close link */
[_response appendContentString:@"</a>"];
*/
/*
- to be done ...
+ TO BE DONE ...
Usage:
<binding name="isCenter" />
<binding name="filename" />
<binding name="string" />
+ <binding name="framework" defaults="Frameworks"/>
<validation message="exactly one of 'action', 'pagename', or 'href' may be bound">
<count test="!=1">
WOAssociation *isCenter;
WOAssociation *filename;
WOAssociation *string;
+ WOAssociation *framework;
WOElement *template;
}
self->isCenter = WOExtGetProperty(_config, @"isCenter");
self->filename = WOExtGetProperty(_config, @"filename");
self->string = WOExtGetProperty(_config, @"string");
+ self->framework = WOExtGetProperty(_config, @"framework");
funcCount = 0;
if (self->action) funcCount++;
#undef SetAssociationValue
- self->template = RETAIN(_subs);
+ self->template = [_subs retain];
}
return self;
}
- (void)dealloc {
- RELEASE(self->action);
- RELEASE(self->pageName);
- RELEASE(self->href);
+ [self->action release];
+ [self->pageName release];
+ [self->href release];
- RELEASE(self->height);
- RELEASE(self->width);
- RELEASE(self->windowName);
- RELEASE(self->isResizable);
- RELEASE(self->showLocation);
- RELEASE(self->showMenuBar);
- RELEASE(self->showScrollbars);
- RELEASE(self->showStatus);
- RELEASE(self->showToolbar);
-
- RELEASE(self->top);
- RELEASE(self->left);
- RELEASE(self->isCenter);
- RELEASE(self->filename);
- RELEASE(self->string);
+ [self->height release];
+ [self->width release];
+ [self->windowName release];
+ [self->isResizable release];
+ [self->showLocation release];
+ [self->showMenuBar release];
+ [self->showScrollbars release];
+ [self->showStatus release];
+ [self->showToolbar release];
+
+ [self->top release];
+ [self->left release];
+ [self->isCenter release];
+ [self->filename release];
+ [self->string release];
+ [self->framework release];
- RELEASE(self->template);
+ [self->template release];
[super dealloc];
}
[self->template takeValuesFromRequest:_rq inContext:_ctx];
}
-- (id)invokeActionForRequest:(WORequest *)_request
- inContext:(WOContext *)_ctx
-{
- if (self->pageName) {
+- (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
+ if (self->pageName != nil) {
NSString *name;
name = [self->pageName stringValueInComponent: [_ctx component]];
return [[_ctx application] pageWithName:name inContext:_ctx];
}
- if (self->action)
+ if (self->action != nil)
return [self->action valueInComponent:[_ctx component]];
- return [self->template invokeActionForRequest:_request inContext:_ctx];
+ return [self->template invokeActionForRequest:_rq inContext:_ctx];
}
/* generating response */
-- (void)appendToResponse:(WOResponse *)_resp
- inContext:(WOContext *)_ctx
-{
+- (void)appendToResponse:(WOResponse *)_resp inContext:(WOContext *)_ctx {
WOComponent *comp;
NSString *tmp;
NSArray *languages;
// link
[_resp appendContentString:
@"<a onclick=\"window.showModalDialog('"];
- if (self->href)
+ if (self->href != nil)
[_resp appendContentString:[self->href stringValueInComponent:comp]];
else
- [_resp appendContentString:@"http://www.ccc.de"];
+ [_resp appendContentString:@"http://sope.opengroupware.org/"];
[_resp appendContentString:@"', 'a short text', '"];
/* configure modal panel */
- if (self->height) {
+ if (self->height != nil) {
[_resp appendContentString:@" dialogHeight: "];
[_resp appendContentString:[self->height stringValueInComponent:comp]];
[_resp appendContentString:@"px;"];
}
- if (self->width) {
+ if (self->width != nil) {
[_resp appendContentString:@" dialogWidth: "];
[_resp appendContentString:[self->width stringValueInComponent:comp]];
[_resp appendContentString:@"px;"];
}
- if (self->top) {
+ if (self->top != nil) {
[_resp appendContentString:@" dialogTop: "];
[_resp appendContentString:[self->top stringValueInComponent:comp]];
[_resp appendContentString:@"px;"];
}
- if (self->left) {
+ if (self->left != nil) {
[_resp appendContentString:@" dialogLeft: "];
[_resp appendContentString:[self->left stringValueInComponent:comp]];
[_resp appendContentString:@"px;"];
}
- if (self->isResizable) {
+ if (self->isResizable != nil) {
[_resp appendContentString:@" resizable: "];
- [_resp appendContentString:[self->isResizable stringValueInComponent:comp]];
+ [_resp appendContentString:
+ [self->isResizable stringValueInComponent:comp]];
[_resp appendContentCharacter:';'];
}
- if (self->showStatus) {
+ if (self->showStatus != nil) {
[_resp appendContentString:@" status: "];
[_resp appendContentString:[self->showStatus stringValueInComponent:comp]];
[_resp appendContentCharacter:';'];
}
- if (self->isCenter) {
+ if (self->isCenter != nil) {
[_resp appendContentString:@" center: "];
[_resp appendContentString:[self->isCenter stringValueInComponent:comp]];
[_resp appendContentCharacter:';'];
[self appendExtraAttributesToResponse:_resp inContext:_ctx];
[_resp appendContentString:@" >"];
- // link content
- if (self->filename) {
+ /* link content */
+ if (self->filename != nil) {
WOResourceManager *rm;
-
+ NSString *frameworkName;
+
rm = [[_ctx application] resourceManager];
languages = [_ctx resourceLookupLanguages];
-
+ frameworkName = (self->framework != nil)
+ ? [self->framework stringValueInComponent:comp]
+ : [comp frameworkName];
+
tmp = [rm urlForResourceNamed:[self->filename stringValueInComponent:comp]
- inFramework:[comp frameworkName]
+ inFramework:frameworkName
languages:languages
request:[_ctx request]];
[_resp appendContentString:tmp];
[_resp appendContentString:@"\" "];
- [_resp appendContentString:@" />"];
+ [_resp appendContentString:
+ (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
}
+
[self->template appendToResponse:_resp inContext:_ctx];
- if (self->string)
+
+ if (self->string != nil)
[_resp appendContentString:[self->string stringValueInComponent:comp]];
-
+
/* close link */
[_resp appendContentString:@"</a>"];
}
<binding name="fieldSize" />
<binding name="inputIsRequired" />
<binding name="requiredText" />
+
+ <!-- SOPE -->
+ <binding name="escapeJS" defaults="YES/NO" />
</wo>
\ No newline at end of file
WOAssociation *inputIsRequired;
WOAssociation *requiredText;
+ /* non WO */
WOElement *template;
+ WOAssociation *escapeJS;
}
@end
+#include <NGObjWeb/NSString+JavaScriptEscaping.h>
+#include <NGExtensions/NSString+Ext.h>
#include "common.h"
@implementation JSValidatedField
- (id)initWithName:(NSString *)_name
associations:(NSDictionary *)_config
- template:(WOElement *)_subs
+ template:(WOElement *)_t
{
- if ((self = [super initWithName:_name associations:_config template:_subs]))
- {
+ if ((self = [super initWithName:_name associations:_config template:_t])) {
self->inputText = WOExtGetProperty(_config,@"inputText");
self->errorMessage = WOExtGetProperty(_config,@"errorMessage");
self->formName = WOExtGetProperty(_config,@"formName");
self->fieldSize = WOExtGetProperty(_config,@"fieldSize");
self->inputIsRequired = WOExtGetProperty(_config,@"inputIsRequired");
self->requiredText = WOExtGetProperty(_config,@"requiredText");
+ self->escapeJS = WOExtGetProperty(_config,@"escapeJS");
if (!self->inputText)
NSLog(@"WARNING: JSValidatedField: 'inputText' not bound.");
if (!self->formName)
NSLog(@"ERROR: JSValidatedField: 'formName' not bound.");
- self->template = RETAIN(_subs);
+ self->template = [_t retain];
}
return self;
}
- (void)dealloc {
- RELEASE(self->inputText);
- RELEASE(self->errorMessage);
- RELEASE(self->fieldSize);
- RELEASE(self->inputIsRequired);
- RELEASE(self->requiredText);
- RELEASE(self->template);
+ [self->inputText release];
+ [self->errorMessage release];
+ [self->fieldSize release];
+ [self->inputIsRequired release];
+ [self->requiredText release];
+ [self->template release];
+ [self->escapeJS release];
[super dealloc];
}
/* operations */
- (NSString *)buildJSSaveID:(NSString *)_id {
- NSArray *ta;
-
- ta = [[NSArray alloc] initWithArray: [_id componentsSeparatedByString:@"."]];
- _id = [ta componentsJoinedByString:@"x"];
- [ta release];
- return _id;
+ return [_id stringByReplacingString:@"." withString:@"x"];
}
/* processing requests */
terrMesg = (self->errorMessage)
? [self->errorMessage stringValueInComponent:comp]
: @"Invalid values.";
+ if (self->escapeJS != nil && [self->escapeJS boolValueInComponent:comp])
+ terrMesg = [terrMesg stringByApplyingJavaScriptEscaping];
tformName = [self->formName stringValueInComponent:comp];
tinput = ([self->inputIsRequired boolValueInComponent:comp])
? @"true"
: @"false";
- ttext = (self->requiredText)
- ? [NSString stringWithFormat:@"\"%@\"",
- [self->requiredText stringValueInComponent:comp]]
- : @"false";
-
+ if (self->requiredText) {
+ ttext = [self->requiredText stringValueInComponent:comp];
+ if (self->escapeJS != nil && [self->escapeJS boolValueInComponent:comp])
+ ttext = [ttext stringByApplyingJavaScriptEscaping];
+ ttext = [NSString stringWithFormat:@"\"%@\"", ttext];
+ }
+ else
+ ttext = @"false";
/* script */
- [_response appendContentString:@"<script language=\"JavaScript\">\n<!--\n"];
+ [_response appendContentString:@"<script type=\"text/javascript\">\n<!--\n"];
if (!((objectsCount =
[[_ctx valueForKey:@"JSValidatedFieldCounter"] intValue]))) {
[self->fieldSize stringValueInComponent:comp]];
[_response appendContentString:@"\""];
}
- [_response appendContentString:@" />"];
+
+ [_response appendContentString:
+ (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
}
@end /* JSValidatedField */
-# $Id$
+# Version file
-SUBMINOR_VERSION:=22
+SUBMINOR_VERSION:=23
+# v4.5.23 requires libNGObjWeb v4.5.145
# v4.5.22 requires libNGObjWeb v4.5.106
[_response appendContentString:s];
[s release];
[_response appendContentCharacter:'"'];
-
+
+ // TODO: need a ctx flag for empty attributes
if ([selArray containsObject:obj])
[_response appendContentString:@" checked=\"checked\""];
- [_response appendContentString:@" />"];
-
+ [_response appendContentString:
+ (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
+
/* append template */
[self->template appendToResponse:_response inContext:_ctx];
[_ctx deleteLastElementIDComponent];
}
else
- [_response appendContentString:@" "];
+ [_response appendContentString:@" "]; // TODO: XML/XHTML?
[_response appendContentString:@"</td>"];
}
[_response appendContentString:@"</tr>"];
<binding name="visibility" required="YES" defaults="YES/NO"/>
<binding name="openedImageFileName" />
<binding name="closedImageFileName" />
- <binding name="framework" />
+ <binding name="framework" defaults="Frameworks"/>
<binding name="openedLabel" />
<binding name="closedLabel" />
<binding name="submitActionName" />
if ([sel isEqual:obj])
[_response appendContentString:@" checked=\"checked\""];
- [_response appendContentString:@" />"];
-
+ [_response appendContentString:
+ (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
+
// append template
[self->template appendToResponse:_response inContext:_ctx];
[_ctx deleteLastElementIDComponent];
[_response appendContentHTMLAttributeValue:[_ctx elementID]];
[_response appendContentString:@"\" value=\""];
[_response appendContentString:title];
- [_response appendContentString:@"\" />"];
+ [_response appendContentString:
+ (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
}
else {
/* gen link */
[_response appendContentHTMLAttributeValue:title];
[_response appendContentString:@"\">"];
- if (self->textColor) {
+ if (self->textColor != nil) {
[_response appendContentString:@"<font color=\""];
[_response appendContentHTMLAttributeValue:
[self->textColor stringValueInComponent:sComponent]];
[_response appendContentHTMLString:title];
- if (self->textColor)
+ if (self->textColor != nil)
[_response appendContentString:@"</font>"];
[_response appendContentString:@"</a>"];
}