1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/renderer/android/content_detector.h" 6 7#include "base/logging.h" 8#include "third_party/WebKit/public/platform/WebPoint.h" 9#include "third_party/WebKit/public/web/WebHitTestResult.h" 10#include "third_party/WebKit/public/web/WebSurroundingText.h" 11 12using WebKit::WebRange; 13using WebKit::WebSurroundingText; 14 15namespace content { 16 17ContentDetector::Result::Result() : valid(false) {} 18 19ContentDetector::Result::Result(const WebKit::WebRange& content_boundaries, 20 const std::string& text, 21 const GURL& intent_url) 22 : valid(true), 23 content_boundaries(content_boundaries), 24 text(text), 25 intent_url(intent_url) { 26} 27 28ContentDetector::Result::~Result() {} 29 30ContentDetector::Result ContentDetector::FindTappedContent( 31 const WebKit::WebHitTestResult& hit_test) { 32 if (hit_test.isNull()) 33 return Result(); 34 35 std::string content_text; 36 WebKit::WebRange range = FindContentRange(hit_test, &content_text); 37 if (range.isNull()) 38 return Result(); 39 40 GURL intent_url = GetIntentURL(content_text); 41 return Result(range, content_text, intent_url); 42} 43 44WebRange ContentDetector::FindContentRange( 45 const WebKit::WebHitTestResult& hit_test, 46 std::string* content_text) { 47 // As the surrounding text extractor looks at maxLength/2 characters on 48 // either side of the hit point, we need to double max content length here. 49 WebSurroundingText surrounding_text; 50 surrounding_text.initialize(hit_test.node(), hit_test.localPoint(), 51 GetMaximumContentLength() * 2); 52 if (surrounding_text.isNull()) 53 return WebRange(); 54 55 string16 content = surrounding_text.textContent(); 56 if (content.empty()) 57 return WebRange(); 58 59 size_t selected_offset = surrounding_text.hitOffsetInTextContent(); 60 for (size_t start_offset = 0; start_offset < content.length();) { 61 size_t relative_start, relative_end; 62 if (!FindContent(content.begin() + start_offset, 63 content.end(), &relative_start, &relative_end, content_text)) { 64 break; 65 } else { 66 size_t content_start = start_offset + relative_start; 67 size_t content_end = start_offset + relative_end; 68 DCHECK(content_end <= content.length()); 69 70 if (selected_offset >= content_start && selected_offset < content_end) { 71 WebRange range = surrounding_text.rangeFromContentOffsets( 72 content_start, content_end); 73 DCHECK(!range.isNull()); 74 return range; 75 } else { 76 start_offset += relative_end; 77 } 78 } 79 } 80 81 return WebRange(); 82} 83 84} // namespace content 85