| /** |
| * @license |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| import {SpecialFilePath, FileInfoStatus} from '../constants/constants'; |
| import {FileInfo} from '../types/common'; |
| import {hasOwnProperty} from './common-util'; |
| |
| export function specialFilePathCompare(a: string, b: string) { |
| // The commit message always goes first. |
| if (a === SpecialFilePath.COMMIT_MESSAGE) { |
| return -1; |
| } |
| if (b === SpecialFilePath.COMMIT_MESSAGE) { |
| return 1; |
| } |
| |
| // The merge list always comes next. |
| if (a === SpecialFilePath.MERGE_LIST) { |
| return -1; |
| } |
| if (b === SpecialFilePath.MERGE_LIST) { |
| return 1; |
| } |
| |
| const aLastDotIndex = a.lastIndexOf('.'); |
| const aExt = a.substr(aLastDotIndex + 1); |
| const aFile = a.substr(0, aLastDotIndex) || a; |
| |
| const bLastDotIndex = b.lastIndexOf('.'); |
| const bExt = b.substr(bLastDotIndex + 1); |
| const bFile = b.substr(0, bLastDotIndex) || b; |
| |
| // Sort header files above others with the same base name. |
| const headerExts = ['h', 'hh', 'hxx', 'hpp']; |
| if (aFile.length > 0 && aFile === bFile) { |
| if (headerExts.includes(aExt) && headerExts.includes(bExt)) { |
| return a.localeCompare(b); |
| } |
| if (headerExts.includes(aExt)) { |
| return -1; |
| } |
| if (headerExts.includes(bExt)) { |
| return 1; |
| } |
| } |
| return aFile.localeCompare(bFile) || a.localeCompare(b); |
| } |
| |
| export function shouldHideFile(file: string) { |
| return file === SpecialFilePath.PATCHSET_LEVEL_COMMENTS; |
| } |
| |
| // In case there are files with comments on them but they are unchanged, then |
| // we explicitly displays the file to render the comments with Unchanged status |
| export function addUnmodifiedFiles( |
| files: {[filename: string]: FileInfo}, |
| commentedPaths: {[fileName: string]: boolean} |
| ) { |
| if (!commentedPaths) return; |
| Object.keys(commentedPaths).forEach(commentedPath => { |
| if (hasOwnProperty(files, commentedPath) || shouldHideFile(commentedPath)) { |
| return; |
| } |
| |
| // if file is Renamed but has comments, then do not show the entry for the |
| // old file path name |
| if ( |
| Object.values(files).some( |
| file => |
| file.status === FileInfoStatus.RENAMED && |
| file.old_path === commentedPath |
| ) |
| ) { |
| return; |
| } |
| // TODO(TS): either change FileInfo to mark delta and size optional |
| // or fill in 0 here |
| files[commentedPath] = { |
| status: FileInfoStatus.UNMODIFIED, |
| } as FileInfo; |
| }); |
| } |
| |
| export function computeDisplayPath(path?: string) { |
| if (path === SpecialFilePath.COMMIT_MESSAGE) { |
| return 'Commit message'; |
| } else if (path === SpecialFilePath.MERGE_LIST) { |
| return 'Merge list'; |
| } |
| return path ?? ''; |
| } |
| |
| export function isMagicPath(path?: string) { |
| return ( |
| !!path && |
| (path === SpecialFilePath.COMMIT_MESSAGE || |
| path === SpecialFilePath.MERGE_LIST) |
| ); |
| } |
| |
| export function computeTruncatedPath(path: string) { |
| return truncatePath(computeDisplayPath(path)); |
| } |
| |
| /** |
| * Truncates URLs to display filename only |
| * Example |
| * // returns '.../text.html' |
| * util.truncatePath.('dir/text.html'); |
| * Example |
| * // returns 'text.html' |
| * util.truncatePath.('text.html'); |
| * |
| */ |
| export function truncatePath(path: string, threshold = 1) { |
| const pathPieces = path.split('/'); |
| |
| if (pathPieces.length <= threshold) { |
| return path; |
| } |
| |
| const index = pathPieces.length - threshold; |
| // Character is an ellipsis. |
| return `\u2026/${pathPieces.slice(index).join('/')}`; |
| } |