Home | History | Annotate | Download | only in android
      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 
     12 using blink::WebRange;
     13 using blink::WebSurroundingText;
     14 
     15 namespace content {
     16 
     17 ContentDetector::Result::Result() : valid(false) {}
     18 
     19 ContentDetector::Result::Result(const blink::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 
     28 ContentDetector::Result::~Result() {}
     29 
     30 ContentDetector::Result ContentDetector::FindTappedContent(
     31     const blink::WebHitTestResult& hit_test) {
     32   if (hit_test.isNull())
     33     return Result();
     34 
     35   std::string content_text;
     36   blink::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 
     44 WebRange ContentDetector::FindContentRange(
     45     const blink::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   base::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