OLD | NEW |
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 Loading... |
37 #include "core/dom/DocumentFragment.h" | 37 #include "core/dom/DocumentFragment.h" |
38 #include "core/dom/NodeTraversal.h" | 38 #include "core/dom/NodeTraversal.h" |
39 #include "core/events/Event.h" | 39 #include "core/events/Event.h" |
40 #include "core/frame/Settings.h" | 40 #include "core/frame/Settings.h" |
41 #include "core/frame/UseCounter.h" | 41 #include "core/frame/UseCounter.h" |
42 #include "core/html/HTMLDivElement.h" | 42 #include "core/html/HTMLDivElement.h" |
43 #include "core/html/track/TextTrack.h" | 43 #include "core/html/track/TextTrack.h" |
44 #include "core/html/track/TextTrackCueList.h" | 44 #include "core/html/track/TextTrackCueList.h" |
45 #include "core/html/track/vtt/VTTElement.h" | 45 #include "core/html/track/vtt/VTTElement.h" |
46 #include "core/html/track/vtt/VTTParser.h" | 46 #include "core/html/track/vtt/VTTParser.h" |
47 #include "core/html/track/vtt/VTTRegionList.h" | 47 #include "core/html/track/vtt/VTTRegion.h" |
48 #include "core/html/track/vtt/VTTScanner.h" | 48 #include "core/html/track/vtt/VTTScanner.h" |
49 #include "core/layout/LayoutVTTCue.h" | 49 #include "core/layout/LayoutVTTCue.h" |
50 #include "platform/RuntimeEnabledFeatures.h" | 50 #include "platform/RuntimeEnabledFeatures.h" |
51 #include "platform/text/BidiResolver.h" | 51 #include "platform/text/BidiResolver.h" |
52 #include "platform/text/TextRunIterator.h" | 52 #include "platform/text/TextRunIterator.h" |
53 #include "wtf/MathExtras.h" | 53 #include "wtf/MathExtras.h" |
54 #include "wtf/text/StringBuilder.h" | 54 #include "wtf/text/StringBuilder.h" |
55 | 55 |
56 namespace blink { | 56 namespace blink { |
57 | 57 |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 } | 465 } |
466 } | 466 } |
467 | 467 |
468 DocumentFragment* VTTCue::getCueAsHTML() { | 468 DocumentFragment* VTTCue::getCueAsHTML() { |
469 createVTTNodeTree(); | 469 createVTTNodeTree(); |
470 DocumentFragment* clonedFragment = DocumentFragment::create(document()); | 470 DocumentFragment* clonedFragment = DocumentFragment::create(document()); |
471 copyVTTNodeToDOMTree(m_vttNodeTree.get(), clonedFragment); | 471 copyVTTNodeToDOMTree(m_vttNodeTree.get(), clonedFragment); |
472 return clonedFragment; | 472 return clonedFragment; |
473 } | 473 } |
474 | 474 |
475 void VTTCue::setRegionId(const String& regionId) { | 475 void VTTCue::setRegion(VTTRegion* region) { |
476 if (m_regionId == regionId) | 476 if (m_region == region) |
477 return; | 477 return; |
478 | |
479 cueWillChange(); | 478 cueWillChange(); |
480 m_regionId = regionId; | 479 m_region = region; |
481 cueDidChange(); | 480 cueDidChange(); |
482 } | 481 } |
483 | 482 |
484 float VTTCue::calculateComputedLinePosition() const { | 483 float VTTCue::calculateComputedLinePosition() const { |
485 // http://dev.w3.org/html5/webvtt/#dfn-cue-computed-line | 484 // http://dev.w3.org/html5/webvtt/#dfn-cue-computed-line |
486 // A WebVTT cue has a computed line whose value is that returned by the | 485 // A WebVTT cue has a computed line whose value is that returned by the |
487 // following algorithm, which is defined in terms of the other aspects of | 486 // following algorithm, which is defined in terms of the other aspects of |
488 // the cue: | 487 // the cue: |
489 | 488 |
490 // 1. If the line is numeric, the WebVTT cue snap-to-lines flag of the | 489 // 1. If the line is numeric, the WebVTT cue snap-to-lines flag of the |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 // track. | 804 // track. |
806 applyUserOverrideCSSProperties(); | 805 applyUserOverrideCSSProperties(); |
807 return m_displayTree; | 806 return m_displayTree; |
808 } | 807 } |
809 | 808 |
810 createVTTNodeTree(); | 809 createVTTNodeTree(); |
811 | 810 |
812 m_cueBackgroundBox->removeChildren(); | 811 m_cueBackgroundBox->removeChildren(); |
813 m_vttNodeTree->cloneChildNodes(m_cueBackgroundBox.get()); | 812 m_vttNodeTree->cloneChildNodes(m_cueBackgroundBox.get()); |
814 | 813 |
815 // TODO(foolip): The region identifier may be non-empty without there being | 814 if (!region()) { |
816 // a corresponding region, in which case this VTTCueBox will be added | |
817 // directly to the text track container in updateDisplay(). | |
818 if (regionId().isEmpty()) { | |
819 VTTDisplayParameters displayParameters = calculateDisplayParameters(); | 815 VTTDisplayParameters displayParameters = calculateDisplayParameters(); |
820 m_displayTree->applyCSSProperties(displayParameters); | 816 m_displayTree->applyCSSProperties(displayParameters); |
821 } else { | 817 } else { |
822 m_displayTree->setInlineStyleProperty(CSSPropertyPosition, | 818 m_displayTree->setInlineStyleProperty(CSSPropertyPosition, |
823 CSSValueRelative); | 819 CSSValueRelative); |
824 } | 820 } |
825 | 821 |
826 // Apply user override settings for text tracks | 822 // Apply user override settings for text tracks |
827 applyUserOverrideCSSProperties(); | 823 applyUserOverrideCSSProperties(); |
828 | 824 |
829 m_displayTreeShouldChange = false; | 825 m_displayTreeShouldChange = false; |
830 | 826 |
831 return m_displayTree; | 827 return m_displayTree; |
832 } | 828 } |
833 | 829 |
834 void VTTCue::removeDisplayTree(RemovalNotification removalNotification) { | 830 void VTTCue::removeDisplayTree(RemovalNotification removalNotification) { |
835 if (removalNotification == NotifyRegion && track()->regions()) { | 831 if (region() && removalNotification == NotifyRegion) { |
836 // The region needs to be informed about the cue removal. | 832 // The region needs to be informed about the cue removal. |
837 VTTRegion* region = track()->regions()->getRegionById(m_regionId); | 833 region()->willRemoveVTTCueBox(m_displayTree); |
838 if (region) | |
839 region->willRemoveVTTCueBox(m_displayTree.get()); | |
840 } | 834 } |
841 | 835 |
842 if (m_displayTree) | 836 if (m_displayTree) |
843 m_displayTree->remove(ASSERT_NO_EXCEPTION); | 837 m_displayTree->remove(ASSERT_NO_EXCEPTION); |
844 } | 838 } |
845 | 839 |
846 void VTTCue::updateDisplay(HTMLDivElement& container) { | 840 void VTTCue::updateDisplay(HTMLDivElement& container) { |
847 DCHECK(track() && track()->isRendered() && isActive()); | 841 DCHECK(track() && track()->isRendered() && isActive()); |
848 | 842 |
849 UseCounter::count(document(), UseCounter::VTTCueRender); | 843 UseCounter::count(document(), UseCounter::VTTCueRender); |
(...skipping 10 matching lines...) Expand all Loading... |
860 if (textPositionIsAuto()) | 854 if (textPositionIsAuto()) |
861 UseCounter::count(document(), UseCounter::VTTCueRenderPositionNot50); | 855 UseCounter::count(document(), UseCounter::VTTCueRenderPositionNot50); |
862 | 856 |
863 if (m_cueSize != 100) | 857 if (m_cueSize != 100) |
864 UseCounter::count(document(), UseCounter::VTTCueRenderSizeNot100); | 858 UseCounter::count(document(), UseCounter::VTTCueRenderSizeNot100); |
865 | 859 |
866 if (m_cueAlignment != Middle) | 860 if (m_cueAlignment != Middle) |
867 UseCounter::count(document(), UseCounter::VTTCueRenderAlignNotMiddle); | 861 UseCounter::count(document(), UseCounter::VTTCueRenderAlignNotMiddle); |
868 | 862 |
869 VTTCueBox* displayBox = getDisplayTree(); | 863 VTTCueBox* displayBox = getDisplayTree(); |
870 VTTRegion* region = 0; | 864 if (!region()) { |
871 if (track()->regions()) | |
872 region = track()->regions()->getRegionById(regionId()); | |
873 | |
874 if (!region) { | |
875 // If cue has an empty region identifier or there is no WebVTT region | |
876 // whose region identifier is identical to cue's region identifier, run | |
877 // the following substeps: | |
878 if (displayBox->hasChildren() && !container.contains(displayBox)) { | 865 if (displayBox->hasChildren() && !container.contains(displayBox)) { |
879 // Note: the display tree of a cue is removed when the active flag of the | 866 // Note: the display tree of a cue is removed when the active flag of the |
880 // cue is unset. | 867 // cue is unset. |
881 container.appendChild(displayBox); | 868 container.appendChild(displayBox); |
882 } | 869 } |
883 } else { | 870 } else { |
884 // Let region be the WebVTT region whose region identifier matches the | 871 HTMLDivElement* regionNode = region()->getDisplayTree(document()); |
885 // region identifier of cue. | |
886 HTMLDivElement* regionNode = region->getDisplayTree(document()); | |
887 | 872 |
888 // Append the region to the viewport, if it was not already. | 873 // Append the region to the viewport, if it was not already. |
889 if (!container.contains(regionNode)) | 874 if (!container.contains(regionNode)) |
890 container.appendChild(regionNode); | 875 container.appendChild(regionNode); |
891 | 876 |
892 region->appendVTTCueBox(displayBox); | 877 region()->appendVTTCueBox(displayBox); |
893 } | 878 } |
894 } | 879 } |
895 | 880 |
896 VTTCue::CueSetting VTTCue::settingName(VTTScanner& input) const { | 881 VTTCue::CueSetting VTTCue::settingName(VTTScanner& input) const { |
897 CueSetting parsedSetting = None; | 882 CueSetting parsedSetting = None; |
898 if (input.scan("vertical")) | 883 if (input.scan("vertical")) |
899 parsedSetting = Vertical; | 884 parsedSetting = Vertical; |
900 else if (input.scan("line")) | 885 else if (input.scan("line")) |
901 parsedSetting = Line; | 886 parsedSetting = Line; |
902 else if (input.scan("position")) | 887 else if (input.scan("position")) |
(...skipping 24 matching lines...) Expand all Loading... |
927 // PERCENT SIGN character (%), then fail. | 912 // PERCENT SIGN character (%), then fail. |
928 // 6. If the last character in input is not a U+0025 PERCENT SIGN character | 913 // 6. If the last character in input is not a U+0025 PERCENT SIGN character |
929 // (%), then fail. | 914 // (%), then fail. |
930 // 7. Ignoring the trailing percent sign, interpret input as a real | 915 // 7. Ignoring the trailing percent sign, interpret input as a real |
931 // number. Let that number be the percentage. | 916 // number. Let that number be the percentage. |
932 // 8. If percentage is outside the range 0..100, then fail. | 917 // 8. If percentage is outside the range 0..100, then fail. |
933 // 9. Return percentage. | 918 // 9. Return percentage. |
934 return input.scanPercentage(number) && !isInvalidPercentage(number); | 919 return input.scanPercentage(number) && !isInvalidPercentage(number); |
935 } | 920 } |
936 | 921 |
937 void VTTCue::parseSettings(const String& inputString) { | 922 void VTTCue::parseSettings(const VTTRegionMap* regionMap, |
| 923 const String& inputString) { |
938 VTTScanner input(inputString); | 924 VTTScanner input(inputString); |
939 | 925 |
940 while (!input.isAtEnd()) { | 926 while (!input.isAtEnd()) { |
941 // The WebVTT cue settings part of a WebVTT cue consists of zero or more of | 927 // The WebVTT cue settings part of a WebVTT cue consists of zero or more of |
942 // the following components, in any order, separated from each other by one | 928 // the following components, in any order, separated from each other by one |
943 // or more U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) | 929 // or more U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) |
944 // characters. | 930 // characters. |
945 input.skipWhile<VTTParser::isValidSettingDelimiter>(); | 931 input.skipWhile<VTTParser::isValidSettingDelimiter>(); |
946 | 932 |
947 if (input.isAtEnd()) | 933 if (input.isAtEnd()) |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 else if (input.scanRun(valueRun, leftKeyword())) | 1065 else if (input.scanRun(valueRun, leftKeyword())) |
1080 m_cueAlignment = Left; | 1066 m_cueAlignment = Left; |
1081 | 1067 |
1082 // 5. If value is a case-sensitive match for the string "right", | 1068 // 5. If value is a case-sensitive match for the string "right", |
1083 // then let cue's WebVTT cue text alignment be right alignment. | 1069 // then let cue's WebVTT cue text alignment be right alignment. |
1084 else if (input.scanRun(valueRun, rightKeyword())) | 1070 else if (input.scanRun(valueRun, rightKeyword())) |
1085 m_cueAlignment = Right; | 1071 m_cueAlignment = Right; |
1086 break; | 1072 break; |
1087 } | 1073 } |
1088 case RegionId: | 1074 case RegionId: |
1089 m_regionId = input.extractString(valueRun); | 1075 if (regionMap) |
| 1076 m_region = regionMap->get(input.extractString(valueRun)); |
1090 break; | 1077 break; |
1091 case None: | 1078 case None: |
1092 break; | 1079 break; |
1093 } | 1080 } |
1094 | 1081 |
1095 // Make sure the entire run is consumed. | 1082 // Make sure the entire run is consumed. |
1096 input.skipRun(valueRun); | 1083 input.skipRun(valueRun); |
1097 } | 1084 } |
1098 | |
1099 // If cue's line position is not auto or cue's size is not 100 or cue's | |
1100 // writing direction is not horizontal, but cue's region identifier is not | |
1101 // the empty string, let cue's region identifier be the empty string. | |
1102 if (m_regionId.isEmpty()) | |
1103 return; | |
1104 | |
1105 if (!lineIsAuto() || m_cueSize != 100 || m_writingDirection != Horizontal) | |
1106 m_regionId = emptyString; | |
1107 } | 1085 } |
1108 | 1086 |
1109 void VTTCue::applyUserOverrideCSSProperties() { | 1087 void VTTCue::applyUserOverrideCSSProperties() { |
1110 Settings* settings = document().settings(); | 1088 Settings* settings = document().settings(); |
1111 if (!settings) | 1089 if (!settings) |
1112 return; | 1090 return; |
1113 | 1091 |
1114 setInlineStylePropertyIfNotEmpty(*m_cueBackgroundBox, | 1092 setInlineStylePropertyIfNotEmpty(*m_cueBackgroundBox, |
1115 CSSPropertyBackgroundColor, | 1093 CSSPropertyBackgroundColor, |
1116 settings->getTextTrackBackgroundColor()); | 1094 settings->getTextTrackBackgroundColor()); |
(...skipping 15 matching lines...) Expand all Loading... |
1132 DCHECK(m_cueBackgroundBox); | 1110 DCHECK(m_cueBackgroundBox); |
1133 return m_cueBackgroundBox->getExecutionContext(); | 1111 return m_cueBackgroundBox->getExecutionContext(); |
1134 } | 1112 } |
1135 | 1113 |
1136 Document& VTTCue::document() const { | 1114 Document& VTTCue::document() const { |
1137 DCHECK(m_cueBackgroundBox); | 1115 DCHECK(m_cueBackgroundBox); |
1138 return m_cueBackgroundBox->document(); | 1116 return m_cueBackgroundBox->document(); |
1139 } | 1117 } |
1140 | 1118 |
1141 DEFINE_TRACE(VTTCue) { | 1119 DEFINE_TRACE(VTTCue) { |
| 1120 visitor->trace(m_region); |
1142 visitor->trace(m_vttNodeTree); | 1121 visitor->trace(m_vttNodeTree); |
1143 visitor->trace(m_cueBackgroundBox); | 1122 visitor->trace(m_cueBackgroundBox); |
1144 visitor->trace(m_displayTree); | 1123 visitor->trace(m_displayTree); |
1145 TextTrackCue::trace(visitor); | 1124 TextTrackCue::trace(visitor); |
1146 } | 1125 } |
1147 | 1126 |
1148 } // namespace blink | 1127 } // namespace blink |
OLD | NEW |