Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: Source/core/html/track/vtt/VTTCue.cpp

Issue 134153002: Use VTTScanner for VTT cue settings parsing (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/html/track/vtt/VTTCue.h ('k') | Source/core/html/track/vtt/VTTScanner.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013, Opera Software ASA. All rights reserved. 2 * Copyright (c) 2013, Opera Software ASA. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 26 matching lines...) Expand all
37 #include "bindings/v8/ExceptionStatePlaceholder.h" 37 #include "bindings/v8/ExceptionStatePlaceholder.h"
38 #include "core/dom/DocumentFragment.h" 38 #include "core/dom/DocumentFragment.h"
39 #include "core/dom/NodeTraversal.h" 39 #include "core/dom/NodeTraversal.h"
40 #include "core/events/Event.h" 40 #include "core/events/Event.h"
41 #include "core/html/HTMLDivElement.h" 41 #include "core/html/HTMLDivElement.h"
42 #include "core/html/track/TextTrack.h" 42 #include "core/html/track/TextTrack.h"
43 #include "core/html/track/TextTrackCueList.h" 43 #include "core/html/track/TextTrackCueList.h"
44 #include "core/html/track/vtt/VTTElement.h" 44 #include "core/html/track/vtt/VTTElement.h"
45 #include "core/html/track/vtt/VTTParser.h" 45 #include "core/html/track/vtt/VTTParser.h"
46 #include "core/html/track/vtt/VTTRegionList.h" 46 #include "core/html/track/vtt/VTTRegionList.h"
47 #include "core/html/track/vtt/VTTScanner.h"
47 #include "core/rendering/RenderVTTCue.h" 48 #include "core/rendering/RenderVTTCue.h"
48 #include "platform/text/BidiResolver.h" 49 #include "platform/text/BidiResolver.h"
49 #include "platform/text/TextRunIterator.h" 50 #include "platform/text/TextRunIterator.h"
50 #include "wtf/MathExtras.h" 51 #include "wtf/MathExtras.h"
51 #include "wtf/text/StringBuilder.h" 52 #include "wtf/text/StringBuilder.h"
52 53
53 namespace WebCore { 54 namespace WebCore {
54 55
55 static const int undefinedPosition = -1; 56 static const int undefinedPosition = -1;
56 57
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 coordinates.second = m_textPosition; 827 coordinates.second = m_textPosition;
827 828
828 return coordinates; 829 return coordinates;
829 } 830 }
830 831
831 ASSERT_NOT_REACHED(); 832 ASSERT_NOT_REACHED();
832 833
833 return coordinates; 834 return coordinates;
834 } 835 }
835 836
836 VTTCue::CueSetting VTTCue::settingName(const String& name) 837 VTTCue::CueSetting VTTCue::settingName(VTTScanner& input)
837 { 838 {
838 DEFINE_STATIC_LOCAL(const String, verticalKeyword, ("vertical")); 839 CueSetting parsedSetting = None;
839 DEFINE_STATIC_LOCAL(const String, lineKeyword, ("line")); 840 if (input.scan("vertical"))
840 DEFINE_STATIC_LOCAL(const String, positionKeyword, ("position")); 841 parsedSetting = Vertical;
841 DEFINE_STATIC_LOCAL(const String, sizeKeyword, ("size")); 842 else if (input.scan("line"))
842 DEFINE_STATIC_LOCAL(const String, alignKeyword, ("align")); 843 parsedSetting = Line;
843 DEFINE_STATIC_LOCAL(const String, regionIdKeyword, ("region")); 844 else if (input.scan("position"))
844 845 parsedSetting = Position;
845 if (name == verticalKeyword) 846 else if (input.scan("size"))
846 return Vertical; 847 parsedSetting = Size;
847 if (name == lineKeyword) 848 else if (input.scan("align"))
848 return Line; 849 parsedSetting = Align;
849 if (name == positionKeyword) 850 else if (RuntimeEnabledFeatures::webVTTRegionsEnabled() && input.scan("regio n"))
850 return Position; 851 parsedSetting = RegionId;
851 if (name == sizeKeyword) 852 // Verify that a ':' follows.
852 return Size; 853 if (parsedSetting != None && input.scan(':'))
853 if (name == alignKeyword) 854 return parsedSetting;
854 return Align;
855 if (RuntimeEnabledFeatures::webVTTRegionsEnabled() && name == regionIdKeywor d)
856 return RegionId;
857
858 return None; 855 return None;
859 } 856 }
860 857
861 // Used for 'position' and 'size'. 858 // Used for 'position' and 'size'.
862 static bool scanPercentage(const String& input, unsigned* position, int& number) 859 static bool scanPercentage(VTTScanner& input, const VTTScanner::Run& valueRun, i nt& number)
863 { 860 {
864 ASSERT(position);
865 // 1. If value contains any characters other than U+0025 PERCENT SIGN 861 // 1. If value contains any characters other than U+0025 PERCENT SIGN
866 // characters (%) and characters in the range U+0030 DIGIT ZERO (0) to 862 // characters (%) and characters in the range U+0030 DIGIT ZERO (0) to
867 // U+0039 DIGIT NINE (9), then jump to the step labeled next setting. 863 // U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
868 // 2. If value does not contain at least one character in the range U+0030 864 // 2. If value does not contain at least one character in the range U+0030
869 // DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step 865 // DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step
870 // labeled next setting. 866 // labeled next setting.
871 if (!VTTParser::collectDigitsToInt(input, position, number)) 867 if (!input.scanDigits(number))
872 return false;
873 if (*position >= input.length())
874 return false; 868 return false;
875 869
876 // 3. If any character in value other than the last character is a U+0025 870 // 3. If any character in value other than the last character is a U+0025
877 // PERCENT SIGN character (%), then jump to the step labeled next 871 // PERCENT SIGN character (%), then jump to the step labeled next
878 // setting. 872 // setting.
879 // 4. If the last character in value is not a U+0025 PERCENT SIGN character 873 // 4. If the last character in value is not a U+0025 PERCENT SIGN character
880 // (%), then jump to the step labeled next setting. 874 // (%), then jump to the step labeled next setting.
881 if (input[(*position)++] != '%') 875 if (!input.scan('%') || !input.isAt(valueRun.end()))
882 return false;
883 if (*position < input.length() && !VTTParser::isValidSettingDelimiter(input[ *position]))
884 return false; 876 return false;
885 877
886 // 5. Ignoring the trailing percent sign, interpret value as an integer, 878 // 5. Ignoring the trailing percent sign, interpret value as an integer,
887 // and let number be that number. 879 // and let number be that number.
888 // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step 880 // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step
889 // labeled next setting. 881 // labeled next setting.
890 return number >= 0 && number <= 100; 882 return number >= 0 && number <= 100;
891 } 883 }
892 884
893 void VTTCue::parseSettings(const String& input) 885 void VTTCue::parseSettings(const String& inputString)
894 { 886 {
895 unsigned position = 0; 887 VTTScanner input(inputString);
896 888
897 while (position < input.length()) { 889 while (!input.isAtEnd()) {
898 890
899 // The WebVTT cue settings part of a WebVTT cue consists of zero or more of the following components, in any order, 891 // The WebVTT cue settings part of a WebVTT cue consists of zero or more of the following components, in any order,
900 // separated from each other by one or more U+0020 SPACE characters or U +0009 CHARACTER TABULATION (tab) characters. 892 // separated from each other by one or more U+0020 SPACE characters or U +0009 CHARACTER TABULATION (tab) characters.
901 while (position < input.length() && VTTParser::isValidSettingDelimiter(i nput[position])) 893 input.skipWhile<VTTParser::isValidSettingDelimiter>();
902 position++; 894
903 if (position >= input.length()) 895 if (input.isAtEnd())
904 break; 896 break;
905 897
906 // When the user agent is to parse the WebVTT settings given by a string input for a text track cue cue, 898 // When the user agent is to parse the WebVTT settings given by a string input for a text track cue cue,
907 // the user agent must run the following steps: 899 // the user agent must run the following steps:
908 // 1. Let settings be the result of splitting input on spaces. 900 // 1. Let settings be the result of splitting input on spaces.
909 // 2. For each token setting in the list settings, run the following sub steps: 901 // 2. For each token setting in the list settings, run the following sub steps:
910 // 1. If setting does not contain a U+003A COLON character (:), or if the first U+003A COLON character (:) 902 // 1. If setting does not contain a U+003A COLON character (:), or if the first U+003A COLON character (:)
911 // in setting is either the first or last character of setting, th en jump to the step labeled next setting. 903 // in setting is either the first or last character of setting, th en jump to the step labeled next setting.
912 unsigned endOfSetting = position; 904 // 2. Let name be the leading substring of setting up to and excludin g the first U+003A COLON character (:) in that string.
913 String setting = VTTParser::collectWord(input, &endOfSetting); 905 CueSetting name = settingName(input);
914 CueSetting name;
915 size_t colonOffset = setting.find(':', 1);
916 if (colonOffset == kNotFound || !colonOffset || colonOffset == setting.l ength() - 1)
917 goto NextSetting;
918
919 // 2. Let name be the leading substring of setting up to and excluding t he first U+003A COLON character (:) in that string.
920 name = settingName(setting.substring(0, colonOffset));
921 906
922 // 3. Let value be the trailing substring of setting starting from the c haracter immediately after the first U+003A COLON character (:) in that string. 907 // 3. Let value be the trailing substring of setting starting from the c haracter immediately after the first U+003A COLON character (:) in that string.
923 position += colonOffset + 1; 908 VTTScanner::Run valueRun = input.collectUntil<VTTParser::isValidSettingD elimiter>();
924 if (position >= input.length())
925 break;
926 909
927 // 4. Run the appropriate substeps that apply for the value of name, as follows: 910 // 4. Run the appropriate substeps that apply for the value of name, as follows:
928 switch (name) { 911 switch (name) {
929 case Vertical: { 912 case Vertical: {
930 // If name is a case-sensitive match for "vertical" 913 // If name is a case-sensitive match for "vertical"
931 // 1. If value is a case-sensitive match for the string "rl", then l et cue's text track cue writing direction 914 // 1. If value is a case-sensitive match for the string "rl", then l et cue's text track cue writing direction
932 // be vertical growing left. 915 // be vertical growing left.
933 String writingDirection = VTTParser::collectWord(input, &position); 916 if (input.scanRun(valueRun, verticalGrowingLeftKeyword()))
934 if (writingDirection == verticalGrowingLeftKeyword())
935 m_writingDirection = VerticalGrowingLeft; 917 m_writingDirection = VerticalGrowingLeft;
936 918
937 // 2. Otherwise, if value is a case-sensitive match for the string " lr", then let cue's text track cue writing 919 // 2. Otherwise, if value is a case-sensitive match for the string " lr", then let cue's text track cue writing
938 // direction be vertical growing right. 920 // direction be vertical growing right.
939 else if (writingDirection == verticalGrowingRightKeyword()) 921 else if (input.scanRun(valueRun, verticalGrowingRightKeyword()))
940 m_writingDirection = VerticalGrowingRight; 922 m_writingDirection = VerticalGrowingRight;
941 break; 923 break;
942 } 924 }
943 case Line: { 925 case Line: {
944 // 1-2 - Collect chars that are either '-', '%', or a digit. 926 // 1-2 - Collect chars that are either '-', '%', or a digit.
945 // 1. If value contains any characters other than U+002D HYPHEN-MINU S characters (-), U+0025 PERCENT SIGN 927 // 1. If value contains any characters other than U+002D HYPHEN-MINU S characters (-), U+0025 PERCENT SIGN
946 // characters (%), and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump 928 // characters (%), and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump
947 // to the step labeled next setting. 929 // to the step labeled next setting.
948 StringBuilder linePositionBuilder; 930 bool isNegative = input.scan('-');
949 while (position < input.length() && (input[position] == '-' || input [position] == '%' || isASCIIDigit(input[position]))) 931 int linePosition;
950 linePositionBuilder.append(input[position++]); 932 unsigned numDigits = input.scanDigits(linePosition);
951 if (position < input.length() && !VTTParser::isValidSettingDelimiter (input[position])) 933 bool isPercentage = input.scan('%');
934
935 if (!input.isAt(valueRun.end()))
952 break; 936 break;
953 937
954 // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT 938 // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
955 // NINE (9), then jump to the step labeled next setting. 939 // NINE (9), then jump to the step labeled next setting.
956 // 3. If any character in value other than the first character is a U+002D HYPHEN-MINUS character (-), then 940 // 3. If any character in value other than the first character is a U+002D HYPHEN-MINUS character (-), then
957 // jump to the step labeled next setting. 941 // jump to the step labeled next setting.
958 // 4. If any character in value other than the last character is a U +0025 PERCENT SIGN character (%), then 942 // 4. If any character in value other than the last character is a U +0025 PERCENT SIGN character (%), then
959 // jump to the step labeled next setting. 943 // jump to the step labeled next setting.
960 String linePosition = linePositionBuilder.toString();
961 if (linePosition.find('-', 1) != kNotFound || linePosition.reverseFi nd("%", linePosition.length() - 2) != kNotFound)
962 break;
963 944
964 // 5. If the first character in value is a U+002D HYPHEN-MINUS chara cter (-) and the last character in value is a 945 // 5. If the first character in value is a U+002D HYPHEN-MINUS chara cter (-) and the last character in value is a
965 // U+0025 PERCENT SIGN character (%), then jump to the step label ed next setting. 946 // U+0025 PERCENT SIGN character (%), then jump to the step label ed next setting.
966 if (linePosition[0] == '-' && linePosition[linePosition.length() - 1 ] == '%') 947 if (!numDigits || (isPercentage && isNegative))
967 break; 948 break;
968 949
969 // 6. Ignoring the trailing percent sign, if any, interpret value as a (potentially signed) integer, and 950 // 6. Ignoring the trailing percent sign, if any, interpret value as a (potentially signed) integer, and
970 // let number be that number. 951 // let number be that number.
971 // NOTE: toInt ignores trailing non-digit characters, such as '%'.
972 bool validNumber;
973 int number = linePosition.toInt(&validNumber);
974 if (!validNumber)
975 break;
976
977 // 7. If the last character in value is a U+0025 PERCENT SIGN charac ter (%), but number is not in the range 952 // 7. If the last character in value is a U+0025 PERCENT SIGN charac ter (%), but number is not in the range
978 // 0 ≤ number ≤ 100, then jump to the step labeled next setting. 953 // 0 ≤ number ≤ 100, then jump to the step labeled next setting.
979 // 8. Let cue's text track cue line position be number. 954 // 8. Let cue's text track cue line position be number.
980 // 9. If the last character in value is a U+0025 PERCENT SIGN charac ter (%), then let cue's text track cue 955 // 9. If the last character in value is a U+0025 PERCENT SIGN charac ter (%), then let cue's text track cue
981 // snap-to-lines flag be false. Otherwise, let it be true. 956 // snap-to-lines flag be false. Otherwise, let it be true.
982 if (linePosition[linePosition.length() - 1] == '%') { 957 if (isPercentage) {
983 if (number < 0 || number > 100) 958 if (linePosition < 0 || linePosition > 100)
984 break; 959 break;
985
986 // 10 - If '%' then set snap-to-lines flag to false. 960 // 10 - If '%' then set snap-to-lines flag to false.
987 m_snapToLines = false; 961 m_snapToLines = false;
962 } else {
963 if (isNegative)
964 linePosition = -linePosition;
Mike West 2014/01/13 07:24:20 Where does this come into play? I don't see it in
fs 2014/01/13 08:12:01 In the old code this was handled by toInt (line 97
965 m_snapToLines = true;
988 } 966 }
989 967 m_linePosition = linePosition;
990 m_linePosition = number;
991 break; 968 break;
992 } 969 }
993 case Position: { 970 case Position: {
994 int number; 971 int number;
995 // Steps 1 - 6. 972 // Steps 1 - 6.
996 if (!scanPercentage(input, &position, number)) 973 if (!scanPercentage(input, valueRun, number))
997 break; 974 break;
998 975
999 // 7. Let cue's text track cue text position be number. 976 // 7. Let cue's text track cue text position be number.
1000 m_textPosition = number; 977 m_textPosition = number;
1001 break; 978 break;
1002 } 979 }
1003 case Size: { 980 case Size: {
1004 int number; 981 int number;
1005 // Steps 1 - 6. 982 // Steps 1 - 6.
1006 if (!scanPercentage(input, &position, number)) 983 if (!scanPercentage(input, valueRun, number))
1007 break; 984 break;
1008 985
1009 // 7. Let cue's text track cue size be number. 986 // 7. Let cue's text track cue size be number.
1010 m_cueSize = number; 987 m_cueSize = number;
1011 break; 988 break;
1012 } 989 }
1013 case Align: { 990 case Align: {
1014 String cueAlignment = VTTParser::collectWord(input, &position);
1015
1016 // 1. If value is a case-sensitive match for the string "start", the n let cue's text track cue alignment be start alignment. 991 // 1. If value is a case-sensitive match for the string "start", the n let cue's text track cue alignment be start alignment.
1017 if (cueAlignment == startKeyword()) 992 if (input.scanRun(valueRun, startKeyword()))
1018 m_cueAlignment = Start; 993 m_cueAlignment = Start;
1019 994
1020 // 2. If value is a case-sensitive match for the string "middle", th en let cue's text track cue alignment be middle alignment. 995 // 2. If value is a case-sensitive match for the string "middle", th en let cue's text track cue alignment be middle alignment.
1021 else if (cueAlignment == middleKeyword()) 996 else if (input.scanRun(valueRun, middleKeyword()))
1022 m_cueAlignment = Middle; 997 m_cueAlignment = Middle;
1023 998
1024 // 3. If value is a case-sensitive match for the string "end", then let cue's text track cue alignment be end alignment. 999 // 3. If value is a case-sensitive match for the string "end", then let cue's text track cue alignment be end alignment.
1025 else if (cueAlignment == endKeyword()) 1000 else if (input.scanRun(valueRun, endKeyword()))
1026 m_cueAlignment = End; 1001 m_cueAlignment = End;
1027 1002
1028 // 4. If value is a case-sensitive match for the string "left", then let cue's text track cue alignment be left alignment. 1003 // 4. If value is a case-sensitive match for the string "left", then let cue's text track cue alignment be left alignment.
1029 else if (cueAlignment == leftKeyword()) 1004 else if (input.scanRun(valueRun, leftKeyword()))
1030 m_cueAlignment = Left; 1005 m_cueAlignment = Left;
1031 1006
1032 // 5. If value is a case-sensitive match for the string "right", the n let cue's text track cue alignment be right alignment. 1007 // 5. If value is a case-sensitive match for the string "right", the n let cue's text track cue alignment be right alignment.
1033 else if (cueAlignment == rightKeyword()) 1008 else if (input.scanRun(valueRun, rightKeyword()))
1034 m_cueAlignment = Right; 1009 m_cueAlignment = Right;
1035 break; 1010 break;
1036 } 1011 }
1037 case RegionId: 1012 case RegionId:
1038 m_regionId = VTTParser::collectWord(input, &position); 1013 m_regionId = input.extractString(valueRun);
1039 break; 1014 break;
1040 case None: 1015 case None:
1041 break; 1016 break;
1042 } 1017 }
1043 1018
1044 NextSetting: 1019 // Make sure the entire run is consumed.
1045 position = endOfSetting; 1020 input.skipRun(valueRun);
1046 } 1021 }
1047 1022
1048 // If cue's line position is not auto or cue's size is not 100 or cue's 1023 // If cue's line position is not auto or cue's size is not 100 or cue's
1049 // writing direction is not horizontal, but cue's region identifier is not 1024 // writing direction is not horizontal, but cue's region identifier is not
1050 // the empty string, let cue's region identifier be the empty string. 1025 // the empty string, let cue's region identifier be the empty string.
1051 if (m_regionId.isEmpty()) 1026 if (m_regionId.isEmpty())
1052 return; 1027 return;
1053 1028
1054 if (m_linePosition != undefinedPosition || m_cueSize != 100 || m_writingDire ction != Horizontal) 1029 if (m_linePosition != undefinedPosition || m_cueSize != 100 || m_writingDire ction != Horizontal)
1055 m_regionId = emptyString(); 1030 m_regionId = emptyString();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 return m_cueBackgroundBox->executionContext(); 1064 return m_cueBackgroundBox->executionContext();
1090 } 1065 }
1091 1066
1092 Document& VTTCue::document() const 1067 Document& VTTCue::document() const
1093 { 1068 {
1094 ASSERT(m_cueBackgroundBox); 1069 ASSERT(m_cueBackgroundBox);
1095 return m_cueBackgroundBox->document(); 1070 return m_cueBackgroundBox->document();
1096 } 1071 }
1097 1072
1098 } // namespace WebCore 1073 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/html/track/vtt/VTTCue.h ('k') | Source/core/html/track/vtt/VTTScanner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698