|
1 /* |
|
2 * Copyright (c) 2006 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: Frame in webkit side |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "config.h" |
|
19 |
|
20 #include "BrCtl.h" |
|
21 #include "Frame.h" |
|
22 #include "Cache.h" |
|
23 #include "DocLoader.h" |
|
24 #include "IntPoint.h" |
|
25 #include "String.h" |
|
26 #include "HTMLNames.h" |
|
27 #include "EventNames.h" |
|
28 #include "HTMLInputElement.h" |
|
29 #include "Document.h" |
|
30 #include "WebFrame.h" |
|
31 #include "WebFrameView.h" |
|
32 #include "WebCursor.h" |
|
33 #include "WebView.h" |
|
34 #include "FrameView.h" |
|
35 #include "RenderImage.h" |
|
36 #include "IntRect.h" |
|
37 #include "FloatRect.h" |
|
38 #include "Image.h" |
|
39 #include "HTMLImageElement.h" |
|
40 #include "StaticObjectsContainer.h" |
|
41 #include "SelectionController.h" |
|
42 #include "WebUtil.h" |
|
43 #include "errordefs.h" |
|
44 #include "RenderListBox.h" |
|
45 #include "RenderTextControl.h" |
|
46 #include "RenderView.h" |
|
47 #include "PlatformScrollbar.h" |
|
48 #include "HTMLSelectElement.h" |
|
49 #include "webkitlogger.h" |
|
50 #include <StringLoader.h> |
|
51 #include <sslerr.h> |
|
52 #include <httperr.h> |
|
53 #include <inet6err.h> |
|
54 #include <in_sock.h> |
|
55 |
|
56 using namespace WebCore; |
|
57 using namespace EventNames; |
|
58 using namespace HTMLNames; |
|
59 |
|
60 static const char* KTel = "tel:"; |
|
61 static const char* KMailto = "mailto:"; |
|
62 static const char* KWtai = "wtai:"; |
|
63 static const char* KWtaiMC = "wtai://wp/mc;"; |
|
64 static const char* KWtaiAP = "wtai://wp/ap;"; |
|
65 static const char* KWtaiSD = "wtai://wp/sd;"; |
|
66 |
|
67 _LIT(KPathBegin,"<!--framePathBegin "); |
|
68 _LIT(KPathEnd," framePathEnd --!>"); |
|
69 _LIT(KMimeWBMP, "image/vnd.wap.wbmp"); |
|
70 _LIT(KMimeOTA, "image/vnd.nokia.ota-bitmap"); |
|
71 |
|
72 TBrCtlDefs::TBrCtlElementType nodeTypeB(Node* node, Frame* frame) |
|
73 { |
|
74 if( !node || !node->isElementNode() ) |
|
75 return TBrCtlDefs::EElementNone; |
|
76 |
|
77 TBrCtlDefs::TBrCtlElementType elType(TBrCtlDefs::EElementNone); |
|
78 HTMLElement *e = static_cast<HTMLElement *>(node); |
|
79 |
|
80 // get the right element type |
|
81 if ( e->hasLocalName(linkTag) ) { |
|
82 elType = TBrCtlDefs::EElementAnchor; |
|
83 } |
|
84 else if ( e->hasLocalName(aTag) ) { |
|
85 elType = TBrCtlDefs::EElementAnchor; |
|
86 |
|
87 String href = e->getAttribute( hrefAttr ); |
|
88 if (!href.isNull()) { |
|
89 |
|
90 if( href.startsWith( KTel ) ) { |
|
91 elType = TBrCtlDefs::EElementTelAnchor; |
|
92 } |
|
93 else if( href.startsWith( KWtai ) ) { |
|
94 |
|
95 if( href.startsWith( KWtaiMC ) || href.startsWith(KWtaiAP) || href.startsWith(KWtaiSD) ) { |
|
96 elType = TBrCtlDefs::EElementTelAnchor; |
|
97 } |
|
98 |
|
99 } |
|
100 else if( href.startsWith( KMailto ) ) { |
|
101 elType = TBrCtlDefs::EElementMailtoAnchor; |
|
102 } |
|
103 |
|
104 |
|
105 } |
|
106 else if (!e->getAttribute( ctiAttr ).isNull()) { |
|
107 elType = TBrCtlDefs::EElementTelAnchor; |
|
108 } |
|
109 else if( e->hasLocalName(areaTag) ) { |
|
110 |
|
111 elType = TBrCtlDefs::EElementInputBox; |
|
112 } |
|
113 } |
|
114 else if (e->isControl()) { |
|
115 HTMLGenericFormElement* ie = static_cast<HTMLGenericFormElement*>( e ); |
|
116 // default for form element |
|
117 elType = TBrCtlDefs::EElementInputBox; |
|
118 if (ie->type() == "radio") |
|
119 elType = ((HTMLInputElement*)ie)->checked() ? TBrCtlDefs::EElementRadioButtonSelected : TBrCtlDefs::EElementRadioButtonUnSelected; |
|
120 else if (ie->type() == "checkbox") |
|
121 elType = ((HTMLInputElement*)ie)->checked() ? TBrCtlDefs::EElementCheckBoxChecked : TBrCtlDefs::EElementCheckBoxUnChecked; |
|
122 else if (ie->type() == "button" || ie->type() == "reset" || ie->type() == "submit") |
|
123 elType = TBrCtlDefs::EElementButton; |
|
124 else if (ie->type() == "file") { |
|
125 if (((HTMLInputElement*)ie)->value() == String()) |
|
126 elType = TBrCtlDefs::EElementFileSelectionBoxNoContent; |
|
127 else |
|
128 elType = TBrCtlDefs::EElementFileSelectionBoxWithContent; |
|
129 } |
|
130 else if (ie->type() == "select-multiple") |
|
131 elType = TBrCtlDefs::EElementSelectMultiBox; |
|
132 else if ( ie->type() == "select-one") { |
|
133 if(!e->getAttribute(sizeAttr).isNull() && !(e->getAttribute(sizeAttr) == "1")) { |
|
134 elType = TBrCtlDefs::EElementSelectMultiBox; |
|
135 } |
|
136 else { |
|
137 elType = TBrCtlDefs::EElementSelectBox; |
|
138 } |
|
139 } |
|
140 else if (ie->type() == "textarea") |
|
141 elType = TBrCtlDefs::EElementTextAreaBox; |
|
142 } |
|
143 else if( e->hasLocalName(objectTag) || e->hasLocalName(embedTag) ) { |
|
144 if( e->renderer() && e->renderer()->isWidget() ) |
|
145 if(node->active()) |
|
146 elType = TBrCtlDefs::EElementActivatedObjectBox; |
|
147 else |
|
148 elType = TBrCtlDefs::EElementObjectBox; |
|
149 else |
|
150 elType = TBrCtlDefs::EElementNone; |
|
151 } |
|
152 |
|
153 // change to activated input box |
|
154 WebView* v = control(frame)->webView(); |
|
155 if ((elType == TBrCtlDefs::EElementInputBox || elType == TBrCtlDefs::EElementTextAreaBox) && v && v->isEditable()) |
|
156 elType = TBrCtlDefs::EElementActivatedInputBox; |
|
157 |
|
158 return elType; |
|
159 } |
|
160 |
|
161 |
|
162 WebFrame* frameAndPointUnderCursor(IntPoint& p_, WebView& v_) |
|
163 { |
|
164 WebFrameView* mfv = v_.mainFrame()->frameView(); |
|
165 p_ = StaticObjectsContainer::instance()->webCursor()->position(); |
|
166 WebFrame* frame = v_.mainFrame()->frameAtPoint(p_); |
|
167 if (!frame) |
|
168 frame = v_.mainFrame(); |
|
169 IntPoint rc = frame->frameView()->rectInGlobalCoords().iTl; |
|
170 p_ = frame->frameView()->viewCoordsInFrameCoords(p_); |
|
171 return frame; |
|
172 } |
|
173 |
|
174 String getNodeUrlAtPointInFrame(WebFrame& f_, IntPoint& p_) |
|
175 { |
|
176 Document* doc = core(&f_)->document(); |
|
177 if (doc) { |
|
178 Node* node = doc->elementFromPoint(p_.x(), p_.y()); |
|
179 |
|
180 if (node) { |
|
181 if (node->hasTagName(areaTag)) { |
|
182 HTMLElement* e = static_cast<HTMLElement*>(node); |
|
183 if(!e->getAttribute(hrefAttr).isNull()) { |
|
184 return e->getAttribute(hrefAttr); |
|
185 } |
|
186 } |
|
187 // get the navigable node at this point |
|
188 Node* n = node; |
|
189 for (; n; n = n->parentNode()) |
|
190 if (n->isFocusable() && n->isElementNode()) |
|
191 break; |
|
192 |
|
193 if (n && n->isFocusable() && n->isElementNode()) { |
|
194 HTMLElement* e = static_cast<HTMLElement*>(n); |
|
195 if (!e->getAttribute(hrefAttr).isNull()) { |
|
196 return e->getAttribute(hrefAttr); |
|
197 } |
|
198 } |
|
199 } |
|
200 } |
|
201 return String(); |
|
202 } |
|
203 |
|
204 |
|
205 int imageCountInFrame(WebFrame& wf_, bool visibleOnly_) |
|
206 { |
|
207 int count = 0; |
|
208 Frame* f = core(&wf_); |
|
209 |
|
210 if (!f || !f->document() || !f->document()->renderer()) |
|
211 return count; |
|
212 |
|
213 Document* doc = f->document(); |
|
214 RefPtr<WebCore::HTMLCollection> collection = doc->images(); |
|
215 |
|
216 FrameView* v = doc->view(); |
|
217 IntRect r1 = wf_.frameView()->topView()->mainFrame()->frameView()->rect(); |
|
218 |
|
219 for (Node *n = collection->firstItem(); n; n = collection->nextItem()) { |
|
220 |
|
221 RenderImage* render = static_cast<RenderImage*>(n->renderer()); |
|
222 if (render) { |
|
223 |
|
224 Image* img = render->image(); |
|
225 if (!img->isNull() && img->data()) { |
|
226 //if visible only is true, check for intersection |
|
227 bool processing = true; |
|
228 if (visibleOnly_) { |
|
229 IntRect imageRect; |
|
230 IntPoint tl = wf_.frameView()->frameCoordsInViewCoords(n->getRect().topLeft()); |
|
231 IntPoint br = wf_.frameView()->frameCoordsInViewCoords(n->getRect().bottomRight()); |
|
232 imageRect.setLocation(tl); |
|
233 imageRect.setSize(br-tl); |
|
234 |
|
235 processing = r1.intersects(imageRect); |
|
236 } |
|
237 if (processing) { |
|
238 String alttext = static_cast<HTMLImageElement*>(render->element())->altText(); |
|
239 // Check if alttext is "Nokia" or "No_save". |
|
240 // Then do not count |
|
241 if (!(equalIgnoringCase(alttext, "nokia") || equalIgnoringCase(alttext, "no_save"))) |
|
242 ++count; |
|
243 } |
|
244 } |
|
245 } |
|
246 |
|
247 } |
|
248 return count; |
|
249 } |
|
250 |
|
251 CArrayFixFlat<TBrCtlImageCarrier>* imagesInFrame(WebFrame& wf_, bool visibleOnly_) |
|
252 { |
|
253 CArrayFixFlat<TBrCtlImageCarrier>* imglist = new CArrayFixFlat<TBrCtlImageCarrier>(10); |
|
254 Frame* f = core(&wf_); |
|
255 |
|
256 if (!f || !f->document() || !f->document()->renderer()) |
|
257 return imglist; |
|
258 |
|
259 CleanupStack::PushL(imglist); |
|
260 |
|
261 Document* doc = f->document(); |
|
262 FrameView* v = doc->view(); |
|
263 IntRect r1 = wf_.frameView()->topView()->mainFrame()->frameView()->rect(); |
|
264 |
|
265 |
|
266 RefPtr<WebCore::HTMLCollection> collection = doc->images(); |
|
267 for (Node* n = collection->firstItem(); n; n = collection->nextItem()) { |
|
268 |
|
269 RenderImage* render = static_cast<RenderImage*>(n->renderer()); |
|
270 if (render) { |
|
271 Image* img = render->image(); |
|
272 if (!img->isNull() && img->data()) { |
|
273 //if visible only is true, check for intersection |
|
274 TBool processing = ETrue; |
|
275 if (visibleOnly_) { |
|
276 IntRect imageRect; |
|
277 IntPoint tl = wf_.frameView()->frameCoordsInViewCoords(n->getRect().topLeft()); |
|
278 IntPoint br = wf_.frameView()->frameCoordsInViewCoords(n->getRect().bottomRight()); |
|
279 imageRect.setLocation(tl); |
|
280 imageRect.setSize(br-tl); |
|
281 |
|
282 processing = r1.intersects(imageRect); |
|
283 } |
|
284 if (processing) { |
|
285 String alttext = static_cast<HTMLImageElement*>(render->element())->altText(); |
|
286 TBrCtlImageType type = EImageTypeAny; |
|
287 if (img->getMimeType().find("image/vnd.wap.wbmp") == 0) |
|
288 type = EImageTypeWbmp; |
|
289 else if (img->getMimeType().find("image/vnd.nokia.ota-bitmap") == 0) |
|
290 type = EImageTypeOta; |
|
291 // |
|
292 TBrCtlImageCarrier tImg(TPtrC8((const TUint8*)img->data()->data(),img->data()->size()), |
|
293 static_cast<HTMLImageElement*>(render->element())->getAttribute(srcAttr), |
|
294 alttext, type, img->getMimeType()); |
|
295 |
|
296 // Check if alttext is "Nokia" or "No_save". |
|
297 // Then do not add the image to the list |
|
298 if (!(equalIgnoringCase(alttext, "nokia") || equalIgnoringCase(alttext, "no_save"))) { |
|
299 // Check if this image has been retrieved before. |
|
300 // Image pointer should be the same for similar images |
|
301 TBool imgexists = false; |
|
302 for (int i=0; i<imglist->Count();i++) { |
|
303 TBrCtlImageCarrier wcImage = imglist->At(i); |
|
304 if (tImg.RawData() == wcImage.RawData()) { |
|
305 imgexists = true; |
|
306 break; |
|
307 } |
|
308 |
|
309 } |
|
310 if (!imgexists) |
|
311 imglist->AppendL(tImg); |
|
312 } |
|
313 } |
|
314 } |
|
315 } |
|
316 } |
|
317 CleanupStack::Pop(imglist); |
|
318 return imglist; |
|
319 } |
|
320 |
|
321 CArrayFixFlat<TBrCtlSubscribeTo>* findSubscribeToInFrame(WebFrame& wf_) |
|
322 { |
|
323 CArrayFixFlat<TBrCtlSubscribeTo>* linkList = new CArrayFixFlat<TBrCtlSubscribeTo>(10); |
|
324 Frame* f = core(&wf_); |
|
325 |
|
326 if (!f || !f->document()) |
|
327 return linkList; |
|
328 |
|
329 CleanupStack::PushL(linkList); |
|
330 for (Node *n = f->document(); n; n = n->traverseNextNode()) { |
|
331 if (n->isElementNode() && n->hasTagName(linkTag)) { |
|
332 |
|
333 HTMLElement* e = static_cast<HTMLElement*>(n); |
|
334 String type = e->getAttribute(typeAttr); |
|
335 |
|
336 if (type == "application/rss+xml" || type == "application/atom+xml" || |
|
337 type == "text/xml" || type == "application/xml") { |
|
338 String href = e->getAttribute(hrefAttr); |
|
339 String title = e->getAttribute(titleAttr); |
|
340 |
|
341 TBrCtlSubscribeTo item(title.des(), href.des(), 0); |
|
342 linkList->AppendL(item); |
|
343 } |
|
344 } |
|
345 } |
|
346 CleanupStack::Pop(linkList); |
|
347 return linkList; |
|
348 } |
|
349 |
|
350 int focusedImage(WebView* webView, TBrCtlImageCarrier*& imageCarrier) |
|
351 { |
|
352 int ret = KErrNone; |
|
353 TBrCtlImageCarrier* t = NULL; |
|
354 RenderImage *r = renderImageUnderCursor(webView); |
|
355 if (r) { |
|
356 Image* img = r->image(); |
|
357 CachedImage* ci = r->cachedImage(); |
|
358 if( ci && !img->isNull()) { |
|
359 SharedBuffer* imgData = img->data(); |
|
360 if (imgData) { |
|
361 TPtrC8 rawData((const unsigned char*)(imgData->data()), (imgData->size())); |
|
362 // Check if there is data in the image buffer. |
|
363 // Broken links do not have data in them |
|
364 if (rawData.Length() > 0) { |
|
365 // Get the alt text |
|
366 String alttext = static_cast<HTMLImageElement*>(r->element())->altText(); |
|
367 // Check if alttext is "Nokia" or "No_save". |
|
368 // Then do not add the image to the list |
|
369 if (!(equalIgnoringCase(alttext, "nokia") || equalIgnoringCase(alttext, "no_save"))) { |
|
370 TBrCtlImageType brCtlTtype = EImageTypeAny; |
|
371 if( img->getMimeType().des().Find(KMimeWBMP) != KErrNotFound ) { |
|
372 brCtlTtype = EImageTypeWbmp; |
|
373 } |
|
374 else if ( img->getMimeType().des().Find(KMimeOTA) != KErrNotFound ) { |
|
375 brCtlTtype = EImageTypeOta; |
|
376 } |
|
377 t = new TBrCtlImageCarrier(TPtrC8((const TUint8*)img->data()->data(),img->data()->size()), |
|
378 static_cast<HTMLImageElement*>(r->element())->getAttribute(srcAttr), |
|
379 alttext, brCtlTtype, img->getMimeType()); |
|
380 if (!t) { |
|
381 ret = KErrNoMemory; |
|
382 } |
|
383 else { |
|
384 ret = KErrNone; |
|
385 } |
|
386 } |
|
387 else { |
|
388 ret = KErrAccessDenied; |
|
389 } |
|
390 } // if (rawData.Length() > 0) |
|
391 else { |
|
392 ret = KErrNotFound; |
|
393 } |
|
394 } |
|
395 else { |
|
396 ret = KErrNotFound; |
|
397 } |
|
398 } // if (ci) |
|
399 else { |
|
400 ret = KErrNotFound; |
|
401 } |
|
402 } // if (r) |
|
403 else { |
|
404 ret = KErrNoMemory; |
|
405 } |
|
406 imageCarrier = t; |
|
407 return ret; |
|
408 } |
|
409 |
|
410 void loadFocusedImage(WebView* webView) |
|
411 { |
|
412 RenderImage *r = renderImageUnderCursor(webView); |
|
413 if (r) { |
|
414 CachedImage* ci = r->cachedImage(); |
|
415 if (ci && ci->status() == CachedResource::Unknown) { |
|
416 IntPoint p; |
|
417 WebFrame* frame = frameAndPointUnderCursor(p, *webView); |
|
418 cache()->loader()->load(core(frame)->document()->docLoader(), ci, true); |
|
419 } |
|
420 } |
|
421 } |
|
422 |
|
423 RenderImage* renderImageUnderCursor(WebView* webView) |
|
424 { |
|
425 IntPoint p; |
|
426 WebFrame* frame = frameAndPointUnderCursor(p, *webView); |
|
427 Frame* f = core(frame); |
|
428 RenderImage* render = NULL; |
|
429 if (!f || !f->document() || !f->document()->renderer()) |
|
430 return NULL; |
|
431 Document* doc = f->document(); |
|
432 FrameView* v = doc->view(); |
|
433 RefPtr<WebCore::HTMLCollection> collection = doc->images(); |
|
434 for (Node* n = collection->firstItem(); n; n = collection->nextItem()) { |
|
435 render = static_cast<RenderImage*>(n->renderer()); |
|
436 if (render) { |
|
437 Image* img = render->image(); |
|
438 if (!img->isNull()) { |
|
439 //if visible only is true, check for intersection |
|
440 if (n->getRect().contains(p)) { |
|
441 return render; |
|
442 } |
|
443 } |
|
444 } |
|
445 } |
|
446 return NULL; |
|
447 } |
|
448 |
|
449 HBufC* generateFrameName() |
|
450 { |
|
451 HBufC* name = NULL; |
|
452 name = HBufC::New(60); |
|
453 if (name) { |
|
454 TPtr path = name->Des(); |
|
455 path.Copy(KPathBegin); |
|
456 TBuf<20>timeBuf; |
|
457 TTime ttime; |
|
458 ttime.HomeTime(); |
|
459 timeBuf.Num(ttime.Int64()); |
|
460 path.Append(timeBuf); |
|
461 path.Append(KPathEnd); |
|
462 } |
|
463 return name; |
|
464 } |
|
465 |
|
466 |
|
467 void addOneMenuItemAfter(CEikMenuPane& menuPane, unsigned int after, int command, int resourceId, unsigned int commandBase) |
|
468 { |
|
469 CEikMenuPaneItem::SData item; |
|
470 HBufC* buf = StringLoader::LoadLC(resourceId); |
|
471 item.iText.Copy(*buf); |
|
472 CleanupStack::PopAndDestroy(); // buf |
|
473 buf = NULL; |
|
474 item.iCommandId = command + commandBase; |
|
475 item.iFlags = 0; |
|
476 item.iCascadeId = 0; |
|
477 menuPane.AddMenuItemL(item, after); |
|
478 } |
|
479 |
|
480 void insertOneMenuItem(CEikMenuPane& menuPane, int command, int resourceId, unsigned int commandBase) |
|
481 { |
|
482 CEikMenuPaneItem::SData item; |
|
483 HBufC* buf = StringLoader::LoadLC(resourceId); |
|
484 item.iText.Copy(*buf); |
|
485 CleanupStack::PopAndDestroy(); // buf |
|
486 buf = NULL; |
|
487 item.iCommandId = command + commandBase; |
|
488 item.iFlags = 0; |
|
489 item.iCascadeId = 0; |
|
490 menuPane.InsertMenuItemL(item, 0); |
|
491 } |
|
492 |
|
493 int textMultiplier(int fontLevel, int originalSize) |
|
494 { |
|
495 int sizeMultiplier = originalSize; |
|
496 switch(fontLevel) |
|
497 { |
|
498 case TBrCtlDefs::EFontSizeLevelAllSmall: |
|
499 // show text 40% smaller than the declared size |
|
500 sizeMultiplier *= 0.6; |
|
501 break; |
|
502 case TBrCtlDefs::EFontSizeLevelSmaller: |
|
503 // show text 20% smaller than the declared size |
|
504 sizeMultiplier *= 0.8; |
|
505 break; |
|
506 default: |
|
507 case TBrCtlDefs::EFontSizeLevelNormal: |
|
508 break; |
|
509 case TBrCtlDefs::EFontSizeLevelLarger: |
|
510 // show text 25% larger than the declared size |
|
511 sizeMultiplier *= 1.25; |
|
512 break; |
|
513 case TBrCtlDefs::EFontSizeLevelAllLarge: |
|
514 // show text 50% larger than the declared size |
|
515 sizeMultiplier *= 1.50; |
|
516 break; |
|
517 } |
|
518 return sizeMultiplier; |
|
519 } |
|
520 |
|
521 static void handleSpecialSchemeL(String url, CBrCtl* brctl) |
|
522 { |
|
523 // only the url is supported currently |
|
524 RArray<TUint> typeArray; |
|
525 CDesCArrayFlat* strArray = new CDesCArrayFlat( 1 ); |
|
526 if (strArray) { |
|
527 // add url id |
|
528 typeArray.Append( EParamRequestUrl ); |
|
529 // add url string |
|
530 TRAPD(err, strArray->AppendL( url.des() )); |
|
531 if (err == KErrNone) { |
|
532 TRAP_IGNORE(brctl->brCtlSpecialLoadObserver()->HandleRequestL( &typeArray, strArray )); |
|
533 } |
|
534 delete strArray; |
|
535 } |
|
536 } |
|
537 |
|
538 void addFocusedUrlToContacts(WebView* webView) |
|
539 { |
|
540 if (webView->brCtl()->brCtlSpecialLoadObserver()) { |
|
541 IntPoint point; |
|
542 WebFrame* frame = frameAndPointUnderCursor(point, *webView); |
|
543 if (frame) { |
|
544 Document* doc = core(frame)->document(); |
|
545 if (doc) { |
|
546 Node* node = doc->elementFromPoint(point.x(), point.y()); |
|
547 if (node) { |
|
548 // get the navigable node at this point |
|
549 Node* n = node; |
|
550 for (; n; n = n->parentNode()) |
|
551 if (n->isFocusable() && n->isElementNode()) |
|
552 break; |
|
553 |
|
554 if (n && n->isFocusable() && n->isElementNode()) { |
|
555 HTMLElement* e = static_cast<HTMLElement*>(n); |
|
556 String tel; |
|
557 String email; |
|
558 String telbook; |
|
559 // href |
|
560 String attr = e->getAttribute(hrefAttr); |
|
561 if (!attr.isNull() && !attr.isEmpty()) { |
|
562 if ( attr.startsWith( KTel ) ) |
|
563 tel = attr.substring(4); |
|
564 else if( attr.startsWith(KWtaiMC) ) |
|
565 tel = attr.substring(13); |
|
566 else if( attr.startsWith(KWtaiAP) ) |
|
567 tel = attr.substring(13); |
|
568 else if( attr.startsWith(KWtaiSD) ) |
|
569 tel = attr.substring(13); |
|
570 else if ( attr.startsWith( KMailto ) ) { |
|
571 email = attr.substring(7); |
|
572 // Find just the email address |
|
573 int i = email.find('?'); |
|
574 if (i > 0 ) { |
|
575 email = email.left(i).stripWhiteSpace(); |
|
576 } |
|
577 } |
|
578 } |
|
579 // cti |
|
580 attr = e->getAttribute(ctiAttr); |
|
581 if (!attr.isNull() && !attr.isEmpty() ) |
|
582 tel = attr; |
|
583 // email |
|
584 attr = e->getAttribute(emailAttr); |
|
585 if (!attr.isNull() && !attr.isEmpty() ) |
|
586 email = attr; |
|
587 // telbook |
|
588 attr = e->getAttribute(telbookAttr); |
|
589 if (!attr.isNull() && !attr.isEmpty() ) |
|
590 telbook = attr; |
|
591 // Save to phone book |
|
592 String url; |
|
593 String makeCallUrlPrefix("wtai://wp/ap;"); |
|
594 char numberNameSeparator = ';'; |
|
595 int len = makeCallUrlPrefix.length() + 3; // NULL terminator and ';' separators |
|
596 len += tel.length() + telbook.length() + email.length(); |
|
597 //url.reserve(len); |
|
598 url = makeCallUrlPrefix; |
|
599 url.append(tel); |
|
600 url.append(numberNameSeparator); |
|
601 url.append(telbook); |
|
602 url.append(numberNameSeparator); |
|
603 url.append(email); |
|
604 handleSpecialSchemeL(url, webView->brCtl()); |
|
605 } |
|
606 } |
|
607 } |
|
608 } |
|
609 } |
|
610 } |
|
611 |
|
612 // ----------------------------------------------------------------------------- |
|
613 // Map the Symbian errors to rainbow errors. |
|
614 // ----------------------------------------------------------------------------- |
|
615 // |
|
616 int mapHttpErrors(int err ) |
|
617 { |
|
618 if (err == KErrSSLAlertUserCanceled){ |
|
619 return KBrowserCancelled; |
|
620 } |
|
621 // All SSL errors are mapped into this one, which gets displayed to the user |
|
622 if (err <= SSL_ERROR_BASE && err > SSL_ERROR_BASE - 200 || |
|
623 err == KErrHttpCannotEstablishTunnel) { |
|
624 return KErrSSLAlertHandshakeFailure; |
|
625 } |
|
626 |
|
627 // Deal with DNS lookup errors |
|
628 if ((err <= KErrInet6NoDestination) && (err > (KErrInet6NoDestination - 200))) { |
|
629 return KBrowserHTTP502; |
|
630 } |
|
631 |
|
632 // Deal with HTTP errors |
|
633 if (err <= KHttpErrorBase && err > KHttpErrorBase - 200) { |
|
634 // Encode errors |
|
635 if (err <= KErrHttpEncodeDefault && err >= KErrHttpEncodeCookie2) { |
|
636 return KBrowserFailure; |
|
637 } |
|
638 // Auth errors |
|
639 if (err == KErrHttpDecodeWWWAuthenticate || |
|
640 err == KErrHttpDecodeUnknownAuthScheme || |
|
641 err == KErrHttpDecodeBasicAuth || |
|
642 err == KErrHttpDecodeDigestAuth) { |
|
643 return KBrowserMissingAuthHeader; |
|
644 } |
|
645 |
|
646 // Decode errors |
|
647 if (err <= KErrHttpDecodeMalformedDate && err >= KErrHttpDecodeCookie) { |
|
648 return KBrowserBadContent; |
|
649 } |
|
650 switch (err) |
|
651 { |
|
652 case KErrHttpRedirectExceededLimit: |
|
653 { |
|
654 return KBrowserTooManyRedirects; |
|
655 } |
|
656 case KErrHttpRedirectNoLocationField: |
|
657 case KErrHttpRedirectUseProxy: |
|
658 { |
|
659 return KBrowserBadRedirect; |
|
660 } |
|
661 case KErrHttpInvalidUri: |
|
662 { |
|
663 return KBrowserMalformedUrl; |
|
664 } |
|
665 default: |
|
666 { |
|
667 return KBrowserFailure; |
|
668 } |
|
669 } |
|
670 } |
|
671 if (err <= KBrowserHTTP100 && err > KBrowserFailure) |
|
672 return err; |
|
673 switch (err) |
|
674 { |
|
675 case KErrHostUnreach: |
|
676 { |
|
677 return KBrowserTcpHostUnreachable; |
|
678 } |
|
679 case KErrAbort: //User has interrupted the loading process. We treat it as cancellation so that no error message shown. |
|
680 case KErrCancel: |
|
681 { |
|
682 return KBrowserCancelled; |
|
683 } |
|
684 case KErrBadName: |
|
685 case KErrPathNotFound: |
|
686 { |
|
687 return KBrowserFileNotFound; |
|
688 } |
|
689 case KErrCommsLineFail: |
|
690 case KErrNotReady: |
|
691 { |
|
692 return KBrowserConnFailed; |
|
693 } |
|
694 case KErrDiskFull: |
|
695 { |
|
696 return KBrowserFileDiskFullError; |
|
697 } |
|
698 case KErrTimedOut: |
|
699 { |
|
700 return KBrowserWaitTimeout; |
|
701 } |
|
702 case KErrCouldNotConnect: |
|
703 { |
|
704 return KBrowserMalformedUrl; |
|
705 } |
|
706 case KErrDisconnected: |
|
707 { |
|
708 return KBrowserHTTP504; |
|
709 } |
|
710 case KErrNoMemory: |
|
711 { |
|
712 return KBrowserOutOfMemory; |
|
713 } |
|
714 default: |
|
715 { |
|
716 return KBrowserFailure; |
|
717 } |
|
718 } // end of switch |
|
719 } |
|
720 |
|
721 |
|
722 bool handleSelectElementScrolling(WebView* webView, int tb) |
|
723 { |
|
724 bool ret = false; |
|
725 if (webView->focusedElementType() == TBrCtlDefs::EElementSelectMultiBox && tb != 0) { |
|
726 IntPoint point; |
|
727 WebFrame* frame = frameAndPointUnderCursor(point, *webView); |
|
728 Element* e = core(frame)->document()->elementFromPoint(point.x(), point.y()); |
|
729 if (e && e->isControl()) { |
|
730 HTMLGenericFormElement* ie = static_cast<HTMLGenericFormElement*>( e ); |
|
731 if (ie->type() == "select-multiple") { |
|
732 RenderListBox* render = static_cast<RenderListBox*>(e->renderer()); |
|
733 if (render->isScrollable()) { |
|
734 HTMLSelectElement* selectElement = static_cast<HTMLSelectElement*>( e ); |
|
735 IntRect r = e->getRect(); |
|
736 int curIndex = render->listIndexAtOffset(point.x() - r.x(), point.y() - r.y()); |
|
737 int topIndex = render->indexOffset(); |
|
738 int bottomIndex = topIndex + selectElement->size() - 1; |
|
739 TPoint curPointInSelectBox(point.x() - r.x(), point.y() - r.y()); |
|
740 IntRect itemRect = render->itemRect(0, 0, curIndex); |
|
741 int centerOfRect = itemRect.y() + (itemRect.height() * 1) / 4; |
|
742 if (tb == -1) { |
|
743 if (curIndex == topIndex) { |
|
744 if (render->scroll(ScrollUp, ScrollByLine)) { |
|
745 ret = true; |
|
746 } |
|
747 } |
|
748 else { |
|
749 int step = ((itemRect.height() + (curPointInSelectBox.iY - centerOfRect)) * webView->scalingFactor()) / 100; |
|
750 if (step <= 0) step = (itemRect.height() * webView->scalingFactor()) / 100; |
|
751 TPoint tp(StaticObjectsContainer::instance()->webCursor()->position().iX, StaticObjectsContainer::instance()->webCursor()->position().iY - step); |
|
752 StaticObjectsContainer::instance()->webCursor()->updatePositionAndElemType(tp); |
|
753 ret = true; |
|
754 } |
|
755 } |
|
756 else { |
|
757 if (curIndex == bottomIndex) { |
|
758 if (render->scroll(ScrollDown, ScrollByLine)) { |
|
759 ret = true; |
|
760 } |
|
761 } |
|
762 else { |
|
763 int step = ((itemRect.height() + (centerOfRect - curPointInSelectBox.iY)) * webView->scalingFactor()) / 100; |
|
764 if (step <= 0) step = (itemRect.height() * webView->scalingFactor()) / 100; |
|
765 TPoint tp(StaticObjectsContainer::instance()->webCursor()->position().iX, StaticObjectsContainer::instance()->webCursor()->position().iY + step); |
|
766 StaticObjectsContainer::instance()->webCursor()->updatePositionAndElemType(tp); |
|
767 ret = true; |
|
768 } |
|
769 } |
|
770 } |
|
771 } |
|
772 } |
|
773 } |
|
774 return ret; |
|
775 } |
|
776 |