File add-missing-blink-tools.patch of Package chromium.openSUSE_Leap_42.3_Update

Description: add back contents of third-party/blink/tools that went missing in the source tarball for 66.0.3359.106
Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=832283

--- /dev/null
+++ b/third_party/blink/tools/OWNERS
@@ -0,0 +1 @@
+file://third_party/WebKit/Tools/OWNERS
--- /dev/null
+++ b/third_party/blink/tools/blinkpy/__init__.py
@@ -0,0 +1,3 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
--- /dev/null
+++ b/third_party/blink/tools/blinkpy/common/__init__.py
@@ -0,0 +1,3 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
--- /dev/null
+++ b/third_party/blink/tools/blinkpy/common/name_style_converter.py
@@ -0,0 +1,128 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# pylint: disable=import-error,print-statement,relative-import
+
+import re
+
+SPECIAL_TOKENS = [
+    # This list should be sorted by length.
+    'CString',
+    'Float32',
+    'Float64',
+    'Base64',
+    'IFrame',
+    'Latin1',
+    'PlugIn',
+    'SQLite',
+    'Uint16',
+    'Uint32',
+    'WebGL2',
+    'ASCII',
+    'CType',
+    'DList',
+    'Int16',
+    'Int32',
+    'MPath',
+    'OList',
+    'TSpan',
+    'UList',
+    'UTF16',
+    'Uint8',
+    'WebGL',
+    'XPath',
+    'ETC1',
+    'HTML',
+    'Int8',
+    'S3TC',
+    'SPv2',
+    'UTF8',
+    'API',
+    'CSS',
+    'DOM',
+    'EXT',
+    'RTC',
+    'SVG',
+    '2D',
+    'AX',
+    'V0',
+    'V8',
+]
+
+MATCHING_EXPRESSION = '((?:[A-Z][a-z]+)|[0-9]D?$)'
+
+
+class SmartTokenizer(object):
+    """Detects special cases that are not easily discernible without additional
+       knowledge, such as recognizing that in SVGSVGElement, the first two SVGs
+       are separate tokens, but WebGL is one token."""
+
+    def __init__(self, name):
+        self.remaining = name
+
+    def tokenize(self):
+        name = self.remaining
+        tokens = []
+        while len(name) > 0:
+            matched_token = None
+            for token in SPECIAL_TOKENS:
+                if name.startswith(token):
+                    matched_token = token
+                    break
+            if not matched_token:
+                match = re.search(MATCHING_EXPRESSION, name)
+                if not match:
+                    matched_token = name
+                elif match.start(0) != 0:
+                    matched_token = name[:match.start(0)]
+                else:
+                    matched_token = match.group(0)
+            tokens.append(name[:len(matched_token)])
+            name = name[len(matched_token):]
+        return tokens
+
+
+class NameStyleConverter(object):
+    """Converts names from camelCase to various other styles.
+    """
+
+    def __init__(self, name):
+        self.tokens = self.tokenize(name)
+
+    def tokenize(self, name):
+        tokenizer = SmartTokenizer(name)
+        return tokenizer.tokenize()
+
+    def to_snake_case(self):
+        """Snake case is the file and variable name style per Google C++ Style
+           Guide:
+           https://google.github.io/styleguide/cppguide.html#Variable_Names
+
+           Also known as the hacker case.
+           https://en.wikipedia.org/wiki/Snake_case
+        """
+        return '_'.join([token.lower() for token in self.tokens])
+
+    def to_upper_camel_case(self):
+        """Upper-camel case is the class and function name style per
+           Google C++ Style Guide:
+           https://google.github.io/styleguide/cppguide.html#Function_Names
+
+           Also known as the PascalCase.
+           https://en.wikipedia.org/wiki/Camel_case.
+        """
+        return ''.join([token[0].upper() + token[1:] for token in self.tokens])
+
+    def to_macro_case(self):
+        """Macro case is the macro name style per Google C++ Style Guide:
+           https://google.github.io/styleguide/cppguide.html#Macro_Names
+        """
+        return '_'.join([token.upper() for token in self.tokens])
+
+    def to_all_cases(self):
+        return {
+            'snake_case': self.to_snake_case(),
+            'upper_camel_case': self.to_upper_camel_case(),
+            'macro_case': self.to_macro_case(),
+        }
--- /dev/null
+++ b/third_party/blink/tools/blinkpy/common/name_style_converter_test.py
@@ -0,0 +1,178 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# pylint: disable=import-error,print-statement,relative-import,protected-access
+
+"""Unit tests for name_style_converter.py."""
+
+import unittest
+
+from name_style_converter import NameStyleConverter
+from name_style_converter import SmartTokenizer
+
+
+class SmartTokenizerTest(unittest.TestCase):
+    def test_simple_cases(self):
+        tokenizer = SmartTokenizer('foo')
+        self.assertEqual(tokenizer.tokenize(), ['foo'])
+
+        tokenizer = SmartTokenizer('fooBar')
+        self.assertEqual(tokenizer.tokenize(), ['foo', 'Bar'])
+
+        tokenizer = SmartTokenizer('fooBarBaz')
+        self.assertEqual(tokenizer.tokenize(), ['foo', 'Bar', 'Baz'])
+
+        tokenizer = SmartTokenizer('Baz')
+        self.assertEqual(tokenizer.tokenize(), ['Baz'])
+
+        tokenizer = SmartTokenizer('')
+        self.assertEqual(tokenizer.tokenize(), [])
+
+        tokenizer = SmartTokenizer('FOO')
+        self.assertEqual(tokenizer.tokenize(), ['FOO'])
+
+        tokenizer = SmartTokenizer('foo2')
+        self.assertEqual(tokenizer.tokenize(), ['foo', '2'])
+
+    def test_tricky_cases(self):
+        tokenizer = SmartTokenizer('XMLHttpRequest')
+        self.assertEqual(tokenizer.tokenize(), ['XML', 'Http', 'Request'])
+
+        tokenizer = SmartTokenizer('HTMLElement')
+        self.assertEqual(tokenizer.tokenize(), ['HTML', 'Element'])
+
+        tokenizer = SmartTokenizer('WebGLRenderingContext')
+        self.assertEqual(tokenizer.tokenize(),
+                         ['WebGL', 'Rendering', 'Context'])
+
+        tokenizer = SmartTokenizer('CanvasRenderingContext2D')
+        self.assertEqual(tokenizer.tokenize(),
+                         ['Canvas', 'Rendering', 'Context', '2D'])
+        tokenizer = SmartTokenizer('CanvasRenderingContext2DAPITest')
+        self.assertEqual(tokenizer.tokenize(),
+                         ['Canvas', 'Rendering', 'Context', '2D', 'API', 'Test'])
+
+        tokenizer = SmartTokenizer('SVGSVGElement')
+        self.assertEqual(tokenizer.tokenize(), ['SVG', 'SVG', 'Element'])
+
+        tokenizer = SmartTokenizer('CanvasRenderingContext2D')
+        self.assertEqual(tokenizer.tokenize(), ['Canvas', 'Rendering', 'Context', '2D'])
+
+        tokenizer = SmartTokenizer('CSSURLImageValue')
+        self.assertEqual(tokenizer.tokenize(), ['CSS', 'URL', 'Image', 'Value'])
+        tokenizer = SmartTokenizer('CSSPropertyAPID')
+        self.assertEqual(tokenizer.tokenize(), ['CSS', 'Property', 'API', 'D'])
+        tokenizer = SmartTokenizer('AXARIAGridCell')
+        self.assertEqual(tokenizer.tokenize(), ['AX', 'ARIA', 'Grid', 'Cell'])
+
+        tokenizer = SmartTokenizer('CDATASection')
+        self.assertEqual(tokenizer.tokenize(), ['CDATA', 'Section'])
+
+        tokenizer = SmartTokenizer('ASCIICType')
+        self.assertEqual(tokenizer.tokenize(), ['ASCII', 'CType'])
+        tokenizer = SmartTokenizer('CString')
+        self.assertEqual(tokenizer.tokenize(), ['CString'])
+
+        tokenizer = SmartTokenizer('HTMLDListElement')
+        self.assertEqual(tokenizer.tokenize(), ['HTML', 'DList', 'Element'])
+        tokenizer = SmartTokenizer('HTMLOListElement')
+        self.assertEqual(tokenizer.tokenize(), ['HTML', 'OList', 'Element'])
+        tokenizer = SmartTokenizer('HTMLIFrameElement')
+        self.assertEqual(tokenizer.tokenize(), ['HTML', 'IFrame', 'Element'])
+        tokenizer = SmartTokenizer('HTMLPlugInElement')
+        self.assertEqual(tokenizer.tokenize(), ['HTML', 'PlugIn', 'Element'])
+
+        # No special handling for OptGroup, FieldSet, and TextArea.
+        tokenizer = SmartTokenizer('HTMLOptGroupElement')
+        self.assertEqual(tokenizer.tokenize(), ['HTML', 'Opt', 'Group', 'Element'])
+        tokenizer = SmartTokenizer('HTMLFieldSetElement')
+        self.assertEqual(tokenizer.tokenize(), ['HTML', 'Field', 'Set', 'Element'])
+        tokenizer = SmartTokenizer('HTMLTextAreaElement')
+        self.assertEqual(tokenizer.tokenize(), ['HTML', 'Text', 'Area', 'Element'])
+
+        tokenizer = SmartTokenizer('Path2D')
+        self.assertEqual(tokenizer.tokenize(), ['Path', '2D'])
+        tokenizer = SmartTokenizer('Point2D')
+        self.assertEqual(tokenizer.tokenize(), ['Point', '2D'])
+        tokenizer = SmartTokenizer('CanvasRenderingContext2DState')
+        self.assertEqual(tokenizer.tokenize(), ['Canvas', 'Rendering', 'Context', '2D', 'State'])
+
+        tokenizer = SmartTokenizer('RTCDTMFSender')
+        self.assertEqual(tokenizer.tokenize(), ['RTC', 'DTMF', 'Sender'])
+
+        tokenizer = SmartTokenizer('WebGLCompressedTextureS3TCsRGB')
+        self.assertEqual(tokenizer.tokenize(), ['WebGL', 'Compressed', 'Texture', 'S3TC', 'sRGB'])
+        tokenizer = SmartTokenizer('WebGL2CompressedTextureETC1')
+        self.assertEqual(tokenizer.tokenize(), ['WebGL2', 'Compressed', 'Texture', 'ETC1'])
+        tokenizer = SmartTokenizer('EXTsRGB')
+        self.assertEqual(tokenizer.tokenize(), ['EXT', 'sRGB'])
+
+        tokenizer = SmartTokenizer('SVGFEBlendElement')
+        self.assertEqual(tokenizer.tokenize(), ['SVG', 'FE', 'Blend', 'Element'])
+        tokenizer = SmartTokenizer('SVGMPathElement')
+        self.assertEqual(tokenizer.tokenize(), ['SVG', 'MPath', 'Element'])
+        tokenizer = SmartTokenizer('SVGTSpanElement')
+        self.assertEqual(tokenizer.tokenize(), ['SVG', 'TSpan', 'Element'])
+        tokenizer = SmartTokenizer('SVGURIReference')
+        self.assertEqual(tokenizer.tokenize(), ['SVG', 'URI', 'Reference'])
+
+        tokenizer = SmartTokenizer('UTF16TextIterator')
+        self.assertEqual(tokenizer.tokenize(), ['UTF16', 'Text', 'Iterator'])
+        tokenizer = SmartTokenizer('UTF8Decoder')
+        self.assertEqual(tokenizer.tokenize(), ['UTF8', 'Decoder'])
+        tokenizer = SmartTokenizer('Uint8Array')
+        self.assertEqual(tokenizer.tokenize(), ['Uint8', 'Array'])
+        tokenizer = SmartTokenizer('DOMWindowBase64')
+        self.assertEqual(tokenizer.tokenize(), ['DOM', 'Window', 'Base64'])
+        tokenizer = SmartTokenizer('TextCodecLatin1')
+        self.assertEqual(tokenizer.tokenize(), ['Text', 'Codec', 'Latin1'])
+        tokenizer = SmartTokenizer('V8BindingForCore')
+        self.assertEqual(tokenizer.tokenize(), ['V8', 'Binding', 'For', 'Core'])
+        tokenizer = SmartTokenizer('V8DOMRect')
+        self.assertEqual(tokenizer.tokenize(), ['V8', 'DOM', 'Rect'])
+
+        tokenizer = SmartTokenizer('V0InsertionPoint')
+        self.assertEqual(tokenizer.tokenize(), ['V0', 'Insertion', 'Point'])
+        tokenizer = SmartTokenizer('ShadowDOMV0Test')
+        self.assertEqual(tokenizer.tokenize(), ['Shadow', 'DOM', 'V0', 'Test'])
+        tokenizer = SmartTokenizer('ElementShadowV0')
+        self.assertEqual(tokenizer.tokenize(), ['Element', 'Shadow', 'V0'])
+        tokenizer = SmartTokenizer('StubChromeClientForSPv2')
+        self.assertEqual(tokenizer.tokenize(), ['Stub', 'Chrome', 'Client', 'For', 'SPv2'])
+
+        tokenizer = SmartTokenizer('SQLiteAuthorizer')
+        self.assertEqual(tokenizer.tokenize(), ['SQLite', 'Authorizer'])
+        tokenizer = SmartTokenizer('XPathEvaluator')
+        self.assertEqual(tokenizer.tokenize(), ['XPath', 'Evaluator'])
+
+        tokenizer = SmartTokenizer('IsXHTMLDocument')
+        self.assertEqual(tokenizer.tokenize(), ['Is', 'XHTML', 'Document'])
+
+        tokenizer = SmartTokenizer('Animation.idl')
+        self.assertEqual(tokenizer.tokenize(), ['Animation', '.idl'])
+
+
+class NameStyleConverterTest(unittest.TestCase):
+    def test_snake_case(self):
+        converter = NameStyleConverter('HTMLElement')
+        self.assertEqual(converter.to_snake_case(), 'html_element')
+
+    def test_upper_camel_case(self):
+        converter = NameStyleConverter('someSuperThing')
+        self.assertEqual(converter.to_upper_camel_case(), 'SomeSuperThing')
+
+        converter = NameStyleConverter('SVGElement')
+        self.assertEqual(converter.to_upper_camel_case(), 'SVGElement')
+
+    def test_macro_case(self):
+        converter = NameStyleConverter('WebGLBaz2D')
+        self.assertEqual(converter.to_macro_case(), 'WEBGL_BAZ_2D')
+
+    def test_all_cases(self):
+        converter = NameStyleConverter('SVGScriptElement')
+        self.assertEqual(converter.to_all_cases(), {
+            'snake_case': 'svg_script_element',
+            'upper_camel_case': 'SVGScriptElement',
+            'macro_case': 'SVG_SCRIPT_ELEMENT',
+        })
--- /dev/null
+++ b/third_party/blink/tools/compile_devtools_frontend.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env vpython
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Compile DevTools frontend code with Closure compiler.
+
+This script wraps devtools/scripts/compile_frontend.py.
+DevTools bot kicks this script.
+"""
+
+import os
+import sys
+
+sys.path.append(os.path.join(
+    os.path.dirname(__file__), '..', '..', 'WebKit', 'Source', 'devtools', 'scripts'))
+import compile_frontend
+
+if __name__ == '__main__':
+    sys.exit(compile_frontend.main())
--- /dev/null
+++ b/third_party/blink/tools/move_blink_source.py
@@ -0,0 +1,615 @@
+#!/usr/bin/env vpython
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tool to move Blink source from third_party/WebKit to third_party/blink.
+
+See https://docs.google.com/document/d/1l3aPv1Wx__SpRkdOhvJz8ciEGigNT3wFKv78XiuW0Tw/edit?usp=sharing#heading=h.o225wrxp242h
+for the details.
+"""
+
+import argparse
+import logging
+import os
+import re
+import sys
+from functools import partial
+
+# Without abspath(), PathFinder can't find chromium_base correctly.
+sys.path.append(os.path.abspath(
+    os.path.join(os.path.dirname(__file__), '..', '..', '..',
+                 'third_party', 'WebKit', 'Tools', 'Scripts')))
+from blinkpy.common.name_style_converter import NameStyleConverter
+from plan_blink_move import plan_blink_move
+from plan_blink_move import relative_dest
+from webkitpy.common.checkout.git import Git
+from webkitpy.common.path_finder import get_chromium_src_dir
+from webkitpy.common.path_finder import get_scripts_dir
+from webkitpy.common.system.executive import Executive
+from webkitpy.common.system.executive import ScriptError
+from webkitpy.common.system.filesystem import FileSystem
+
+_log = logging.getLogger('move_blink_source')
+
+
+class FileType(object):
+    NONE = 0
+    BUILD = 1
+    BLINK_BUILD = 2
+    OWNERS = 3
+    DEPS = 4
+    MOJOM = 5
+    TYPEMAP = 6
+    BLINK_BUILD_PY = 7
+    LAYOUT_TESTS_WITH_MOJOM = 8
+
+    @staticmethod
+    def detect(path):
+        slash_dir, basename = os.path.split(path)
+        slash_dir = slash_dir.replace(os.path.sep, '/')
+        if basename == 'DEPS':
+            return FileType.DEPS
+        if basename == 'OWNERS':
+            return FileType.OWNERS
+        if basename.endswith('.mojom'):
+            return FileType.MOJOM
+        if basename.endswith('.typemap'):
+            return FileType.TYPEMAP
+        if basename.endswith('.py') and 'third_party/WebKit/Source/build' in slash_dir:
+            return FileType.BLINK_BUILD_PY
+        if basename.endswith(('.gn', '.gni')):
+            if 'third_party/WebKit' in path or 'third_party/blink' in slash_dir:
+                return FileType.BLINK_BUILD
+            if 'third_party' in slash_dir:
+                return FileType.NONE
+            return FileType.BUILD
+        if basename.endswith('.html') and re.search(
+                r'third_party/WebKit/LayoutTests/(geolocation-api|installedapp|' +
+                r'media/mediasession|payments|presentation|webshare)', slash_dir):
+            return FileType.LAYOUT_TESTS_WITH_MOJOM
+        return FileType.NONE
+
+
+class MoveBlinkSource(object):
+
+    def __init__(self, fs, options, repo_root):
+        self._fs = fs
+        self._options = options
+        _log.debug(options)
+        self._repo_root = repo_root
+
+        # The following fields are initialized in _create_basename_maps.
+        self._basename_map = None
+        self._basename_re = None
+        self._idl_generated_impl_headers = None
+        # _checked_in_header_re is used to distinguish checked-in header files
+        # and generated header files.
+        self._checked_in_header_re = None
+
+        self._updated_files = []
+
+    def update(self, apply_only=None):
+        """Updates contents of files affected by Blink source move.
+
+        Args:
+            apply_only: If it's None, updates all affected files. Otherwise,
+                it should be a set of file paths and this function updates
+                only the files in |apply_only|.
+        """
+        _log.info('Planning renaming ...')
+        file_pairs = plan_blink_move(self._fs, [])
+        _log.info('Will move %d files', len(file_pairs))
+
+        self._create_basename_maps(file_pairs)
+        dirs = self._update_file_content(apply_only)
+
+        # Updates #includes in files in directories with updated DEPS +
+        # third_party/WebKit/{Source,common,public}.
+        self._append_unless_upper_dir_exists(dirs, self._fs.join(self._repo_root, 'third_party', 'WebKit', 'Source'))
+        self._append_unless_upper_dir_exists(dirs, self._fs.join(self._repo_root, 'third_party', 'WebKit', 'common'))
+        self._append_unless_upper_dir_exists(dirs, self._fs.join(self._repo_root, 'third_party', 'WebKit', 'public'))
+        self._append_unless_upper_dir_exists(dirs, self._fs.join(self._repo_root, 'mojo', 'public', 'tools',
+                                                                 'bindings', 'generators', 'cpp_templates'))
+        self._update_cpp_includes_in_directories(dirs, apply_only)
+
+        # Content update for individual files.
+        # The following is a list of tuples.
+        #  Tuple: (<file path relative to repo root>, [replacement commands])
+        #  Command: a callable object, or
+        #           a tuple of (<original string>, <new string>).
+        file_replacement_list = [
+            ('DEPS',
+             [('src/third_party/WebKit/Source/devtools',
+               'src/third_party/blink/renderer/devtools')]),
+            ('WATCHLISTS',
+             [('third_party/WebKit/Source', 'third_party/blink/renderer'),
+              ('third_party/WebKit/public', 'third_party/blink/renderer/public')]),
+            ('build/check_gn_headers_whitelist.txt',
+             [('third_party/WebKit/Source', 'third_party/blink/renderer'),
+              ('third_party/WebKit/public', 'third_party/blink/renderer/public'),
+              self._update_basename]),
+            ('testing/buildbot/gn_isolate_map.pyl',
+             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
+            ('third_party/WebKit/Source/BUILD.gn',
+             [('$root_gen_dir/third_party/WebKit',
+               '$root_gen_dir/third_party/blink/renderer')]),
+            ('third_party/WebKit/Source/config.gni',
+             [('snake_case_source_files = false',
+               'snake_case_source_files = true')]),
+            ('third_party/WebKit/Source/core/css/CSSProperties.json5',
+             [self._update_basename]),
+            ('third_party/WebKit/Source/core/css/ComputedStyleExtraFields.json5',
+             [self._update_basename]),
+            ('third_party/WebKit/Source/core/css/ComputedStyleFieldAliases.json5',
+             [self._update_basename]),
+            ('third_party/WebKit/Source/core/html/parser/create-html-entity-table',
+             [self._update_basename]),
+            ('third_party/WebKit/Source/core/inspector/inspector_protocol_config.json',
+             [self._update_basename]),
+            ('third_party/WebKit/Source/core/probe/CoreProbes.json5',
+             [self._update_basename]),
+            ('third_party/WebKit/Source/core/testing/InternalSettings.h',
+             [('InternalSettingsGenerated.h', 'internal_settings_generated.h')]),
+            ('third_party/WebKit/Source/core/testing/Internals.cpp',
+             [('InternalRuntimeFlags.h', 'internal_runtime_flags.h')]),
+            ('third_party/WebKit/Source/platform/probe/PlatformProbes.json5',
+             [self._update_basename]),
+            ('third_party/WebKit/public/BUILD.gn',
+             [('$root_gen_dir/third_party/WebKit',
+               '$root_gen_dir/third_party/blink/renderer')]),
+            ('third_party/WebKit/public/blink_resources.grd',
+             [('../Source/', '../')]),
+            ('tools/android/eclipse/.classpath',
+             [('third_party/WebKit/public', 'third_party/blink/renderer/public')]),
+            ('tools/android/loading/cloud/backend/deploy.sh',
+             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
+            ('tools/android/loading/emulation_unittest.py',
+             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
+            ('tools/android/loading/options.py',
+             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
+            ('tools/android/loading/request_track.py',
+             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
+            ('tools/gritsettings/resource_ids',
+             [('third_party/WebKit/public', 'third_party/blink/renderer/public'),
+              ('third_party/WebKit/Source', 'third_party/blink/renderer')]),
+            ('tools/metrics/actions/extract_actions.py',
+             [('third_party/WebKit/Source', 'third_party/blink/renderer')]),
+            ('tools/metrics/histograms/update_editor_commands.py',
+             [('third_party/WebKit/Source/core/editing/EditorCommand.cpp',
+               'third_party/blink/renderer/core/editing/editor_command.cc')]),
+            ('tools/metrics/histograms/update_use_counter_css.py',
+             [('third_party/WebKit/Source/core/frame/UseCounter.cpp',
+               'third_party/blink/renderer/core/frame/use_counter.cc')]),
+            ('tools/metrics/histograms/update_use_counter_feature_enum.py',
+             [('third_party/WebKit/public', 'third_party/blink/renderer/public')]),
+        ]
+        for file_path, replacement_list in file_replacement_list:
+            if not apply_only or file_path in apply_only:
+                self._update_single_file_content(file_path, replacement_list, should_write=self._options.run)
+
+        if self._options.run:
+            _log.info('Formatting updated %d files ...', len(self._updated_files))
+            git = Git(cwd=self._repo_root)
+            # |git cl format| can't handle too many files at once.
+            while len(self._updated_files) > 0:
+                end_index = 100
+                if end_index > len(self._updated_files):
+                    end_index = len(self._updated_files)
+                git.run(['cl', 'format'] + self._updated_files[:end_index])
+                self._updated_files = self._updated_files[end_index:]
+
+            if not apply_only:
+                _log.info('Make a local commit ...')
+                git.commit_locally_with_message("""The Great Blink mv for source files, part 1.
+
+Update file contents without moving files.
+
+NOAUTOREVERT=true
+Bug: 768828
+""")
+
+    def move(self, apply_only=None):
+        """Move Blink source files.
+
+        Args:
+            apply_only: If it's None, move all affected files. Otherwise,
+                it should be a set of file paths and this function moves
+                only the files in |apply_only|.
+        """
+        _log.info('Planning renaming ...')
+        file_pairs = plan_blink_move(self._fs, [])
+
+        if apply_only:
+            file_pairs = [(src, dest) for (src, dest) in file_pairs
+                          if 'third_party/WebKit/' + src.replace('\\', '/') in apply_only]
+            print 'Update file_pairs = ', file_pairs
+        _log.info('Will move %d files', len(file_pairs))
+
+        git = Git(cwd=self._repo_root)
+        files_set = self._get_checked_in_files(git)
+        for i, (src, dest) in enumerate(file_pairs):
+            src_from_repo = self._fs.join('third_party', 'WebKit', src)
+            if src_from_repo.replace('\\', '/') not in files_set:
+                _log.info('%s is not in the repository', src)
+                continue
+            dest_from_repo = self._fs.join('third_party', 'blink', dest)
+            self._fs.maybe_make_directory(self._repo_root, 'third_party', 'blink', self._fs.dirname(dest))
+            if self._options.run_git:
+                git.move(src_from_repo, dest_from_repo)
+                _log.info('[%d/%d] Git moved %s', i + 1, len(file_pairs), src)
+            else:
+                self._fs.move(self._fs.join(self._repo_root, src_from_repo),
+                              self._fs.join(self._repo_root, dest_from_repo))
+                _log.info('[%d/%d] Moved %s', i + 1, len(file_pairs), src)
+        if apply_only:
+            return
+
+        self._update_single_file_content(
+            'build/get_landmines.py',
+            [('\ndef main', '  print \'The Great Blink mv for source files (crbug.com/768828)\'\n\ndef main')])
+
+        _log.info('Run run-bindings-tests ...')
+        Executive().run_command(['python',
+                                 self._fs.join(get_scripts_dir(), 'run-bindings-tests'),
+                                 '--reset-results'],
+                                cwd=self._repo_root)
+
+        if self._options.run_git:
+            _log.info('Make a local commit ...')
+            git.commit_locally_with_message("""The Great Blink mv for source files, part 2.
+
+Move and rename files.
+
+NOAUTOREVERT=true
+Bug: 768828
+""")
+
+    def fix_branch(self):
+        git = Git(cwd=self._repo_root)
+        status = self._get_local_change_status(git)
+        if len(status) == 0:
+            _log.info('No local changes.')
+            return
+        modified_files = {f for (s, f) in status if s != 'D'}
+        deleted_files = {f for (s, f) in status if s == 'D'}
+
+        self.update(apply_only=modified_files)
+        self.move(apply_only=modified_files)
+        try:
+            git.commit_locally_with_message('This commit should be squashed.')
+        except ScriptError:
+            _log.info('move_blink_source.py modified nothing.')
+
+        # TODO(tkent): Show a message about deleted_files.
+
+    def _get_local_change_status(self, git):
+        """Returns a list of tuples representing local change summary.
+
+        Each tuple contains two strings. The first one is file change status
+        such as "M", "D".  See --diff-filter section of git-diff manual page.
+        The second one is file name relative to the repository top.
+        """
+
+        base_commit = git.run(['show-branch', '--merge-base', 'master', 'HEAD']).strip()
+        # Note that file names in the following command result are always
+        # slash-separated, even on Windows.
+        status_lines = git.run(['diff', '--name-status', '--no-renames', base_commit]).split('\n')
+        status_tuple_list = []
+        for l in status_lines:
+            items = l.split('\t')
+            if len(items) == 2:
+                status_tuple_list.append(tuple(items))
+            elif len(l) > 0:
+                _log.warning('Unrecognized diff output: "%s"', l)
+        return status_tuple_list
+
+    def _get_checked_in_files(self, git):
+        files_text = git.run(['ls-files',
+                              'third_party/WebKit/Source',
+                              'third_party/WebKit/common',
+                              'third_party/WebKit/public'])
+        return set(files_text.split('\n'))
+
+    def _create_basename_maps(self, file_pairs):
+        basename_map = {}
+        # Generated inspector/protocol/* contains a lot of names duplicated with
+        # checked-in core files. We don't want to rename them, and don't want to
+        # replace them in BUILD.gn and #include accidentally.
+        pattern = r'(?<!inspector/protocol/)\b('
+        idl_headers = set()
+        header_pattern = r'(?<!inspector/protocol/)\b('
+        for source, dest in file_pairs:
+            _, source_base = self._fs.split(source)
+            _, dest_base = self._fs.split(dest)
+            # OriginTrialFeaturesForCore.h in bindings/tests/results/modules/
+            # confuses generated/checked-in detection in _replace_include_path().
+            if 'bindings/tests' in source.replace('\\', '/'):
+                continue
+            if source_base.endswith('.h'):
+                header_pattern += re.escape(source_base) + '|'
+            if source_base == dest_base:
+                continue
+            basename_map[source_base] = dest_base
+            pattern += re.escape(source_base) + '|'
+            # IDL sometimes generates implementation files as well as
+            # binding files. We'd like to update #includes for such files.
+            if source_base.endswith('.idl'):
+                source_header = source_base.replace('.idl', '.h')
+                basename_map[source_header] = dest_base.replace('.idl', '.h')
+                pattern += re.escape(source_header) + '|'
+                idl_headers.add(source_header)
+        _log.info('Rename %d files for snake_case', len(basename_map))
+        self._basename_map = basename_map
+        self._basename_re = re.compile(pattern[0:len(pattern) - 1] + ')(?=["\']|$)')
+        self._idl_generated_impl_headers = idl_headers
+        self._checked_in_header_re = re.compile(header_pattern[0:len(header_pattern) - 1] + ')$')
+
+    def _shorten_path(self, path):
+        if path.startswith(self._repo_root):
+            return path[len(self._repo_root) + 1:]
+        return path
+
+    @staticmethod
+    def _filter_file(fs, dirname, basename):
+        return FileType.detect(fs.join(dirname, basename)) != FileType.NONE
+
+    def _update_build(self, content):
+        content = content.replace('//third_party/WebKit/Source', '//third_party/blink/renderer')
+        content = content.replace('//third_party/WebKit/common', '//third_party/blink/common')
+        content = content.replace('//third_party/WebKit/public', '//third_party/blink/renderer/public')
+        # export_header_blink exists outside of Blink too.
+        content = content.replace('export_header_blink = "third_party/WebKit/public/platform/WebCommon.h"',
+                                  'export_header_blink = "third_party/blink/renderer/public/platform/web_common.h"')
+        return content
+
+    def _update_blink_build(self, content):
+        content = self._update_build(content)
+
+        # Update visibility=[...]
+        content = content.replace('//third_party/WebKit/*', '//third_party/blink/*')
+        content = content.replace('//third_party/WebKit/Source/*', '//third_party/blink/renderer/*')
+        content = content.replace('//third_party/WebKit/public/*', '//third_party/blink/renderer/public/*')
+
+        # Update mojom variables
+        content = content.replace('export_header = "third_party/WebKit/common',
+                                  'export_header = "third_party/blink/common')
+        content = content.replace('export_header_blink = "third_party/WebKit/Source',
+                                  'export_header_blink = "third_party/blink/renderer')
+        return self._update_basename(content)
+
+    def _update_owners(self, content):
+        content = content.replace('//third_party/WebKit/Source', '//third_party/blink/renderer')
+        content = content.replace('//third_party/WebKit/common', '//third_party/blink/common')
+        content = content.replace('//third_party/WebKit/public', '//third_party/blink/renderer/public')
+        return content
+
+    def _update_deps(self, content):
+        original_content = content
+        content = content.replace('third_party/WebKit/Source', 'third_party/blink/renderer')
+        content = content.replace('third_party/WebKit/common', 'third_party/blink/common')
+        content = content.replace('third_party/WebKit/public', 'third_party/blink/renderer/public')
+        content = content.replace('third_party/WebKit', 'third_party/blink')
+        if original_content == content:
+            return content
+        return self._update_basename(content)
+
+    def _update_mojom(self, content):
+        content = content.replace('third_party/WebKit/public', 'third_party/blink/renderer/public')
+        content = content.replace('third_party/WebKit/common', 'third_party/blink/common')
+        return content
+
+    def _update_typemap(self, content):
+        content = content.replace('//third_party/WebKit/Source', '//third_party/blink/renderer')
+        content = content.replace('//third_party/WebKit/common', '//third_party/blink/common')
+        content = content.replace('//third_party/WebKit/public', '//third_party/blink/renderer/public')
+        return self._update_basename(content)
+
+    def _update_blink_build_py(self, content):
+        # We don't prepend 'third_party/blink/renderer/' to matched basenames
+        # because it won't affect build and manual update after the great mv is
+        # enough.
+        return self._update_basename(content)
+
+    def _update_layout_tests(self, content):
+        return content.replace('file:///gen/third_party/WebKit/', 'file:///gen/third_party/blink/renderer/')
+
+    def _update_basename(self, content):
+        return self._basename_re.sub(lambda match: self._basename_map[match.group(1)], content)
+
+    @staticmethod
+    def _append_unless_upper_dir_exists(dirs, new_dir):
+        for i in range(0, len(dirs)):
+            if new_dir.startswith(dirs[i]):
+                return
+            if dirs[i].startswith(new_dir):
+                dirs[i] = new_dir
+                return
+        dirs.append(new_dir)
+
+    def _update_file_content(self, apply_only):
+        _log.info('Find *.gn, *.mojom, *.py, *.typemap, DEPS, and OWNERS ...')
+        files = self._fs.files_under(
+            self._repo_root, dirs_to_skip=['.git', 'out'], file_filter=self._filter_file)
+        _log.info('Scan contents of %d files ...', len(files))
+        updated_deps_dirs = []
+        for file_path in files:
+            file_type = FileType.detect(file_path)
+            original_content = self._fs.read_text_file(file_path)
+            content = original_content
+            if file_type == FileType.BUILD:
+                content = self._update_build(content)
+            elif file_type == FileType.BLINK_BUILD:
+                content = self._update_blink_build(content)
+            elif file_type == FileType.OWNERS:
+                content = self._update_owners(content)
+            elif file_type == FileType.DEPS:
+                if self._fs.dirname(file_path) == self._repo_root:
+                    _log.info("Skip //DEPS")
+                    continue
+                content = self._update_deps(content)
+            elif file_type == FileType.MOJOM:
+                content = self._update_mojom(content)
+            elif file_type == FileType.TYPEMAP:
+                content = self._update_typemap(content)
+            elif file_type == FileType.BLINK_BUILD_PY:
+                content = self._update_blink_build_py(content)
+            elif file_type == FileType.LAYOUT_TESTS_WITH_MOJOM:
+                content = self._update_layout_tests(content)
+
+            if original_content == content:
+                continue
+            if self._options.run and (not apply_only or file_path.replace('\\', '/') in apply_only):
+                self._fs.write_text_file(file_path, content)
+                self._updated_files.append(file_path)
+            if file_type == FileType.DEPS:
+                self._append_unless_upper_dir_exists(updated_deps_dirs, self._fs.dirname(file_path))
+            _log.info('Updated %s', self._shorten_path(file_path))
+        return updated_deps_dirs
+
+    def _update_cpp_includes_in_directories(self, dirs, apply_only):
+        for dirname in dirs:
+            _log.info('Processing #include in %s ...', self._shorten_path(dirname))
+            files = self._fs.files_under(
+                dirname, file_filter=lambda fs, _, basename: basename.endswith(
+                    ('.h', '.cc', '.cpp', '.mm', '.cc.tmpl', '.cpp.tmpl',
+                     '.h.tmpl', 'XPathGrammar.y', '.gperf')))
+            for file_path in files:
+                posix_file_path = file_path.replace('\\', '/')
+                original_content = self._fs.read_text_file(file_path)
+
+                content = self._update_cpp_includes(original_content)
+                if file_path.endswith('.h') and '/third_party/WebKit/public/' in posix_file_path:
+                    content = self._update_basename_only_includes(content, file_path)
+                if file_path.endswith('.h') and '/third_party/WebKit/' in posix_file_path:
+                    content = self._update_include_guard(content, file_path)
+
+                if original_content == content:
+                    continue
+                if self._options.run and (not apply_only or posix_file_path in apply_only):
+                    self._fs.write_text_file(file_path, content)
+                    self._updated_files.append(file_path)
+                _log.info('Updated %s', self._shorten_path(file_path))
+
+    def _replace_include_path(self, match):
+        include_or_import = match.group(1)
+        path = match.group(2)
+
+        # If |path| starts with 'third_party/WebKit', we should adjust the
+        # directory name for third_party/blink, and replace its basename by
+        # self._basename_map.
+        #
+        # If |path| starts with a Blink-internal directory such as bindings,
+        # core, modules, platform, public, it refers to a checked-in file, or a
+        # generated file. For the former, we should add
+        # 'third_party/blink/renderer/' and replace the basename.  For the
+        # latter, we should update the basename for a name mapped from an IDL
+        # renaming, and should not add 'third_party/blink/renderer'.
+
+        if path.startswith('third_party/WebKit'):
+            path = path.replace('third_party/WebKit/Source', 'third_party/blink/renderer')
+            path = path.replace('third_party/WebKit/common', 'third_party/blink/common')
+            path = path.replace('third_party/WebKit/public', 'third_party/blink/renderer/public')
+            path = self._update_basename(path)
+            return '#%s "%s"' % (include_or_import, path)
+
+        match = self._checked_in_header_re.search(path)
+        if match:
+            if match.group(1) in self._basename_map:
+                path = 'third_party/blink/renderer/' + path[:match.start(1)] + self._basename_map[match.group(1)]
+            else:
+                path = 'third_party/blink/renderer/' + path
+        elif 'core/inspector/protocol/' not in path:
+            basename_start = path.rfind('/') + 1
+            basename = path[basename_start:]
+            if basename in self._idl_generated_impl_headers:
+                path = path[:basename_start] + self._basename_map[basename]
+            elif basename.startswith('V8'):
+                path = path[:basename_start] + NameStyleConverter(basename[:len(basename) - 2]).to_snake_case() + '.h'
+        return '#%s "%s"' % (include_or_import, path)
+
+    def _update_cpp_includes(self, content):
+        pattern = re.compile(r'#(include|import)\s+"((bindings|core|modules|platform|public|' +
+                             r'third_party/WebKit/(Source|common|public))/[-_\w/.]+)"')
+        return pattern.sub(self._replace_include_path, content)
+
+    def _replace_basename_only_include(self, subdir, source_path, match):
+        source_basename = match.group(1)
+        if source_basename in self._basename_map:
+            return '#include "third_party/blink/renderer/public/%s/%s"' % (subdir, self._basename_map[source_basename])
+        _log.warning('Basename-only %s in %s', match.group(0), self._shorten_path(source_path))
+        return match.group(0)
+
+    def _update_basename_only_includes(self, content, source_path):
+        if not source_path.endswith('.h') or '/third_party/WebKit/public/' not in source_path.replace('\\', '/'):
+            return
+        # In public/ header files, we should replace |#include "WebFoo.h"|
+        # with |#include "third_party/blink/renderer/public/platform-or-web/web_foo.h"|
+        subdir = self._fs.basename(self._fs.dirname(source_path))
+        # subdir is 'web' or 'platform'.
+        return re.sub(r'#include\s+"(\w+\.h)"',
+                      partial(self._replace_basename_only_include, subdir, source_path), content)
+
+    def _update_include_guard(self, content, source_path):
+        current_guard = re.sub(r'[.]', '_', self._fs.basename(source_path))
+        new_path = relative_dest(self._fs, self._fs.relpath(
+            source_path, start=self._fs.join(self._repo_root, 'third_party', 'WebKit')))
+        new_guard = 'THIRD_PARTY_BLINK_' + re.sub(r'[\\/.]', '_', new_path.upper()) + '_'
+        content = re.sub(r'#ifndef\s+(WTF_)?' + current_guard, '#ifndef ' + new_guard, content);
+        content = re.sub(r'#define\s+(WTF_)?' + current_guard, '#define ' + new_guard, content);
+        content = re.sub(r'#endif\s+//\s+(WTF_)?' + current_guard, '#endif  // ' + new_guard, content);
+        return content
+
+    def _update_single_file_content(self, file_path, replace_list, should_write=True):
+        full_path = self._fs.join(self._repo_root, file_path)
+        original_content = self._fs.read_text_file(full_path)
+        content = original_content
+        for command in replace_list:
+            if isinstance(command, tuple):
+                src, dest = command
+                content = content.replace(src, dest)
+            elif callable(command):
+                content = command(content)
+            else:
+                raise TypeError('A tuple or a function is expected.')
+        if content != original_content:
+            if should_write:
+                self._fs.write_text_file(full_path, content)
+                self._updated_files.append(full_path)
+            _log.info('Updated %s', file_path)
+        else:
+            _log.warning('%s does not contain specified source strings.', file_path)
+
+
+def main():
+    logging.basicConfig(level=logging.DEBUG,
+                        format='[%(asctime)s %(levelname)s %(name)s] %(message)s',
+                        datefmt='%H:%M:%S')
+    parser = argparse.ArgumentParser(description='Blink source mover')
+    sub_parsers = parser.add_subparsers()
+
+    update_parser = sub_parsers.add_parser('update')
+    update_parser.set_defaults(command='update')
+    update_parser.add_argument('--run', dest='run', action='store_true',
+                               help='Update file contents')
+
+    move_parser = sub_parsers.add_parser('move')
+    move_parser.set_defaults(command='move')
+    move_parser.add_argument('--git', dest='run_git', action='store_true',
+                             help='Run |git mv| command instead of |mv|.')
+
+    fixbranch_parser = sub_parsers.add_parser('fixbranch')
+    fixbranch_parser.set_defaults(command='fixbranch', run=True, run_git=True)
+
+    options = parser.parse_args()
+    mover = MoveBlinkSource(FileSystem(), options, get_chromium_src_dir())
+    if options.command == 'update':
+        mover.update()
+    elif options.command == 'move':
+        mover.move()
+    elif options.command == 'fixbranch':
+        mover.fix_branch()
+
+
+if __name__ == '__main__':
+    main()
--- /dev/null
+++ b/third_party/blink/tools/plan_blink_move.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env vpython
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import re
+import sys
+
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..',
+                             'third_party', 'WebKit', 'Tools', 'Scripts'))
+from blinkpy.common.name_style_converter import NameStyleConverter
+from webkitpy.common.system.filesystem import FileSystem
+
+
+def relative_dest(fs, filename):
+    """Returns a destination path string for given filename.
+
+    |filename| is a path relative to third_party/WebKit, and the resultant path
+    is relative to third_party/blink.
+    """
+    dest = None
+    if filename.startswith('public'):
+        dest = re.sub(r'^public', 'renderer' + fs.sep + 'public', filename)
+    elif filename.startswith('Source'):
+        dest = re.sub(r'^Source', 'renderer', filename)
+    elif filename.startswith('common'):
+        dest = filename
+    else:
+        raise ValueError('|filename| must start with "common", "public", or "Source": %s' % filename)
+    if filename.endswith(('.h', '.cpp', '.mm', '.idl', '.typemap', 'Settings.json5')):
+        dirname, basename = fs.split(dest)
+        basename, ext = fs.splitext(basename)
+        # Skip some inspector-related files. #includes for these files are
+        # generated by a script outside of Blink.
+        if (re.match(r'Inspector.*Agent', basename)
+                or basename == 'InspectorTraceEvents'
+                or basename == 'PerformanceMonitor'
+                or basename == 'PlatformTraceEventsAgent'):
+            return dest
+        # Skip CSSProperty*. Some files are generated, and some files are
+        # checked-in. It's hard to handle them automatically.
+        if re.search(r'css[\\/]properties$', dirname):
+            return dest
+        if filename.endswith('.cpp'):
+            ext = '.cc'
+        # WebKit.h should be renamed to blink.h.
+        if basename == 'WebKit' and ext == '.h':
+            basename = 'blink'
+        if basename.lower() != basename:
+            basename = NameStyleConverter(basename).to_snake_case()
+        return fs.join(dirname, basename + ext)
+    return dest
+
+
+def start_with_list(name, prefixes):
+    if len(prefixes) == 0:
+        return True
+    for prefix in prefixes:
+        if name.startswith(prefix):
+            return True
+    return False
+
+
+def plan_blink_move(fs, prefixes):
+    """Returns (source, dest) path pairs.
+
+    The source paths are relative to third_party/WebKit,
+    and the dest paths are relative to third_party/blink.
+    The paths use os.sep as the path part separator.
+    """
+    blink_dir = fs.join(fs.dirname(__file__), '..')
+    webkit_dir = fs.join(blink_dir, '..', '..', 'third_party', 'WebKit')
+    source_files = fs.files_under(fs.join(webkit_dir, 'Source'))
+    source_files += fs.files_under(fs.join(webkit_dir, 'common'))
+    source_files += fs.files_under(fs.join(webkit_dir, 'public'))
+
+    # It's possible to check git.exists() here, but we don't do it due to slow
+    # performance. We should check it just before executing git command.
+
+    source_files = [f[len(webkit_dir) + 1:] for f in source_files]
+    return [(f, relative_dest(fs, f)) for f in source_files
+            if f.find('node_modules') == -1 and start_with_list(f, prefixes)]
+
+
+def main():
+    fs = FileSystem()
+    file_pairs = plan_blink_move(fs, sys.argv[1:])
+    print 'Show renaming plan. It contains files not in the repository.'
+    print '<Source path relative to third_party/WebKit> => <Destination path relative to third_party/blink>'
+    for pair in file_pairs:
+        print '%s\t=>\t%s' % pair
+
+
+if __name__ == '__main__':
+    main()
openSUSE Build Service is sponsored by