Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 407 lines (320 sloc) 11.138 kb
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
1 //
2 // KSHTMLWriter.m
3 //
efecaa1 @mikeabdullah Settle on BSD license.
mikeabdullah authored
4 // Copyright (c) 2010, Mike Abdullah and Karelia Software
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL MIKE ABDULLAH OR KARELIA SOFTWARE BE LIABLE FOR ANY
19 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
25 //
26
efecaa1 @mikeabdullah Settle on BSD license.
mikeabdullah authored
27
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
28 #import "KSHTMLWriter.h"
29
3aeccf6 @mikeabdullah KSXMLWriter uses a KSElementInfo object internally.
mikeabdullah authored
30 #import "KSElementInfo.h"
31
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
32
33 @implementation KSHTMLWriter
34
72adfa1 @mikeabdullah Documenting .isXHTML generation better.
mikeabdullah authored
35 #pragma mark Creating an HTML Writer
36
5f5a663 @mikeabdullah Consistently use "writer" or "output" terminology.
mikeabdullah authored
37 - (id)initWithOutputWriter:(id <KSWriter>)output;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
38 {
5f5a663 @mikeabdullah Consistently use "writer" or "output" terminology.
mikeabdullah authored
39 [super initWithOutputWriter:output];
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
40
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
41 _isXHTML = YES;
fba7c04 HTML Writer tracks all element IDs written, so can tell you if an ID is ...
Mike authored
42 _IDs = [[NSMutableSet alloc] init];
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
43 _classNames = [[NSMutableArray alloc] init];
44
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
45 return self;
46 }
47
5f5a663 @mikeabdullah Consistently use "writer" or "output" terminology.
mikeabdullah authored
48 - (id)initWithOutputWriter:(id <KSWriter>)output isXHTML:(BOOL)isXHTML;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
49 {
5f5a663 @mikeabdullah Consistently use "writer" or "output" terminology.
mikeabdullah authored
50 if (self = [self initWithOutputWriter:output])
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
51 {
52 _isXHTML = isXHTML;
53 }
54
55 return self;
56 }
57
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
58 - (void)dealloc
59 {
fba7c04 HTML Writer tracks all element IDs written, so can tell you if an ID is ...
Mike authored
60 [_IDs release];
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
61 [_classNames release];
62
63 [super dealloc];
64 }
65
72adfa1 @mikeabdullah Documenting .isXHTML generation better.
mikeabdullah authored
66 #pragma mark XHTML
67
68 @synthesize XHTML = _isXHTML;
69
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
70 #pragma mark Document
71
69f22da @mikeabdullah -startDocument… allows specification of string encoding too.
mikeabdullah authored
72 - (void)startDocument:(NSString *)DTD encoding:(NSStringEncoding)encoding isXHTML:(BOOL)isXHTML;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
73 {
74 _isXHTML = isXHTML;
69f22da @mikeabdullah -startDocument… allows specification of string encoding too.
mikeabdullah authored
75 [self startDocument:DTD encoding:encoding];
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
76 }
77
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
78 #pragma mark CSS Class Name
79
99c57a9 Likewise -pushElementClassName: becomes -pushClassName:
Mike authored
80 - (void)pushClassName:(NSString *)className;
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
81 {
82 [_classNames addObject:className];
83 }
84
6bc0b29 @mikeabdullah Switch to 'push' terminology for element attributes.
mikeabdullah authored
85 - (NSString *)elementClassName;
ecfabe0 @mikeabdullah Expose -className.
mikeabdullah authored
86 {
87 NSString *result = nil;
88 if ([_classNames count])
89 {
90 result = [_classNames componentsJoinedByString:@" "];
91 }
92 return result;
93 }
94
30bbf6a Allow values for attributes to be type id, not
Dan Wood authored
95 - (void)pushAttribute:(NSString *)attribute value:(id)value;
e96c6c8 @mikeabdullah Calling [htmlWriter pushElementAttribute:@"class" value:@"foo"] automati...
mikeabdullah authored
96 {
97 if ([attribute isEqualToString:@"class"])
98 {
fba7c04 HTML Writer tracks all element IDs written, so can tell you if an ID is ...
Mike authored
99 return [self pushClassName:value];
e96c6c8 @mikeabdullah Calling [htmlWriter pushElementAttribute:@"class" value:@"foo"] automati...
mikeabdullah authored
100 }
fba7c04 HTML Writer tracks all element IDs written, so can tell you if an ID is ...
Mike authored
101
102 // Keep track of IDs in use
103 if ([attribute isEqualToString:@"id"]) [_IDs addObject:value];
104 [super pushAttribute:attribute value:value];
e96c6c8 @mikeabdullah Calling [htmlWriter pushElementAttribute:@"class" value:@"foo"] automati...
mikeabdullah authored
105 }
106
3aeccf6 @mikeabdullah KSXMLWriter uses a KSElementInfo object internally.
mikeabdullah authored
107 - (KSElementInfo *)currentElementInfo;
589179c @mikeabdullah Include -className in -elementAttributes.
mikeabdullah authored
108 {
3aeccf6 @mikeabdullah KSXMLWriter uses a KSElementInfo object internally.
mikeabdullah authored
109 KSElementInfo *result = [super currentElementInfo];
589179c @mikeabdullah Include -className in -elementAttributes.
mikeabdullah authored
110
3aeccf6 @mikeabdullah KSXMLWriter uses a KSElementInfo object internally.
mikeabdullah authored
111 // Add in buffered class info
6bc0b29 @mikeabdullah Switch to 'push' terminology for element attributes.
mikeabdullah authored
112 NSString *class = [self elementClassName];
3aeccf6 @mikeabdullah KSXMLWriter uses a KSElementInfo object internally.
mikeabdullah authored
113 if (class) [result addAttribute:@"class" value:class];
589179c @mikeabdullah Include -className in -elementAttributes.
mikeabdullah authored
114
115 return result;
116 }
117
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
118 #pragma mark HTML Fragments
119
120 - (void)writeHTMLString:(NSString *)html;
121 {
122 [self writeString:html];
123 }
124
125 - (void)writeHTMLFormat:(NSString *)format , ...
126 {
127 va_list argList;
128 va_start(argList, format);
129 NSString *aString = [[[NSString alloc] initWithFormat:format arguments:argList] autorelease];
130 va_end(argList);
131
132 [self writeHTMLString:aString];
133 }
134
135 #pragma mark General
136
137 - (void)startElement:(NSString *)tagName className:(NSString *)className;
138 {
139 [self startElement:tagName idName:nil className:className];
140 }
141
142 - (void)startElement:(NSString *)tagName idName:(NSString *)idName className:(NSString *)className;
143 {
b12f4c9 Sorry to keep changing this, but -pushElementAttribute: really is too wo...
Mike authored
144 if (idName) [self pushAttribute:@"id" value:idName];
145 if (className) [self pushAttribute:@"class" value:className];
9beb73b @mikeabdullah Take a bunch of primitive element APIs private. Just need to use -addAtt...
mikeabdullah authored
146
147 [self startElement:tagName];
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
148 }
149
fba7c04 HTML Writer tracks all element IDs written, so can tell you if an ID is ...
Mike authored
150 - (BOOL)isIDValid:(NSString *)anID; // NO if the ID has already been used
151 {
152 BOOL result = ![_IDs containsObject:anID];
153 return result;
154 }
155
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
156 #pragma mark Line Break
157
158 - (void)writeLineBreak;
159 {
160 [self startElement:@"br"];
161 [self endElement];
162 }
163
164 #pragma mark Higher-level Tag Writing
165
166 - (void)startAnchorElementWithHref:(NSString *)href title:(NSString *)titleString target:(NSString *)targetString rel:(NSString *)relString;
167 {
b12f4c9 Sorry to keep changing this, but -pushElementAttribute: really is too wo...
Mike authored
168 if (href) [self pushAttribute:@"href" value:href];
169 if (targetString) [self pushAttribute:@"target" value:targetString];
170 if (titleString) [self pushAttribute:@"title" value:titleString];
171 if (relString) [self pushAttribute:@"rel" value:relString];
9beb73b @mikeabdullah Take a bunch of primitive element APIs private. Just need to use -addAtt...
mikeabdullah authored
172
173 [self startElement:@"a"];
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
174 }
175
ac684bc @mikeabdullah Don't need to pass id and class directly when writing an image.
mikeabdullah authored
176 - (void)writeImageWithSrc:(NSString *)src
177 alt:(NSString *)alt
30bbf6a Allow values for attributes to be type id, not
Dan Wood authored
178 width:(id)width
179 height:(id)height;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
180 {
b12f4c9 Sorry to keep changing this, but -pushElementAttribute: really is too wo...
Mike authored
181 [self pushAttribute:@"src" value:src];
182 [self pushAttribute:@"alt" value:alt];
183 if (width) [self pushAttribute:@"width" value:width];
184 if (height) [self pushAttribute:@"height" value:height];
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
185
9beb73b @mikeabdullah Take a bunch of primitive element APIs private. Just need to use -addAtt...
mikeabdullah authored
186 [self startElement:@"img"];
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
187 [self endElement];
188 }
189
190 // TODO: disable indentation & newlines when we are in an anchor tag, somehow.
191
192 #pragma mark Link
193
194 - (void)writeLinkWithHref:(NSString *)href
195 type:(NSString *)type
196 rel:(NSString *)rel
197 title:(NSString *)title
198 media:(NSString *)media;
199 {
b12f4c9 Sorry to keep changing this, but -pushElementAttribute: really is too wo...
Mike authored
200 if (rel) [self pushAttribute:@"rel" value:rel];
15c3119 @mikeabdullah Merge (I think).
mikeabdullah authored
201 if (!type) type = @"text/css"; [self pushAttribute:@"type" value:type];
b12f4c9 Sorry to keep changing this, but -pushElementAttribute: really is too wo...
Mike authored
202 [self pushAttribute:@"href" value:href];
203 if (title) [self pushAttribute:@"title" value:title];
204 if (media) [self pushAttribute:@"media" value:media];
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
205
3e48d47 Explicitly write out links (link and style tags) with a charset, so that...
Dan Wood authored
206 [self pushAttribute:@"UTF-8" value:@"charset"];
207
9beb73b @mikeabdullah Take a bunch of primitive element APIs private. Just need to use -addAtt...
mikeabdullah authored
208 [self startElement:@"link"];
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
209 [self endElement];
210 }
211
212 - (void)writeLinkToStylesheet:(NSString *)href
213 title:(NSString *)title
214 media:(NSString *)media;
215 {
42af387 @mikeabdullah Writing a <LINK> with nil type will automatically fill in default type. ...
mikeabdullah authored
216 [self writeLinkWithHref:href type:nil rel:@"stylesheet" title:title media:media];
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
217 }
218
60c7e89 @mikeabdullah Simpler method for pulling in an external script.
mikeabdullah authored
219 #pragma mark Scripts
220
37c85e9 @mikeabdullah -writeJavascriptWithSrc: actually makes more sense.
mikeabdullah authored
221 - (void)writeJavascriptWithSrc:(NSString *)src;
60c7e89 @mikeabdullah Simpler method for pulling in an external script.
mikeabdullah authored
222 {
27cf398 @mikeabdullah Assertion.
mikeabdullah authored
223 NSParameterAssert(src);
224
1ca811e @mikeabdullah Split out -startJavascriptElementWithSrc:
mikeabdullah authored
225 [self startJavascriptElementWithSrc:src];
60c7e89 @mikeabdullah Simpler method for pulling in an external script.
mikeabdullah authored
226 [self endElement];
227 }
de567f7 added method to output JavaScript (via Dan)
Terrence Talbot authored
228
4d9ca24 @mikeabdullah -writeJavascript:useCDATA: convenience method.
mikeabdullah authored
229 - (void)writeJavascript:(NSString *)script useCDATA:(BOOL)useCDATA;
230 {
1ca811e @mikeabdullah Split out -startJavascriptElementWithSrc:
mikeabdullah authored
231 [self startJavascriptElementWithSrc:nil];
4d9ca24 @mikeabdullah -writeJavascript:useCDATA: convenience method.
mikeabdullah authored
232
233 if (useCDATA) [self startJavascriptCDATA];
234 [self writeString:script];
235 if (useCDATA) [self endJavascriptCDATA];
236
237 [self endElement];
238 }
239
1ca811e @mikeabdullah Split out -startJavascriptElementWithSrc:
mikeabdullah authored
240 - (void)startJavascriptElementWithSrc:(NSString *)src; // src may be nil
241 {
b12f4c9 Sorry to keep changing this, but -pushElementAttribute: really is too wo...
Mike authored
242 [self pushAttribute:@"type" value:@"text/javascript"]; // in theory, HTML5 pages could omit this
243 if (src) [self pushAttribute:@"src" value:src];
3e48d47 Explicitly write out links (link and style tags) with a charset, so that...
Dan Wood authored
244 [self pushAttribute:@"charset" value:@"UTF-8"];
245
9beb73b @mikeabdullah Take a bunch of primitive element APIs private. Just need to use -addAtt...
mikeabdullah authored
246 [self startElement:@"script"];
8a9783e @mikeabdullah Embedded scripts should start on a newline.
mikeabdullah authored
247
248 // Embedded scripts should start on their own line for clarity
2d68556 @mikeabdullah Embedded scripts should also write their end tag on a new line.
mikeabdullah authored
249 if (!src)
250 {
251 [self writeString:@"\n"];
252 [self stopWritingInline];
253 }
1ca811e @mikeabdullah Split out -startJavascriptElementWithSrc:
mikeabdullah authored
254 }
255
f241869 @mikeabdullah Split out -startJavascriptCDATA and -endJavascriptCDATA.
mikeabdullah authored
256 - (void)startJavascriptCDATA;
257 {
258 [self writeString:@"\n/* "];
259 [self startCDATA];
260 [self writeString:@" */"];
261 }
262
263 - (void)endJavascriptCDATA;
264 {
265 [self writeString:@"\n/* "];
266 [self endCDATA];
267 [self writeString:@" */\n"];
268 }
269
0bc7e19 Add new convenience method for writing <param name="foo" value="bar" />
Dan Wood authored
270 #pragma mark Param
271
272 - (void)writeParamElementWithName:(NSString *)name value:(NSString *)value;
273 {
b12f4c9 Sorry to keep changing this, but -pushElementAttribute: really is too wo...
Mike authored
274 if (name) [self pushAttribute:@"name" value:name];
275 if (value) [self pushAttribute:@"value" value:value];
0bc7e19 Add new convenience method for writing <param name="foo" value="bar" />
Dan Wood authored
276 [self startElement:@"param"];
277 [self endElement];
278 }
279
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
280 #pragma mark Style
281
6dd07ee @mikeabdullah Convenience method for writing inline CSS.
mikeabdullah authored
282 - (void)writeStyleElementWithCSSString:(NSString *)css;
283 {
284 [self startStyleElementWithType:@"text/css"];
285 [self writeString:css]; // browsers don't expect styles to be XML escaped
286 [self endElement];
287 }
288
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
289 - (void)startStyleElementWithType:(NSString *)type;
290 {
b12f4c9 Sorry to keep changing this, but -pushElementAttribute: really is too wo...
Mike authored
291 if (type) [self pushAttribute:@"type" value:type];
9beb73b @mikeabdullah Take a bunch of primitive element APIs private. Just need to use -addAtt...
mikeabdullah authored
292 [self startElement:@"style"];
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
293 }
294
295 #pragma mark Elements Stack
296
297 - (BOOL)topElementIsList;
298 {
299 NSString *tagName = [self topElement];
f23f8c7 @mikeabdullah XML Writing should be case-sensitive.
mikeabdullah authored
300 BOOL result = ([tagName isEqualToString:@"ul"] ||
301 [tagName isEqualToString:@"ol"]);
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
302 return result;
303 }
304
c35c721 @mikeabdullah Only a handful of HTML elements are allowed to be empty.
mikeabdullah authored
305 #pragma mark (X)HTML
306
307 - (BOOL)elementCanBeEmpty:(NSString *)tagName;
308 {
f23f8c7 @mikeabdullah XML Writing should be case-sensitive.
mikeabdullah authored
309 if ([tagName isEqualToString:@"br"] ||
310 [tagName isEqualToString:@"img"] ||
311 [tagName isEqualToString:@"hr"] ||
312 [tagName isEqualToString:@"meta"] ||
313 [tagName isEqualToString:@"link"] ||
314 [tagName isEqualToString:@"input"] ||
315 [tagName isEqualToString:@"base"] ||
316 [tagName isEqualToString:@"basefont"] ||
317 [tagName isEqualToString:@"param"] ||
318 [tagName isEqualToString:@"area"] ||
319 [tagName isEqualToString:@"source"]) return YES;
c35c721 @mikeabdullah Only a handful of HTML elements are allowed to be empty.
mikeabdullah authored
320
321 return NO;
322 }
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
323
324 - (BOOL)canWriteElementInline:(NSString *)tagName;
325 {
326 switch ([tagName length])
327 {
328 case 1:
f23f8c7 @mikeabdullah XML Writing should be case-sensitive.
mikeabdullah authored
329 if ([tagName isEqualToString:@"a"] ||
330 [tagName isEqualToString:@"b"] ||
331 [tagName isEqualToString:@"i"]) return YES;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
332 break;
333
334 case 2:
f23f8c7 @mikeabdullah XML Writing should be case-sensitive.
mikeabdullah authored
335 if ([tagName isEqualToString:@"br"] ||
336 [tagName isEqualToString:@"em"]) return YES;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
337 break;
338
339 case 3:
f23f8c7 @mikeabdullah XML Writing should be case-sensitive.
mikeabdullah authored
340 if ([tagName isEqualToString:@"img"] ||
341 [tagName isEqualToString:@"sup"] ||
342 [tagName isEqualToString:@"sub"] ||
343 [tagName isEqualToString:@"big"]) return YES;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
344 break;
345
346 case 4:
f23f8c7 @mikeabdullah XML Writing should be case-sensitive.
mikeabdullah authored
347 if ([tagName isEqualToString:@"span"] ||
348 [tagName isEqualToString:@"font"]) return YES;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
349 break;
350
351 case 5:
f23f8c7 @mikeabdullah XML Writing should be case-sensitive.
mikeabdullah authored
352 if ([tagName isEqualToString:@"small"]) return YES;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
353 break;
354
355 case 6:
f23f8c7 @mikeabdullah XML Writing should be case-sensitive.
mikeabdullah authored
356 if ([tagName isEqualToString:@"strong"]) return YES;
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
357 break;
358 }
359
360 return [super canWriteElementInline:tagName];
361 }
362
363 #pragma mark Element Primitives
364
c8bc317 @mikeabdullah Can now ditch -openTag:writeInline:
mikeabdullah authored
365 - (void)startElement:(NSString *)elementName writeInline:(BOOL)writeInline; // for more control
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
366 {
566d24c @mikeabdullah non-lowercase tags shouldn't be used for HTML.
mikeabdullah authored
367 NSAssert1([elementName isEqualToString:[elementName lowercaseString]], @"Attempt to start non-lowercase element: %@", elementName);
368
369
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
370 // Add in any pre-written classes
6bc0b29 @mikeabdullah Switch to 'push' terminology for element attributes.
mikeabdullah authored
371 NSString *class = [self elementClassName];
ecfabe0 @mikeabdullah Expose -className.
mikeabdullah authored
372 if (class)
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
373 {
374 [_classNames removeAllObjects];
b12f4c9 Sorry to keep changing this, but -pushElementAttribute: really is too wo...
Mike authored
375 [super pushAttribute:@"class" value:class];
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
376 }
9beb73b @mikeabdullah Take a bunch of primitive element APIs private. Just need to use -addAtt...
mikeabdullah authored
377
c8bc317 @mikeabdullah Can now ditch -openTag:writeInline:
mikeabdullah authored
378 [super startElement:elementName writeInline:writeInline];
75c4ca6 @mikeabdullah Experimental support for building up CSS class names before writing an e...
mikeabdullah authored
379 }
380
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
381 - (void)closeEmptyElementTag; // /> OR > depending on -isXHTML
382 {
383 if ([self isXHTML])
384 {
385 [super closeEmptyElementTag];
386 }
387 else
388 {
389 [self writeString:@">"];
390 }
391 }
392
928af59 @mikeabdullah XML Writers now sport an encoding property. Anything passed into -writeS...
mikeabdullah authored
393 #pragma mark String Encoding
394
395 // NBSP is special -- for HTML, we usually want to encode it, for XML, no.
396 - (NSCharacterSet *)legalCharacterSet;
397 {
398 NSMutableCharacterSet *result = [[[super legalCharacterSet] mutableCopy] autorelease];
399
400 // Take out special characters which we ALWAYS want to escape
401 [result removeCharactersInRange:NSMakeRange(160,1)]; // nbsp ... since they are hard to spot!
402
403 return result;
404 }
405
994c91e @mikeabdullah And the real star of our show arrives: KSHTMLWriter!
mikeabdullah authored
406 @end
Something went wrong with that request. Please try again.