1 /* |
|
2 * Copyright (c) 2000 - 2003 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "nw_frame_frameelementhandleri.h" |
|
20 |
|
21 #include "nw_xhtml_xhtmlcontenthandler.h" |
|
22 #include "nw_hed_hedeventhandler.h" |
|
23 #include "nw_hed_documentroot.h" |
|
24 #include "nw_lmgr_activecontainerbox.h" |
|
25 #include "nw_lmgr_textbox.h" |
|
26 #include "nw_lmgr_breakbox.h" |
|
27 #include "nw_evt_activateevent.h" |
|
28 #include "nw_evt_focusevent.h" |
|
29 #include "nw_xhtml_xhtml_1_0_tokens.h" |
|
30 #include "nwx_url_utils.h" |
|
31 #include "nwx_settings.h" |
|
32 #include "nwx_http_defs.h" |
|
33 |
|
34 /* ------------------------------------------------------------------------- * |
|
35 private method |
|
36 * ------------------------------------------------------------------------- */ |
|
37 |
|
38 /* |
|
39 Get the URL in base tag defined in header, this value can be used to combine with |
|
40 relative URL to figure out the absolute URL. |
|
41 */ |
|
42 static TBrowserStatusCode |
|
43 NW_XHTML_frameElementHandler_getBaseTagUrl (NW_XHTML_ContentHandler_t* contentHandler, |
|
44 NW_Text_t** srcVal); |
|
45 |
|
46 /* ------------------------------------------------------------------------- */ |
|
47 static |
|
48 NW_LMgr_Box_t* |
|
49 NW_XHTML_frameElementHandler_ImodeCreateBox(const NW_XHTML_ElementHandler_t* elementHandler, |
|
50 NW_XHTML_ContentHandler_t* contentHandler, |
|
51 NW_DOM_ElementNode_t* elementNode) |
|
52 { |
|
53 NW_Text_t* srcVal = NULL; |
|
54 NW_LMgr_ActiveContainerBox_t* box = NULL; |
|
55 NW_Ucs2* storage = NULL; |
|
56 NW_Uint8 freeNeeded; |
|
57 NW_Text_Length_t charCount; |
|
58 NW_HED_EventHandler_t* eventHandler = NULL; |
|
59 |
|
60 NW_REQUIRED_PARAM(elementHandler); |
|
61 |
|
62 // find the 'src' attribute and get its string value |
|
63 if (NW_DOM_ElementNode_getTagToken(elementNode) == NW_XHTML_ElementToken_frame) |
|
64 { |
|
65 NW_XHTML_GetDOMAttribute (contentHandler, |
|
66 elementNode, |
|
67 NW_XHTML_AttributeToken_src, &srcVal); |
|
68 |
|
69 // if there is no 'src' value, see if an 'href' value is specified |
|
70 if (!srcVal) |
|
71 { |
|
72 NW_XHTML_GetDOMAttribute (contentHandler, |
|
73 elementNode, |
|
74 NW_XHTML_AttributeToken_href, &srcVal); |
|
75 } |
|
76 |
|
77 if (!srcVal) |
|
78 { |
|
79 NW_XHTML_frameElementHandler_getBaseTagUrl (contentHandler, &srcVal); |
|
80 } |
|
81 } |
|
82 |
|
83 if (srcVal) |
|
84 { |
|
85 NW_Ucs4 character; |
|
86 NW_Url_Schema_t scheme = NW_SCHEMA_INVALID; |
|
87 TBrowserStatusCode schemeStatus = KBrsrSuccess; |
|
88 |
|
89 storage = (NW_Ucs2*) |
|
90 NW_Text_GetUCS2Buffer (srcVal, NW_Text_Flags_Aligned, &charCount, |
|
91 &freeNeeded); |
|
92 |
|
93 if (!storage ) |
|
94 { |
|
95 NW_Object_Delete(srcVal); |
|
96 return NULL; |
|
97 } |
|
98 |
|
99 // we do not want to handle frame links within a page (i.e. src values that start with '#') |
|
100 character = NW_Text_GetAt( srcVal, 0 ); |
|
101 |
|
102 if( character == '#' ) |
|
103 { |
|
104 NW_Object_Delete(srcVal); |
|
105 if (freeNeeded){ |
|
106 NW_Str_Delete(storage); |
|
107 } |
|
108 return NULL; |
|
109 } |
|
110 |
|
111 /* At this point, only interested if there is a scheme present. Philosophy is |
|
112 to present EVERYTHING to the user - except bad TEL/MAILTO links. If there is a problem |
|
113 with a URL, it should be caught later when the anchor is selected/used. */ |
|
114 schemeStatus = NW_Url_GetScheme(storage, &scheme); |
|
115 |
|
116 /* We don't want to display bad links, but other schemes are okay. */ |
|
117 if (schemeStatus == KBrsrMalformedUrl) |
|
118 { |
|
119 box = NULL; |
|
120 } |
|
121 else |
|
122 { |
|
123 eventHandler = |
|
124 NW_HED_EventHandler_New (NW_HED_DocumentNodeOf (contentHandler), elementNode); |
|
125 box = NW_LMgr_ActiveContainerBox_New( |
|
126 0, NW_LMgr_EventHandlerOf (eventHandler), NW_LMgr_ActionType_OpenLink); |
|
127 } |
|
128 |
|
129 /* If elementNode has no children, then insert a box for the link text from the url. */ |
|
130 if (box && (NW_DOM_Node_getFirstChild(elementNode) == NULL)) |
|
131 { |
|
132 TBrowserStatusCode status; |
|
133 NW_Text_t* linkText = NULL; |
|
134 NW_Text_t* text = NULL; |
|
135 NW_LMgr_TextBox_t* linkTextBox; |
|
136 NW_LMgr_Box_t* breakBox = NULL; |
|
137 |
|
138 NW_Uint16 lineTextArray[4] = |
|
139 { NW_XHTML_AttributeToken_id, |
|
140 NW_XHTML_AttributeToken_name, |
|
141 NW_XHTML_AttributeToken_src, |
|
142 NW_XHTML_AttributeToken_title |
|
143 }; |
|
144 |
|
145 /* For frames, link text needs to be taken from either "id", |
|
146 "name" or "src" attributes, in this order of priority */ |
|
147 NW_Uint8 i; |
|
148 |
|
149 for (i = 0; i < 4; i++) |
|
150 { |
|
151 NW_XHTML_GetDOMAttribute (contentHandler, |
|
152 elementNode, |
|
153 lineTextArray[i], |
|
154 &text); |
|
155 // ignore empty text too |
|
156 if( text && text->characterCount > 0 ) |
|
157 { |
|
158 break; |
|
159 } |
|
160 } |
|
161 |
|
162 if (!text) |
|
163 { |
|
164 NW_Object_Delete(srcVal); |
|
165 if (freeNeeded){ |
|
166 NW_Str_Delete(storage); |
|
167 } |
|
168 return NULL; |
|
169 } |
|
170 |
|
171 linkText = NW_Text_Copy(text, NW_TRUE); /* deep copy */ |
|
172 NW_Object_Delete(text); |
|
173 text = NULL; |
|
174 linkTextBox = NW_LMgr_TextBox_New (0, linkText); |
|
175 status = NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBoxOf(box), NW_LMgr_BoxOf(linkTextBox)); |
|
176 if (status != KBrsrSuccess) |
|
177 { |
|
178 NW_Object_Delete(linkTextBox); |
|
179 } |
|
180 |
|
181 breakBox = (NW_LMgr_Box_t*)NW_LMgr_BreakBox_New ((NW_ADT_Vector_Metric_t)1); |
|
182 status = NW_LMgr_ContainerBox_AddChild (NW_LMgr_ContainerBoxOf(box), NW_LMgr_BoxOf(breakBox)); |
|
183 |
|
184 if (status != KBrsrSuccess) |
|
185 { |
|
186 NW_Object_Delete(breakBox); |
|
187 } |
|
188 } |
|
189 |
|
190 NW_Object_Delete(srcVal); |
|
191 if (freeNeeded){ |
|
192 NW_Str_Delete(storage); |
|
193 } |
|
194 } |
|
195 if (!box){ |
|
196 return NULL; |
|
197 } |
|
198 return NW_LMgr_BoxOf(box); |
|
199 } |
|
200 |
|
201 /* ------------------------------------------------------------------------- * |
|
202 class definition |
|
203 * ------------------------------------------------------------------------- */ |
|
204 |
|
205 /* ------------------------------------------------------------------------- */ |
|
206 const |
|
207 NW_XHTML_frameElementHandler_Class_t NW_XHTML_frameElementHandler_Class = { |
|
208 { /* NW_Object_Core */ |
|
209 /* super */ &NW_XHTML_ElementHandler_Class, |
|
210 /* queryInterface */ _NW_Object_Core_QueryInterface |
|
211 }, |
|
212 { /* NW_XHTML_ElementHandler */ |
|
213 /* initialize */ _NW_XHTML_ElementHandler_Initialize, |
|
214 /* createBoxTree */ _NW_XHTML_frameElementHandler_CreateBoxTree, |
|
215 /* processEvent */ _NW_XHTML_frameElementHandler_ProcessEvent |
|
216 }, |
|
217 { /* NW_XHTML_frameElementHandler */ |
|
218 /* unused */ NW_Object_Unused |
|
219 } |
|
220 }; |
|
221 |
|
222 /* ------------------------------------------------------------------------- * |
|
223 singleton definition |
|
224 * ------------------------------------------------------------------------- */ |
|
225 |
|
226 const NW_XHTML_frameElementHandler_t NW_XHTML_frameElementHandler = { |
|
227 { { &NW_XHTML_frameElementHandler_Class } } |
|
228 }; |
|
229 |
|
230 /* ------------------------------------------------------------------------- * |
|
231 virtual methods |
|
232 * ------------------------------------------------------------------------- */ |
|
233 TBrowserStatusCode |
|
234 _NW_XHTML_frameElementHandler_CreateBoxTree (const NW_XHTML_ElementHandler_t* elementHandler, |
|
235 NW_XHTML_ContentHandler_t* contentHandler, |
|
236 NW_DOM_ElementNode_t* elementNode, |
|
237 NW_LMgr_ContainerBox_t* parentBox) |
|
238 { |
|
239 NW_LMgr_Box_t* box = NULL; |
|
240 |
|
241 NW_TRY (status) |
|
242 { |
|
243 box = NW_XHTML_frameElementHandler_ImodeCreateBox(elementHandler, contentHandler, elementNode); |
|
244 |
|
245 if (!box) |
|
246 { |
|
247 // There was no src attribute, so just return |
|
248 NW_THROW_SUCCESS(status); |
|
249 } |
|
250 |
|
251 // Add the box to the tree |
|
252 status = NW_LMgr_ContainerBox_AddChild (parentBox, box); |
|
253 _NW_THROW_ON_ERROR (status); |
|
254 |
|
255 // Apply common attributes and styles |
|
256 status = NW_XHTML_ElementHandler_ApplyStyles (elementHandler, contentHandler, elementNode, &box, NULL); |
|
257 NW_THROW_ON (status, KBrsrOutOfMemory); |
|
258 |
|
259 // Apply Styles will take care of replacing container box if display was block, list-item or marquee. |
|
260 // In case of 'display:none' or an error it removes the container box. That's why we check box |
|
261 if (!box) |
|
262 { |
|
263 NW_THROW_SUCCESS(status); |
|
264 } |
|
265 |
|
266 parentBox = NW_LMgr_ContainerBoxOf (box); |
|
267 |
|
268 // Invoke our superclass for completion |
|
269 status = _NW_XHTML_ElementHandler_CreateBoxTree(elementHandler, contentHandler, elementNode, parentBox); |
|
270 } |
|
271 NW_CATCH (status) |
|
272 { |
|
273 if(box) |
|
274 { |
|
275 NW_Object_Delete(box); |
|
276 } |
|
277 } |
|
278 NW_FINALLY |
|
279 { |
|
280 return status; |
|
281 } NW_END_TRY |
|
282 } |
|
283 |
|
284 /* ------------------------------------------------------------------------- */ |
|
285 NW_Uint8 |
|
286 _NW_XHTML_frameElementHandler_ProcessEvent (const NW_XHTML_ElementHandler_t* elementHandler, |
|
287 NW_XHTML_ContentHandler_t* contentHandler, |
|
288 NW_DOM_ElementNode_t* elementNode, |
|
289 NW_LMgr_Box_t* box, |
|
290 NW_Evt_Event_t* event) |
|
291 { |
|
292 NW_Text_t* url = NULL; |
|
293 TBrowserStatusCode status; |
|
294 |
|
295 NW_REQUIRED_PARAM(elementHandler); |
|
296 NW_REQUIRED_PARAM(box); |
|
297 |
|
298 // we are really only interested in the following events |
|
299 if ((NW_Object_Core_GetClass (event) != &NW_Evt_ActivateEvent_Class) && |
|
300 (NW_Object_Core_GetClass (event) != &NW_Evt_FocusEvent_Class)) |
|
301 { |
|
302 return NW_LMgr_EventNotAbsorbed; |
|
303 } |
|
304 |
|
305 if(NW_Object_Core_GetClass (event) == &NW_Evt_FocusEvent_Class) |
|
306 { |
|
307 return NW_LMgr_EventAbsorbed; |
|
308 } |
|
309 |
|
310 // find the 'src' attribute and get its string value |
|
311 NW_XHTML_GetDOMAttribute (contentHandler, |
|
312 elementNode, |
|
313 NW_XHTML_AttributeToken_src, &url); |
|
314 |
|
315 // if there is no 'src' value, see if an 'href' value is specified |
|
316 if (!url) |
|
317 { |
|
318 NW_XHTML_GetDOMAttribute (contentHandler, |
|
319 elementNode, |
|
320 NW_XHTML_AttributeToken_href, &url); |
|
321 } |
|
322 |
|
323 if (!url) |
|
324 { |
|
325 NW_XHTML_frameElementHandler_getBaseTagUrl (contentHandler, &url); |
|
326 } |
|
327 |
|
328 |
|
329 if (!url) |
|
330 { |
|
331 return NW_LMgr_EventAbsorbed; |
|
332 } |
|
333 |
|
334 // load the content |
|
335 status = NW_XHTML_ContentHandler_StartLoad (contentHandler, NW_TextOf (url), |
|
336 NW_HED_UrlRequest_Reason_DocLoad, elementNode, NW_UrlRequest_Type_Any); |
|
337 |
|
338 NW_Object_Delete(url); |
|
339 |
|
340 if (status != KBrsrSuccess) |
|
341 { |
|
342 NW_HED_DocumentNode_HandleError (contentHandler, |
|
343 NW_HED_ContentHandler_GetUrlRequest (contentHandler), |
|
344 BRSR_STAT_CLASS_GENERAL, (NW_WaeError_t) status); |
|
345 } |
|
346 |
|
347 // we absorbed the event! |
|
348 return NW_LMgr_EventAbsorbed; |
|
349 } |
|
350 |
|
351 // |
|
352 // Get the URL in base tag defined in header, this value can be used to combine with |
|
353 // relative URL to figure out the absolute URL. |
|
354 // |
|
355 static TBrowserStatusCode |
|
356 NW_XHTML_frameElementHandler_getBaseTagUrl (NW_XHTML_ContentHandler_t* contentHandler, |
|
357 NW_Text_t** srcVal) |
|
358 { |
|
359 NW_DOM_Node_t* baseElement; |
|
360 NW_String_t href; |
|
361 |
|
362 NW_ASSERT (srcVal); |
|
363 |
|
364 // get the base url as found in the "base" element |
|
365 baseElement = NW_HED_DomHelper_FindElement (&contentHandler->domHelper, NW_HED_DomTree_GetRootNode ( |
|
366 contentHandler->domTree), 3, NW_XHTML_ElementToken_base, 0, NULL); |
|
367 |
|
368 if (baseElement) |
|
369 { |
|
370 TBrowserStatusCode status = NW_HED_DomHelper_GetAttributeValue (&contentHandler->domHelper, baseElement, |
|
371 NW_XHTML_AttributeToken_href, &href); |
|
372 |
|
373 if (status == KBrsrSuccess) |
|
374 { |
|
375 *srcVal = (NW_Text_t*) NW_Text_UCS2_New (href.storage, 0, NW_Text_Flags_TakeOwnership); |
|
376 } |
|
377 } |
|
378 return KBrsrSuccess; |
|
379 } |
|