diff --git a/DEPS b/DEPS index e197b1a..b116334 100644 --- a/DEPS +++ b/DEPS
@@ -40,7 +40,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '99c9796dde4cae3c71d0381256fea04eea48218e', + 'skia_revision': 'ddff43aa5e696dad75c823ebcf8258923c0d0257', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '5bec04aa94e48ec34ea3b611e6ba64ecd5a6bc72', + 'catapult_revision': '489a5bc40e983273304af2375580900819b1389d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other.
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index b87bb97..efe69357 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -533,8 +533,8 @@ return new AwDevToolsManagerDelegate(); } -std::unique_ptr<base::Value> -AwContentBrowserClient::GetServiceManifestOverlay(const std::string& name) { +std::unique_ptr<base::Value> AwContentBrowserClient::GetServiceManifestOverlay( + base::StringPiece name) { int id = -1; if (name == content::mojom::kBrowserServiceName) id = IDR_AW_BROWSER_MANIFEST_OVERLAY;
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index a3472c5..e53659f 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -131,7 +131,7 @@ content::NavigationHandle* navigation_handle) override; content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; std::unique_ptr<base::Value> GetServiceManifestOverlay( - const std::string& name) override; + base::StringPiece name) override; void RegisterRenderFrameMojoInterfaces( service_manager::InterfaceRegistry* registry, content::RenderFrameHost* render_frame_host) override;
diff --git a/base/OWNERS b/base/OWNERS index b58c9bb1..06f165f 100644 --- a/base/OWNERS +++ b/base/OWNERS
@@ -17,11 +17,12 @@ # multiple consumers across the codebase, consider placing it in a new directory # under components/ instead. +danakj@chromium.org +dcheng@chromium.org +gab@chromium.org mark@chromium.org thakis@chromium.org -danakj@chromium.org thestig@chromium.org -dcheng@chromium.org # For Bind/Callback: per-file bind*=tzik@chromium.org
diff --git a/base/time/time.cc b/base/time/time.cc index f5cefd4..93a6195c 100644 --- a/base/time/time.cc +++ b/base/time/time.cc
@@ -191,10 +191,6 @@ } double Time::ToJsTime() const { - if (is_null()) { - // Preserve 0 so the invalid result doesn't depend on the platform. - return 0; - } if (is_max()) { // Preserve max without offset to prevent overflow. return std::numeric_limits<double>::infinity();
diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc index 8906c3b..f25315f 100644 --- a/base/time/time_unittest.cc +++ b/base/time/time_unittest.cc
@@ -159,6 +159,15 @@ EXPECT_EQ(700.0003, t.ToDoubleT()); t = Time::FromDoubleT(800.73); EXPECT_EQ(800730.0, t.ToJsTime()); + + // Correctly convert |- epoch offset| which is valid time in javascript. + Time minusEpoch = Time::FromJsTime(-11644473600000.0); + EXPECT_EQ(-11644473600000, minusEpoch.ToJsTime()); + + // Check conversion of boundary javascript time values. + // See http://www.ecma-international.org/ecma-262/6.0/#sec-timeclip + EXPECT_EQ(-8.46e15, Time::FromJsTime(-8.46e15).ToJsTime()); + EXPECT_EQ(8.46e15, Time::FromJsTime(8.46e15).ToJsTime()); } #if defined(OS_POSIX)
diff --git a/blimp/engine/app/blimp_content_browser_client.cc b/blimp/engine/app/blimp_content_browser_client.cc index 5e8c42b3..e3a5d01 100644 --- a/blimp/engine/app/blimp_content_browser_client.cc +++ b/blimp/engine/app/blimp_content_browser_client.cc
@@ -53,8 +53,7 @@ } std::unique_ptr<base::Value> -BlimpContentBrowserClient::GetServiceManifestOverlay( - const std::string& name) { +BlimpContentBrowserClient::GetServiceManifestOverlay(base::StringPiece name) { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); int id = -1; if (name == content::mojom::kBrowserServiceName) {
diff --git a/blimp/engine/app/blimp_content_browser_client.h b/blimp/engine/app/blimp_content_browser_client.h index d843da0..20a2a7d 100644 --- a/blimp/engine/app/blimp_content_browser_client.h +++ b/blimp/engine/app/blimp_content_browser_client.h
@@ -32,7 +32,7 @@ service_manager::InterfaceRegistry* registry, content::RenderProcessHost* render_process_host) override; std::unique_ptr<base::Value> GetServiceManifestOverlay( - const std::string& name) override; + base::StringPiece name) override; BlimpBrowserContext* GetBrowserContext();
diff --git a/chrome/android/java/res/drawable/material_progressbar.xml b/chrome/android/java/res/drawable/material_progressbar.xml deleted file mode 100644 index 9e740a98..0000000 --- a/chrome/android/java/res/drawable/material_progressbar.xml +++ /dev/null
@@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright 2016 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. --> - -<!-- This file is necessary because the design support library (as of 24.0) doesn't have properly - styled progress bars on JB & KK. --> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:id="@android:id/background"> - <shape> - <solid android:color="@color/google_grey_400" /> - </shape> - </item> - - <item android:id="@android:id/progress"> - <clip> - <shape> - <solid android:color="@color/light_active_color" /> - </shape> - </clip> - </item> - - <item android:id="@android:id/secondaryProgress"> - <clip> - <shape> - <solid android:color="@color/google_grey_600" /> - </shape> - </clip> - </item> -</layer-list>
diff --git a/chrome/android/java/res/layout/download_item_view.xml b/chrome/android/java/res/layout/download_item_view.xml index 679d1f8..1210f0f4 100644 --- a/chrome/android/java/res/layout/download_item_view.xml +++ b/chrome/android/java/res/layout/download_item_view.xml
@@ -96,16 +96,18 @@ android:textColor="@color/default_text_color" android:textSize="14sp" /> - <ProgressBar + <org.chromium.chrome.browser.widget.MaterialProgressBar android:id="@+id/download_progress_view" - style="@style/DownloadProgressBar" android:layout_width="wrap_content" android:layout_height="2dp" android:layout_marginTop="5dp" android:layout_marginBottom="5dp" android:layout_below="@+id/filename_progress_view" android:layout_alignParentStart="true" - android:layout_toStartOf="@+id/pause_button" /> + android:layout_toStartOf="@+id/pause_button" + chrome:colorBackground="@color/google_grey_400" + chrome:colorProgress="@color/light_active_color" + chrome:colorSecondaryProgress="@color/google_grey_600" /> <TextView android:id="@+id/status_view"
diff --git a/chrome/android/java/res/layout/download_manager_ui_space_widget.xml b/chrome/android/java/res/layout/download_manager_ui_space_widget.xml index ba99847..a963bbf 100644 --- a/chrome/android/java/res/layout/download_manager_ui_space_widget.xml +++ b/chrome/android/java/res/layout/download_manager_ui_space_widget.xml
@@ -3,7 +3,8 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<merge xmlns:android="http://schemas.android.com/apk/res/android"> +<merge xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:chrome="http://schemas.android.com/apk/res-auto" > <!-- Widget style adapted from the UX spec: https://bugs.chromium.org/p/chromium/issues/detail?id=658246&desc=2#c18 @@ -26,13 +27,15 @@ android:textSize="20sp" /> <!-- The progress bar uses 32dp of space, vertically, including spacing. --> - <ProgressBar + <org.chromium.chrome.browser.widget.MaterialProgressBar android:id="@+id/space_bar" - style="@style/MaterialProgressBar" android:layout_width="match_parent" android:layout_height="4dp" android:layout_marginTop="14dp" - android:layout_marginBottom="14dp" /> + android:layout_marginBottom="14dp" + chrome:colorBackground="@color/google_grey_400" + chrome:colorProgress="@color/light_active_color" + chrome:colorSecondaryProgress="@color/google_grey_600" /> <TextView android:id="@+id/size_other_apps"
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index 545d532..9b9cf78 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -525,16 +525,6 @@ <item name="android:textAllCaps">true</item> </style> - <!-- Progress bars --> - <style name="DownloadProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal"> - <item name="android:indeterminateDrawable">@drawable/download_progressbar</item> - <item name="android:indeterminateDuration">250</item> - <item name="android:progressDrawable">@drawable/download_progressbar</item> - </style> - <style name="MaterialProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal"> - <item name="android:progressDrawable">@drawable/material_progressbar</item> - </style> - <!-- Misc styles --> <style name="LocationBarButton"> <item name="android:background">@null</item>
diff --git a/chrome/android/java/res/values/attrs.xml b/chrome/android/java/res/values/attrs.xml index 1bdd359..cb74a3c 100644 --- a/chrome/android/java/res/values/attrs.xml +++ b/chrome/android/java/res/values/attrs.xml
@@ -57,6 +57,12 @@ <attr name="backgroundColor" format="reference|color" /> </declare-styleable> + <declare-styleable name="MaterialProgressBar"> + <attr name="colorBackground" format="reference|color" /> + <attr name="colorProgress" format="reference|color" /> + <attr name="colorSecondaryProgress" format="reference|color" /> + </declare-styleable> + <declare-styleable name="RadioButtonWithDescription"> <attr name="titleText" format="string" /> </declare-styleable>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index d0dd150f..b9af768 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -124,6 +124,7 @@ <!-- Progress Bar colors --> <color name="progress_bar_foreground">@color/light_active_color</color> <color name="progress_bar_foreground_white">@android:color/white</color> + <color name="progress_bar_secondary">@color/google_grey_600</color> <color name="progress_bar_background">#3d4386f7</color> <color name="progress_bar_background_white">#4d000000</color>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelMetrics.java index feb4e2f3..2f11ac4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelMetrics.java
@@ -8,6 +8,8 @@ import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; import org.chromium.chrome.browser.contextualsearch.ContextualSearchBlacklist.BlacklistReason; import org.chromium.chrome.browser.contextualsearch.ContextualSearchHeuristics; +import org.chromium.chrome.browser.contextualsearch.ContextualSearchRankerLogger; +import org.chromium.chrome.browser.contextualsearch.ContextualSearchRankerLoggerImpl; import org.chromium.chrome.browser.contextualsearch.ContextualSearchUma; import org.chromium.chrome.browser.contextualsearch.QuickActionCategory; @@ -19,6 +21,9 @@ public class ContextualSearchPanelMetrics { private static final int MILLISECONDS_TO_NANOSECONDS = 1000000; + // The Ranker logger to use to write Tap Suppression Ranker logs to UMA. + private final ContextualSearchRankerLogger mTapSuppressionRankerLogger; + // Flags for logging. private BlacklistReason mBlacklistReason; private boolean mDidSearchInvolvePromo; @@ -41,6 +46,8 @@ private boolean mWasQuickActionClicked; private boolean mWasSelectionAllCaps; private boolean mDidSelectionStartWithCapital; + private char mSelectionFirstChar; + private int mSelectionLength; // Whether any Tap suppression heuristic was satisfied when the panel was shown. private boolean mWasAnyHeuristicSatisfiedOnPanelShow; // Time when the panel was triggered (not reset by a chained search). @@ -61,6 +68,16 @@ private long mPanelOpenedBeyondPeekTimeNs; // The current set of heuristics that should be logged with results seen when the panel closes. private ContextualSearchHeuristics mResultsSeenExperiments; + // The current set of heuristics to be logged through ranker with results seen when the panel + // closes. + private ContextualSearchHeuristics mRankerLogExperiments; + + /** + * Constructs an object to track metrics for the Contextual Search Overlay Panel. + */ + ContextualSearchPanelMetrics() { + mTapSuppressionRankerLogger = new ContextualSearchRankerLoggerImpl(); + } /** * Log information when the panel's state has changed. @@ -96,6 +113,8 @@ (System.nanoTime() - mPanelTriggerTimeNs) / MILLISECONDS_TO_NANOSECONDS; ContextualSearchUma.logDurationBetweenTriggerAndScroll( durationMs, mWasSearchContentViewSeen); + mTapSuppressionRankerLogger.log( + ContextualSearchRankerLogger.Feature.DURATION_BEFORE_SCROLL_MS, durationMs); } if (isEndingSearch) { @@ -125,6 +144,9 @@ mQuickActionCategory); ContextualSearchUma.logQuickActionClicked(mWasQuickActionClicked, mQuickActionCategory); + mTapSuppressionRankerLogger.log( + ContextualSearchRankerLogger.Feature.OUTCOME_WAS_QUICK_ACTION_CLICKED, + mWasQuickActionClicked); } if (mWasSelectionAllCaps && mWasActivatedByTap) { @@ -150,6 +172,14 @@ || mWasSelectionAllCaps; ContextualSearchUma.logAnyTapSuppressionHeuristicSatisfied( mWasSearchContentViewSeen, wasAnySuppressionHeuristicSatisfied); + // Log all the experiments to the Ranker logger. + if (mRankerLogExperiments != null) { + writeSelectionFeaturesToRanker(); + mTapSuppressionRankerLogger.logOutcome(mWasSearchContentViewSeen); + mRankerLogExperiments.logRankerTapSuppression(mTapSuppressionRankerLogger); + mTapSuppressionRankerLogger.writeLogAndReset(); + mRankerLogExperiments = null; + } } } @@ -323,17 +353,31 @@ * @param selection The text that is selected when a selection is established. */ public void onSelectionEstablished(String selection) { + mSelectionLength = selection.length(); // In some locales, there is no concept of an upper or lower case letter. Account for this - // by checking that the selected text is not equalivalet to selection#toLowerCase(). + // by checking that the selected text is not equivalent to selection#toLowerCase(). mWasSelectionAllCaps = selection.equals(selection.toUpperCase(Locale.getDefault())) && !selection.equals(selection.toLowerCase(Locale.getDefault())); - String firstChar = String.valueOf(selection.charAt(0)); + mSelectionFirstChar = selection.charAt(0); + String firstChar = String.valueOf(mSelectionFirstChar); mDidSelectionStartWithCapital = firstChar.equals( firstChar.toUpperCase(Locale.getDefault())) && !firstChar.equals(firstChar.toLowerCase(Locale.getDefault())); } /** + * Writes the set of selection features that we've collected for Ranker to its log. + */ + private void writeSelectionFeaturesToRanker() { + mTapSuppressionRankerLogger.log( + ContextualSearchRankerLogger.Feature.SELECTION_LENGTH, mSelectionLength); + mTapSuppressionRankerLogger.log( + ContextualSearchRankerLogger.Feature.SELECTION_FIRST_CHAR, mSelectionFirstChar); + mTapSuppressionRankerLogger.log( + ContextualSearchRankerLogger.Feature.SELECTION_WAS_ALL_CAPS, mWasSelectionAllCaps); + } + + /** * Called to record the time when a search request started, for resolve and prefetch timing. */ public void onSearchRequestStarted() { @@ -385,6 +429,15 @@ } /** + * Sets the experiments to log through Ranker with results seen. + * @param rankerLogExperiments The experiments to log through ranker when the panel results + * are known. + */ + public void setRankerLogExperiments(ContextualSearchHeuristics rankerLogExperiments) { + mRankerLogExperiments = rankerLogExperiments; + } + + /** * Records timing information when the search panel has been viewed for the first time. */ private void onSearchPanelFirstView() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/BarOverlapTapSuppression.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/BarOverlapTapSuppression.java index 0e58598..8bd295f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/BarOverlapTapSuppression.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/BarOverlapTapSuppression.java
@@ -64,6 +64,11 @@ return !mIsEnabled && mIsConditionSatisfied; } + @Override + protected void logRankerTapSuppression(ContextualSearchRankerLogger logger) { + logger.log(ContextualSearchRankerLogger.Feature.WAS_SCREEN_BOTTOM, mIsConditionSatisfied); + } + /** * @return The height of the content view area of the base page in pixels, or 0 if the * Height cannot be reliably obtained.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java index fc518f3..7555c804 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java
@@ -66,8 +66,6 @@ // Quick Answers. private static final String ENABLE_QUICK_ANSWERS = "enable_quick_answers"; - // Tap triggering suppression. - static final String SUPPRESSION_TAPS = "suppression_taps"; // Enables collection of recent scroll seen/unseen histograms. // TODO(donnd): remove all supporting code once short-lived data collection is done. private static final String ENABLE_RECENT_SCROLL_COLLECTION = "enable_recent_scroll_collection"; @@ -105,7 +103,6 @@ private static Integer sScreenTopSuppressionDps; private static Boolean sIsBarOverlapCollectionEnabled; private static Boolean sIsBarOverlapSuppressionEnabled; - private static Integer sSuppressionTaps; private static Boolean sShouldHideContextualCardsData; private static Boolean sIsContextualCardsBarIntegrationEnabled; private static Boolean sIsOnlineDetectionDisabled; @@ -365,24 +362,6 @@ } /** - * @return Whether triggering by Tap is suppressed (through a combination of various signals). - */ - static boolean isTapSuppressionEnabled() { - return getSuppressionTaps() > 0; - } - - /** - * @return The suppression threshold, expressed as the number of Taps since the last open where - * we start suppressing the UX on Tap. - */ - static int getSuppressionTaps() { - if (sSuppressionTaps == null) { - sSuppressionTaps = getIntParamValueOrDefault(SUPPRESSION_TAPS, 0); - } - return sSuppressionTaps.intValue(); - } - - /** * @return Whether to auto-promote clicks in the AMP carousel into a separate Tab. */ static boolean isAmpAsSeparateTabEnabled() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristic.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristic.java index 16bfd0f..c663351 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristic.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristic.java
@@ -51,4 +51,12 @@ protected boolean isConditionSatisfiedForAggregateLogging() { return false; } + + /** + * Logs the heuristic to UMA through Ranker logging for the purpose of Tap Suppression. + * @param logger A logger to log to. + */ + protected void logRankerTapSuppression(ContextualSearchRankerLogger logger) { + // Default is to not log. + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristics.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristics.java index 03453d1..82a0502 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristics.java
@@ -61,4 +61,14 @@ } return false; } + + /** + * Logs all the heuristics to the given logger. + * @param logger The logger to log to. + */ + public void logRankerTapSuppression(ContextualSearchRankerLogger logger) { + for (ContextualSearchHeuristic heuristic : mHeuristics) { + heuristic.logRankerTapSuppression(logger); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java index 3e07c59..e6c0ff1b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java
@@ -1299,6 +1299,7 @@ mHeuristics.add(mQuickAnswersHeuristic); } mSearchPanel.getPanelMetrics().setResultsSeenExperiments(mHeuristics); + mSearchPanel.getPanelMetrics().setRankerLogExperiments(mHeuristics); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLogger.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLogger.java new file mode 100644 index 0000000..3af8a83b --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLogger.java
@@ -0,0 +1,49 @@ +// Copyright 2016 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. + +package org.chromium.chrome.browser.contextualsearch; + +/** + * An interface for logging to UMA via Ranker. + */ +public interface ContextualSearchRankerLogger { + enum Feature { + UNKNOWN, + // Outcome labels: + OUTCOME_WAS_PANEL_OPENED, + OUTCOME_WAS_QUICK_ACTION_CLICKED, + OUTCOME_WAS_QUICK_ANSWER_SEEN, + // Features: + DURATION_AFTER_SCROLL_MS, + DURATION_BEFORE_SCROLL_MS, + SCREEN_TOP_DPS, + WAS_SCREEN_BOTTOM, + PREVIOUS_WEEK_IMPRESSIONS_COUNT, + PREVIOUS_WEEK_CTR_PERCENT, + PREVIOUS_28DAY_IMPRESSIONS_COUNT, + PREVIOUS_28DAY_CTR_PERCENT, + SELECTION_LENGTH, + SELECTION_FIRST_CHAR, + SELECTION_WAS_ALL_CAPS + } + + /** + * Logs a particular key/value pair. + * @param feature The feature to log. + * @param value The value to log, which is associated with the given key. + */ + void log(Feature feature, Object value); + + /** + * Logs the final outcome value that indicates the ML label. + * @param value The outcome label value. + */ + void logOutcome(Object value); + + /** + * Writes all the accumulated log entries and resets the logger so that future log calls + * accumulate into a new record. + */ + void writeLogAndReset(); +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java new file mode 100644 index 0000000..f56846a --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java
@@ -0,0 +1,30 @@ +// Copyright 2016 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. + +package org.chromium.chrome.browser.contextualsearch; + +import org.chromium.base.Log; + +/** + * Implements the UMA logging for Ranker that's used for Contextual Search Tap Suppression. + */ +public class ContextualSearchRankerLoggerImpl implements ContextualSearchRankerLogger { + private static final String TAG = "ContextualSearch"; + + @Override + public void log(Feature feature, Object value) { + // TODO(donnd): log to an actual persistent proto ASAP! + Log.v(TAG, "log %s with value %s", feature.toString(), value); + } + + @Override + public void logOutcome(Object value) { + log(Feature.OUTCOME_WAS_PANEL_OPENED, value); + } + + @Override + public void writeLogAndReset() { + Log.v(TAG, "Reset!\n"); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java index d5171191..a3be80c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/CtrSuppression.java
@@ -86,6 +86,27 @@ } } + @Override + protected void logRankerTapSuppression(ContextualSearchRankerLogger logger) { + if (nativeHasPreviousWeekData(mNativePointer)) { + int previousWeekImpressions = nativeGetPreviousWeekImpressions(mNativePointer); + int previousWeekCtr = (int) (100 * nativeGetPreviousWeekCtr(mNativePointer)); + logger.log(ContextualSearchRankerLogger.Feature.PREVIOUS_WEEK_IMPRESSIONS_COUNT, + previousWeekImpressions); + logger.log(ContextualSearchRankerLogger.Feature.PREVIOUS_WEEK_CTR_PERCENT, + previousWeekCtr); + } + + if (nativeHasPrevious28DayData(mNativePointer)) { + int previous28DayImpressions = nativeGetPrevious28DayImpressions(mNativePointer); + int previous28DayCtr = (int) (100 * nativeGetPrevious28DayCtr(mNativePointer)); + logger.log(ContextualSearchRankerLogger.Feature.PREVIOUS_28DAY_IMPRESSIONS_COUNT, + previous28DayImpressions); + logger.log(ContextualSearchRankerLogger.Feature.PREVIOUS_28DAY_CTR_PERCENT, + previous28DayCtr); + } + } + // ============================================================================================ // Device integer storage. // ============================================================================================
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/NearTopTapSuppression.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/NearTopTapSuppression.java index 39bf83f..1f3f9f1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/NearTopTapSuppression.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/NearTopTapSuppression.java
@@ -46,6 +46,11 @@ } } + @Override + protected void logRankerTapSuppression(ContextualSearchRankerLogger logger) { + logger.log(ContextualSearchRankerLogger.Feature.SCREEN_TOP_DPS, mYDp); + } + // TODO(twellington): Define a default value to use when determining if the condition is // satisfied for logging. }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/QuickAnswersHeuristic.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/QuickAnswersHeuristic.java index 85750b5..4d5ce34 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/QuickAnswersHeuristic.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/QuickAnswersHeuristic.java
@@ -55,4 +55,9 @@ wasSearchContentViewSeen, mIsConditionSatisfied, mDidAnswer); } } + + @Override + protected void logRankerTapSuppression(ContextualSearchRankerLogger logger) { + logger.log(ContextualSearchRankerLogger.Feature.OUTCOME_WAS_QUICK_ANSWER_SEEN, mDidAnswer); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/RecentScrollTapSuppression.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/RecentScrollTapSuppression.java index 8fda5dd0..bfdc715 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/RecentScrollTapSuppression.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/RecentScrollTapSuppression.java
@@ -75,4 +75,10 @@ protected boolean isConditionSatisfiedForAggregateLogging() { return !mIsEnabled && mIsConditionSatisfied; } + + @Override + protected void logRankerTapSuppression(ContextualSearchRankerLogger logger) { + logger.log(ContextualSearchRankerLogger.Feature.DURATION_AFTER_SCROLL_MS, + mDurationSinceRecentScrollMs); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppression.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppression.java index c585ba2..e652bd77 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppression.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppression.java
@@ -14,8 +14,6 @@ private static final int TAP_RADIUS_DPS = 30; private final boolean mIsTapSuppressionEnabled; - private final int mExperimentThresholdTaps; - private final int mTapsSinceOpen; private final float mPxToDp; private final boolean mIsSecondTap; private final boolean mIsConditionSatisfied; // whether to suppress or not. @@ -32,10 +30,8 @@ */ TapSuppression(ContextualSearchSelectionController controller, ContextualSearchTapState previousTapState, int x, int y, int tapsSinceOpen) { - mIsTapSuppressionEnabled = ContextualSearchFieldTrial.isTapSuppressionEnabled(); - mExperimentThresholdTaps = ContextualSearchFieldTrial.getSuppressionTaps(); + mIsTapSuppressionEnabled = false; mPxToDp = controller.getPxToDp(); - mTapsSinceOpen = tapsSinceOpen; mIsSecondTap = previousTapState != null && previousTapState.wasSuppressed() && !shouldHandleFirstTap(); @@ -68,7 +64,8 @@ * @return Whether a first tap should be handled or not. */ private boolean shouldHandleFirstTap() { - return mTapsSinceOpen < mExperimentThresholdTaps; + // TODO(donnd): enable with better logic. + return true; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemView.java index 8c9d1875..717c2b87 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadItemView.java
@@ -12,12 +12,12 @@ import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; -import android.widget.ProgressBar; import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.download.DownloadNotificationService; +import org.chromium.chrome.browser.widget.MaterialProgressBar; import org.chromium.chrome.browser.widget.TintedImageButton; import org.chromium.chrome.browser.widget.TintedImageView; import org.chromium.chrome.browser.widget.selection.SelectableItemView; @@ -51,7 +51,7 @@ private View mLayoutInProgress; private TextView mFilenameInProgressView; private TextView mDownloadStatusView; - private ProgressBar mProgressView; + private MaterialProgressBar mProgressView; private TintedImageButton mPauseResumeButton; private View mCancelButton; @@ -72,7 +72,7 @@ protected void onFinishInflate() { super.onFinishInflate(); mIconView = (TintedImageView) findViewById(R.id.icon_view); - mProgressView = (ProgressBar) findViewById(R.id.download_progress_view); + mProgressView = (MaterialProgressBar) findViewById(R.id.download_progress_view); mLayoutContainer = (LinearLayout) findViewById(R.id.layout_container); mLayoutCompleted = findViewById(R.id.completed_layout);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java index 9eb7542..3f4031ff 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java
@@ -10,7 +10,6 @@ import android.os.StatFs; import android.support.v7.widget.RecyclerView; import android.view.ViewGroup; -import android.widget.ProgressBar; import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; @@ -19,6 +18,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; +import org.chromium.chrome.browser.widget.MaterialProgressBar; import java.io.File; import java.util.concurrent.ExecutionException; @@ -108,7 +108,7 @@ private TextView mSpaceUsedByDownloadsTextView; private TextView mSpaceUsedByOtherAppsTextView; private TextView mSpaceFreeTextView; - private ProgressBar mSpaceBar; + private MaterialProgressBar mSpaceBar; private long mFreeBytes; SpaceDisplay(final ViewGroup parent, DownloadHistoryAdapter historyAdapter) { @@ -116,7 +116,7 @@ mSpaceUsedByDownloadsTextView = (TextView) parent.findViewById(R.id.size_downloaded); mSpaceUsedByOtherAppsTextView = (TextView) parent.findViewById(R.id.size_other_apps); mSpaceFreeTextView = (TextView) parent.findViewById(R.id.size_free); - mSpaceBar = (ProgressBar) parent.findViewById(R.id.space_bar); + mSpaceBar = (MaterialProgressBar) parent.findViewById(R.id.space_bar); mFileSystemBytesTask = new StorageSizeTask(true).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java index fc69c7c..bedf4696 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
@@ -12,6 +12,7 @@ import android.os.SystemClock; import android.provider.Browser; import android.text.TextUtils; +import android.util.Pair; import android.webkit.WebView; import org.chromium.base.CommandLine; @@ -45,6 +46,11 @@ private static final String SCHEME_WTAI_MC = "wtai://wp/mc;"; private static final String SCHEME_SMS = "sms"; + private static final String PLAY_PACKAGE_PARAM = "id"; + private static final String PLAY_REFERRER_PARAM = "referrer"; + private static final String PLAY_APP_PATH = "/store/apps/details"; + private static final String PLAY_HOSTNAME = "play.google.com"; + @VisibleForTesting static final String EXTRA_BROWSER_FALLBACK_URL = "browser_fallback_url"; @@ -332,13 +338,19 @@ // check whether the intent can be resolved. If not, we will see // whether we can download it from the Market. if (!canResolveActivity) { + Pair<String, String> appInfo = null; if (hasBrowserFallbackUrl) { - return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, params); + // If the fallback URL is a link to Play Store, send the user to Play Store app + // instead: crbug.com/638672. + appInfo = maybeGetPlayStoreAppIdAndReferrer(browserFallbackUrl); + if (appInfo == null) { + return clobberCurrentTabWithFallbackUrl(browserFallbackUrl, params); + } } - String packagename = intent.getPackage(); + String packagename = appInfo != null ? appInfo.first : intent.getPackage(); if (packagename != null) { - String marketReferrer = + String marketReferrer = appInfo != null ? appInfo.second : IntentUtils.safeGetStringExtra(intent, EXTRA_MARKET_REFERRER); if (TextUtils.isEmpty(marketReferrer)) { marketReferrer = mDelegate.getPackageName(); @@ -347,8 +359,8 @@ Uri marketUri = new Uri.Builder() .scheme("market") .authority("details") - .appendQueryParameter("id", packagename) - .appendQueryParameter("referrer", Uri.decode(marketReferrer)) + .appendQueryParameter(PLAY_PACKAGE_PARAM, packagename) + .appendQueryParameter(PLAY_REFERRER_PARAM, Uri.decode(marketReferrer)) .build(); intent = new Intent(Intent.ACTION_VIEW, marketUri); intent.addCategory(Intent.CATEGORY_BROWSABLE); @@ -565,11 +577,10 @@ */ private OverrideUrlLoadingResult clobberCurrentTabWithFallbackUrl( String browserFallbackUrl, ExternalNavigationParams params) { - if (!params.isMainFrame()) { - // For subframes, we don't support fallback url for now. - // http://crbug.com/364522. - return OverrideUrlLoadingResult.NO_OVERRIDE; - } + // For subframes, we don't support fallback url for now. + // http://crbug.com/364522. + if (!params.isMainFrame()) return OverrideUrlLoadingResult.NO_OVERRIDE; + // NOTE: any further redirection from fall-back URL should not override URL loading. // Otherwise, it can be used in chain for fingerprinting multiple app installation // status in one shot. In order to prevent this scenario, we notify redirection @@ -582,6 +593,21 @@ } /** + * If the given URL is to Google Play, extracts the package name and referrer tracking code + * from the {@param url} and returns as a Pair in that order. Otherwise returns null. + */ + private Pair<String, String> maybeGetPlayStoreAppIdAndReferrer(String url) { + Uri uri = Uri.parse(url); + if (PLAY_HOSTNAME.equals(uri.getHost()) && uri.getPath() != null + && uri.getPath().startsWith(PLAY_APP_PATH) + && !TextUtils.isEmpty(uri.getQueryParameter(PLAY_PACKAGE_PARAM))) { + return new Pair<String, String>(uri.getQueryParameter(PLAY_PACKAGE_PARAM), + uri.getQueryParameter(PLAY_REFERRER_PARAM)); + } + return null; + } + + /** * @return Whether the |url| could be handled by an external application on the system. */ public boolean canExternalAppHandleUrl(String url) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java index c4863018..b12225bb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java
@@ -227,10 +227,10 @@ description.setText(templateUrl.getShortName()); TextView url = (TextView) view.findViewById(R.id.url); - url.setText(templateUrl.getUrl()); + url.setText(templateUrl.getKeyword()); if (templateUrl.getType() == TemplateUrlService.TYPE_PREPOPULATED || templateUrl.getType() == TemplateUrlService.TYPE_DEFAULT - || templateUrl.getUrl().length() == 0) { + || templateUrl.getKeyword().length() == 0) { url.setVisibility(View.GONE); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java b/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java index c4fed06..2bdbd77 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/search_engines/TemplateUrlService.java
@@ -16,8 +16,6 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * Android wrapper of the TemplateUrlService which provides access from the Java @@ -64,24 +62,20 @@ public static class TemplateUrl { private final int mIndex; private final String mShortName; - private final String mUrl; private final boolean mIsPrepopulated; private final String mKeyword; @TemplateUrlType private int mTemplateUrlType; @CalledByNative("TemplateUrl") public static TemplateUrl create( - int id, String shortName, String url, boolean isPrepopulated, String keyword) { - return new TemplateUrl(id, shortName, url, isPrepopulated, keyword); + int id, String shortName, boolean isPrepopulated, String keyword) { + return new TemplateUrl(id, shortName, isPrepopulated, keyword); } public TemplateUrl( - int index, String shortName, String url, boolean isPrepopulated, String keyword) { + int index, String shortName, boolean isPrepopulated, String keyword) { mIndex = index; mShortName = shortName; - Pattern pattern = Pattern.compile("[^/]+.com"); - Matcher m = pattern.matcher(url); - mUrl = m.find() ? m.group(0) : ""; mIsPrepopulated = isPrepopulated; mKeyword = keyword; } @@ -94,10 +88,6 @@ return mShortName; } - public String getUrl() { - return mUrl; - } - public boolean getIsPrepopulated() { return mIsPrepopulated; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 948efd0..699d62e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -1132,8 +1132,6 @@ * @return The {@link ContentViewCore} associated with the current page. */ public ContentViewCore getActiveContentViewCore() { - // TODO(jinsukkim): Remove this along with the refactoring for Blimp. - // See https://crbug.com/650515. return mContentViewCore; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcher.java index 9a0a84e..5b50aa0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcher.java
@@ -22,15 +22,10 @@ /** Observes fetching of the Web Manifest. */ public interface Observer { /** - * Called when the Web Manifest for the initial URL load has been fetched (successfully or - * unsuccessfully). - * TODO(pkotwicz): Add calls to {@link #onFinishedFetchingWebManifestForInitialUrl()}. - * @param fetchedInfo The fetched Web Manifest data. Null if the initial URL does not point - * to a Web Manifest. - * @param bestIconUrl The icon URL in {@link fetchedInfo#iconUrlToMurmur2HashMap()} best - * suited for use as the launcher icon on this device. + * Called when the initial URL load has completed and the page has no Web Manifest or the + * Web Manifest is not WebAPK compatible. */ - void onFinishedFetchingWebManifestForInitialUrl(WebApkInfo fetchedInfo, String bestIconUrl); + void onWebManifestForInitialUrlNotWebApkCompatible(); /** * Called when the Web Manifest has been successfully fetched (including on the initial URL @@ -121,6 +116,15 @@ mObserver.onGotManifestData(info, bestIconUrl); } + /** + * Called when the initial URL load has completed and the page has no Web Manifest or the + * Web Manifest is not WebAPK compatible. + */ + @CalledByNative + private void onWebManifestForInitialUrlNotWebApkCompatible() { + mObserver.onWebManifestForInitialUrlNotWebApkCompatible(); + } + private native long nativeInitialize(String scope, String webManifestUrl); private native void nativeReplaceWebContents( long nativeWebApkUpdateDataFetcher, WebContents webContents);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java index f492fdfb..e9efda1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateManager.java
@@ -72,9 +72,8 @@ } @Override - public void onFinishedFetchingWebManifestForInitialUrl( - WebApkInfo fetchedInfo, String bestIconUrl) { - onGotManifestData(fetchedInfo, bestIconUrl); + public void onWebManifestForInitialUrlNotWebApkCompatible() { + onGotManifestData(null, null); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/MaterialProgressBar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/MaterialProgressBar.java new file mode 100644 index 0000000..74a5c2e --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/MaterialProgressBar.java
@@ -0,0 +1,243 @@ +// Copyright 2016 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. + +package org.chromium.chrome.browser.widget; + +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.support.v4.view.ViewCompat; +import android.util.AttributeSet; +import android.view.View; + +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.chrome.R; + +/** + * Material-styled horizontal progress bar + * + * This class is to be used in place of the support library's progress bar, which does not support + * indeterminate progress bar styling on JB or KK. + * + * ------------------------------------------------------------------------------------------------- + * DESIGN SPEC + * + * https://material.io/guidelines/components/progress-activity.html + * + * Secondary progress is represented by a second bar that is drawn on top of the primary progress, + * and is completely optional. + * + * ------------------------------------------------------------------------------------------------- + * DEFINING THE CONTROL STYLING IN AN XML LAYOUT + * + * Add the "chrome" namespace as an attribute to the main tag of the layout file: + * xmlns:chrome="http://schemas.android.com/apk/res-auto + * + * These attributes control styling of the bar: + * chrome:colorBackground Background color of the progress bar. + * chrome:colorProgress Represents progress along the determinate progress bar. + * Also used as the pulsing color. + * chrome:colorSecondaryProgress Represents secondary progress on top of the regular progress. + */ +public class MaterialProgressBar extends View implements AnimatorUpdateListener { + private static final long INDETERMINATE_ANIMATION_DURATION_MS = 3000; + + private final ValueAnimator mIndeterminateAnimator = ValueAnimator.ofFloat(0.0f, 3.0f); + private final Paint mBackgroundPaint = new Paint(); + private final Paint mProgressPaint = new Paint(); + private final Paint mSecondaryProgressPaint = new Paint(); + + private boolean mIsIndeterminate; + private int mProgress; + private int mSecondaryProgress; + + public MaterialProgressBar(Context context) { + super(context); + initialize(context, null, 0); + } + + public MaterialProgressBar(Context context, AttributeSet attrs) { + super(context, attrs); + initialize(context, attrs, 0); + } + + public MaterialProgressBar(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + initialize(context, attrs, defStyle); + } + + /** Sets the background color, corresponding to "chrome:colorBackground". */ + @Override + public void setBackgroundColor(int color) { + mBackgroundPaint.setColor(color); + postInvalidateOnAnimation(); + } + + /** Sets the progress color, corresponding to "chrome:colorProgress". */ + public void setProgressColor(int color) { + mProgressPaint.setColor(color); + postInvalidateOnAnimation(); + } + + /** Sets the secondary color, corresponding to "chrome:colorSecondaryProgress". */ + public void setSecondaryProgressColor(int color) { + mSecondaryProgressPaint.setColor(color); + postInvalidateOnAnimation(); + } + + /** + * Sets the progress value being displayed. + * @param progress Progress value, ranging from 0 to 100. Will be clamped into the range. + */ + public void setProgress(int progress) { + mProgress = Math.max(0, Math.min(100, progress)); + postInvalidateOnAnimation(); + } + + /** + * Sets the secondary progress value being displayed. + * @param progress Progress value, ranging from 0 to 100. Will be clamped into the range. + */ + public void setSecondaryProgress(int progress) { + mSecondaryProgress = Math.max(0, Math.min(100, progress)); + postInvalidateOnAnimation(); + } + + /** Sets whether the progress bar is indeterminate or not. */ + public void setIndeterminate(boolean indeterminate) { + if (mIsIndeterminate == indeterminate) return; + mIsIndeterminate = indeterminate; + + if (mIsIndeterminate) startIndeterminateAnimation(); + postInvalidateOnAnimation(); + } + + @Override + public void setVisibility(int visibility) { + super.setVisibility(visibility); + if (visibility == View.VISIBLE) { + startIndeterminateAnimation(); + } else { + stopIndeterminateAnimation(); + } + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + postInvalidateOnAnimation(); + } + + @Override + public void onDraw(Canvas canvas) { + if (mIsIndeterminate) { + drawIndeterminateBar(canvas); + } else { + drawDeterminateBar(canvas); + } + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + startIndeterminateAnimation(); + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + stopIndeterminateAnimation(); + } + + private void initialize(Context context, AttributeSet attrs, int defStyle) { + Resources resources = context.getResources(); + int backgroundColor = + ApiCompatibilityUtils.getColor(resources, R.color.progress_bar_background); + int progressColor = + ApiCompatibilityUtils.getColor(resources, R.color.progress_bar_foreground); + int secondaryProgressColor = + ApiCompatibilityUtils.getColor(resources, R.color.progress_bar_secondary); + + if (attrs != null) { + TypedArray a = context.obtainStyledAttributes( + attrs, R.styleable.MaterialProgressBar, defStyle, 0); + backgroundColor = + a.getColor(R.styleable.MaterialProgressBar_colorBackground, backgroundColor); + progressColor = + a.getColor(R.styleable.MaterialProgressBar_colorProgress, progressColor); + secondaryProgressColor = a.getColor( + R.styleable.MaterialProgressBar_colorSecondaryProgress, secondaryProgressColor); + a.recycle(); + } + + setBackgroundColor(backgroundColor); + setProgressColor(progressColor); + setSecondaryProgressColor(secondaryProgressColor); + + mIndeterminateAnimator.setRepeatCount(ValueAnimator.INFINITE); + mIndeterminateAnimator.setDuration(INDETERMINATE_ANIMATION_DURATION_MS); + mIndeterminateAnimator.addUpdateListener(this); + } + + private void startIndeterminateAnimation() { + if (!mIsIndeterminate || mIndeterminateAnimator.isRunning()) return; + if (!ViewCompat.isAttachedToWindow(this) || getVisibility() != View.VISIBLE) return; + mIndeterminateAnimator.start(); + } + + private void stopIndeterminateAnimation() { + if (!mIndeterminateAnimator.isRunning()) return; + mIndeterminateAnimator.cancel(); + } + + private void drawIndeterminateBar(Canvas canvas) { + int width = canvas.getWidth(); + drawRect(canvas, mBackgroundPaint, 0, width); + + // The first pulse fires off at the beginning of the animation. + float value = (Float) mIndeterminateAnimator.getAnimatedValue(); + float left = width * (float) (Math.pow(value, 1.5f) - 0.5f); + float right = width * value; + drawRect(canvas, mProgressPaint, left, right); + + // The second pulse fires off at some point after the first pulse has been fired. + final float secondPulseStart = 1.1f; + final float secondPulseLength = 1.0f; + if (value >= secondPulseStart) { + float percentage = (value - secondPulseStart) / secondPulseLength; + left = width * (float) (Math.pow(percentage, 3.0f) - 0.1f); + right = width * percentage; + drawRect(canvas, mProgressPaint, left, right); + } + } + + private void drawDeterminateBar(Canvas canvas) { + int width = canvas.getWidth(); + drawRect(canvas, mBackgroundPaint, 0, width); + + if (mProgress > 0) { + float percentage = mProgress / 100.0f; + drawRect(canvas, mProgressPaint, 0, width * percentage); + } + + if (mSecondaryProgress > 0) { + float percentage = mSecondaryProgress / 100.0f; + drawRect(canvas, mSecondaryProgressPaint, 0, width * percentage); + } + } + + private void drawRect(Canvas canvas, Paint paint, float start, float end) { + if (ViewCompat.getLayoutDirection(this) == View.LAYOUT_DIRECTION_RTL) { + int width = canvas.getWidth(); + float rtlStart = width - end; + float rtlEnd = width - start; + canvas.drawRect(rtlStart, 0, rtlEnd, canvas.getHeight(), paint); + } else { + canvas.drawRect(start, 0, end, canvas.getHeight(), paint); + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/SlowedProgressBar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/SlowedProgressBar.java deleted file mode 100644 index 7767e9c..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/SlowedProgressBar.java +++ /dev/null
@@ -1,109 +0,0 @@ -// Copyright 2015 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. - -package org.chromium.chrome.browser.widget; - -import android.content.Context; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.widget.ProgressBar; - -import org.chromium.base.annotations.SuppressFBWarnings; - -/** - * A throttled version of {@link ProgressBar}. This steals calls to - * {@link android.view.View#postInvalidateOnAnimation} and delays them if necessary to reach a - * specific FPS. - */ -public class SlowedProgressBar extends ProgressBar { - private long mLastDrawTimeMs; - private boolean mPendingInvalidation; - private static final int MIN_MS_PER_FRAME = 66; - private int mTargetProgress; - - private final Runnable mInvalidationRunnable = new Runnable() { - @Override - public void run() { - mPendingInvalidation = false; - invalidate(); - } - }; - - private final Runnable mUpdateProgressRunnable = new Runnable() { - @Override - public void run() { - setProgressInternal(mTargetProgress); - } - }; - - /** - * Create a new progress bar with range 0...100 and initial progress of 0. - * @param context the application environment. - */ - public SlowedProgressBar(Context context) { - super(context, null); - } - - /** - * Create a new progress bar with range 0...100 and initial progress of 0. - * @param context the application environment. - * @param attrs the xml attributes that should be used to initialize this view. - */ - public SlowedProgressBar(Context context, AttributeSet attrs) { - super(context, attrs); - } - - /** - * Create a new progress bar with range 0...100 and initial progress of 0. - * @param context the application environment. - * @param attrs the xml attributes that should be used to initialize this view. - * @param defStyle the default style to apply to this view. - */ - public SlowedProgressBar(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - /** - * Keep track of the last time we drew. - */ - @Override - public void onDraw(Canvas canvas) { - mLastDrawTimeMs = System.currentTimeMillis(); - super.onDraw(canvas); - } - - /** - * Delay invalidations to be no more than 1 per MIN_MS_PER_FRAME; - * never allow more than one invalidation outstanding. - */ - @Override - public void postInvalidateOnAnimation() { - if (mPendingInvalidation) return; - long nextDrawTime = mLastDrawTimeMs + MIN_MS_PER_FRAME; - long delay = Math.max(0, nextDrawTime - System.currentTimeMillis()); - mPendingInvalidation = true; - postOnAnimationDelayed(mInvalidationRunnable, delay); - } - - /** - * Ensure invalidations always occurs in the scope of animation. - * @param progress The progress value to set the visuals to. - */ - @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD") - @Override - public synchronized void setProgress(int progress) { - if (mTargetProgress == progress) return; - mTargetProgress = progress; - removeCallbacks(mUpdateProgressRunnable); - postOnAnimation(mUpdateProgressRunnable); - } - - /** - * Called to update the progress visuals. - * @param progress The progress value to set the visuals to. - */ - protected void setProgressInternal(int progress) { - super.setProgress(progress); - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/SmoothProgressBar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/SmoothProgressBar.java deleted file mode 100644 index 2f9f47f..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/SmoothProgressBar.java +++ /dev/null
@@ -1,154 +0,0 @@ -// Copyright 2015 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. - -package org.chromium.chrome.browser.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.ProgressBar; - -import org.chromium.base.ObserverList; -import org.chromium.base.ObserverList.RewindableIterator; - -/** - * A progress bar that smoothly animates incremental updates. - * <p> - * Consumers of this class need to be aware that calls to {@link #getProgress()} will return - * the currently visible progress value and not the one set in the last call to - * {@link #setProgress(int)}. - */ -public class SmoothProgressBar extends ProgressBar { - - /** - * Allows observation of visual changes to the progress bar. - */ - public interface ProgressChangeListener { - /** - * Triggered when the visible progress has changed. - * @param progress The current progress value. - */ - void onProgressChanged(int progress); - - /** - * Triggered when the visibility of the progress bar has changed. - * @param visibility The visibility of the progress bar. - */ - void onProgressVisibilityChanged(int visibility); - } - - private static final int MAX = 100; - - // The amount of time between subsequent progress updates. 16ms is chosen to make 60fps. - private static final long PROGRESS_UPDATE_DELAY_MS = 16; - - private final ObserverList<ProgressChangeListener> mObservers; - private final RewindableIterator<ProgressChangeListener> mObserversIterator; - - private boolean mIsAnimated; - private int mTargetProgress; - - // Since the progress bar is being animated, the internal progress bar resolution should be - // at least fine as the width, not MAX. This multiplier will be applied to input progress - // to convert to a finer scale. - private int mResolutionMutiplier = 1; - - private Runnable mUpdateProgressRunnable = new Runnable() { - @Override - public void run() { - if (getProgress() == mTargetProgress) return; - if (!mIsAnimated) { - setProgressInternal(mTargetProgress); - return; - } - // Every time, the progress bar get's at least 20% closer to mTargetProcess. - // Add 3 to guarantee progressing even if they only differ by 1. - setProgressInternal(getProgress() + (mTargetProgress - getProgress() + 3) / 4); - postOnAnimationDelayed(this, PROGRESS_UPDATE_DELAY_MS); - } - }; - - /** - * Create a new progress bar with range 0...100 and initial progress of 0. - * @param context the application environment. - * @param attrs the xml attributes that should be used to initialize this view. - */ - public SmoothProgressBar(Context context, AttributeSet attrs) { - super(context, attrs); - setMax(MAX * mResolutionMutiplier); - - mObservers = new ObserverList<ProgressChangeListener>(); - mObserversIterator = mObservers.rewindableIterator(); - - } - - /** - * Adds an observer to be notified of progress changes. - * @param observer The observer to be added. - */ - public void addProgressChangeListener(ProgressChangeListener observer) { - mObservers.addObserver(observer); - } - - /** - * Removes an observer to be notified of progress changes. - * @param observer The observer to be removed. - */ - public void removeProgressChangeListener(ProgressChangeListener observer) { - mObservers.removeObserver(observer); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - - int normalizedProgress = getProgress() / mResolutionMutiplier; - - // Choose an integer resolution multiplier that makes the scale at least fine as the width. - mResolutionMutiplier = Math.max(1, (w + MAX - 1) / MAX); - setMax(mResolutionMutiplier * MAX); - setProgressInternal(normalizedProgress * mResolutionMutiplier); - } - - @Override - public void setProgress(int progress) { - final int targetProgress = progress * mResolutionMutiplier; - if (mTargetProgress == targetProgress) return; - mTargetProgress = targetProgress; - removeCallbacks(mUpdateProgressRunnable); - postOnAnimation(mUpdateProgressRunnable); - } - - /** - * Sets whether to animate incremental updates or not. - * @param isAnimated True if it is needed to animate incremental updates. - */ - public void setAnimated(boolean isAnimated) { - mIsAnimated = isAnimated; - } - - /** - * Called to update the progress visuals. - * @param progress The progress value to set the visuals to. - */ - protected void setProgressInternal(int progress) { - super.setProgress(progress); - - if (mObserversIterator != null) { - for (mObserversIterator.rewind(); mObserversIterator.hasNext();) { - mObserversIterator.next().onProgressChanged(progress); - } - } - } - - @Override - public void setVisibility(int visibility) { - super.setVisibility(visibility); - - if (mObserversIterator != null) { - for (mObserversIterator.rewind(); mObserversIterator.hasNext();) { - mObserversIterator.next().onProgressVisibilityChanged(visibility); - } - } - } -}
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index e3fffa1..feb9767 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -237,6 +237,8 @@ "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchNetworkCommunicator.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchObserver.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java", + "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLogger.java", + "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRequest.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java", "java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionHandler.java", @@ -1088,6 +1090,7 @@ "java/src/org/chromium/chrome/browser/widget/FadingShadowView.java", "java/src/org/chromium/chrome/browser/widget/FloatLabelLayout.java", "java/src/org/chromium/chrome/browser/widget/LoadingView.java", + "java/src/org/chromium/chrome/browser/widget/MaterialProgressBar.java", "java/src/org/chromium/chrome/browser/widget/NumberRollView.java", "java/src/org/chromium/chrome/browser/widget/OverviewListLayout.java", "java/src/org/chromium/chrome/browser/widget/PaddedFrameLayout.java", @@ -1096,8 +1099,6 @@ "java/src/org/chromium/chrome/browser/widget/ProgressAnimationSmooth.java", "java/src/org/chromium/chrome/browser/widget/RadioButtonWithDescription.java", "java/src/org/chromium/chrome/browser/widget/RoundedIconGenerator.java", - "java/src/org/chromium/chrome/browser/widget/SlowedProgressBar.java", - "java/src/org/chromium/chrome/browser/widget/SmoothProgressBar.java", "java/src/org/chromium/chrome/browser/widget/TextBubble.java", "java/src/org/chromium/chrome/browser/widget/TintedDrawable.java", "java/src/org/chromium/chrome/browser/widget/TintedImageButton.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index 7b29f81..4ee4ddf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -2003,7 +2003,6 @@ */ @SmallTest @Feature({"ContextualSearch"}) - @CommandLineFlags.Add(ContextualSearchFieldTrial.SUPPRESSION_TAPS + "=" + PLENTY_OF_TAPS) public void testTapALot() throws InterruptedException, TimeoutException { mPolicy.setTapLimitForDecidedForTesting(PLENTY_OF_TAPS); mPolicy.setTapLimitForUndecidedForTesting(PLENTY_OF_TAPS);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java index 1624199f..8be64f1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java
@@ -682,6 +682,38 @@ } @SmallTest + public void testFallbackUrl_FallbackToMarketApp() { + mDelegate.setCanResolveActivity(false); + + String intent = "intent:///name/nm0000158#Intent;scheme=imdb;package=com.imdb.mobile;" + + "S." + ExternalNavigationHandler.EXTRA_BROWSER_FALLBACK_URL + "=" + + "https://play.google.com/store/apps/details?id=com.imdb.mobile" + + "&referrer=mypage;end"; + checkUrl(intent) + .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, + START_OTHER_ACTIVITY); + + assertEquals("market://details?id=com.imdb.mobile&referrer=mypage", + mDelegate.startActivityIntent.getDataString()); + + String intentNoRef = "intent:///name/nm0000158#Intent;scheme=imdb;package=com.imdb.mobile;" + + "S." + ExternalNavigationHandler.EXTRA_BROWSER_FALLBACK_URL + "=" + + "https://play.google.com/store/apps/details?id=com.imdb.mobile;end"; + checkUrl(intentNoRef) + .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, + START_OTHER_ACTIVITY); + + assertEquals("market://details?id=com.imdb.mobile&referrer=test", + mDelegate.startActivityIntent.getDataString()); + + String intentBadUrl = "intent:///name/nm0000158#Intent;scheme=imdb;package=com.imdb.mobile;" + + "S." + ExternalNavigationHandler.EXTRA_BROWSER_FALLBACK_URL + "=" + + "https://play.google.com/store/search?q=pub:imdb;end"; + checkUrl(intentBadUrl) + .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_CLOBBERING_TAB, IGNORE); + } + + @SmallTest public void testFallbackUrl_IntentResolutionFailsWithoutPackageName() { // IMDB app isn't installed. mDelegate.setCanResolveActivity(false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcherTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcherTest.java index 42ce3dc2..d69c5fa0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcherTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateDataFetcherTest.java
@@ -13,6 +13,7 @@ import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeTabbedActivityTestBase; +import org.chromium.chrome.test.util.browser.TabLoadObserver; import org.chromium.chrome.test.util.browser.WebappTestPage; import org.chromium.net.test.EmbeddedTestServer; @@ -49,26 +50,29 @@ // callback is called. private static class CallbackWaiter extends CallbackHelper implements WebApkUpdateDataFetcher.Observer { + private boolean mWebApkCompatible; private String mName; private String mBestIconMurmur2Hash; @Override - public void onFinishedFetchingWebManifestForInitialUrl( - WebApkInfo fetchedInfo, String bestIconUrl) { - assertNull(mName); - mName = fetchedInfo.name(); - mBestIconMurmur2Hash = fetchedInfo.iconUrlToMurmur2HashMap().get(bestIconUrl); + public void onWebManifestForInitialUrlNotWebApkCompatible() { + mWebApkCompatible = false; notifyCalled(); } @Override public void onGotManifestData(WebApkInfo fetchedInfo, String bestIconUrl) { assertNull(mName); + mWebApkCompatible = true; mName = fetchedInfo.name(); mBestIconMurmur2Hash = fetchedInfo.iconUrlToMurmur2HashMap().get(bestIconUrl); notifyCalled(); } + public boolean isWebApkCompatible() { + return mWebApkCompatible; + } + public String name() { return mName; } @@ -97,13 +101,11 @@ startMainActivityOnBlankPage(); } - /** - * Starts a WebApkUpdateDataFetcher. Calls {@link callback} once the fetcher is done. - */ + /** Creates and starts a WebApkUpdateDataFetcher. */ private void startWebApkUpdateDataFetcher(final String scopeUrl, final String manifestUrl, final WebApkUpdateDataFetcher.Observer observer) { final WebApkUpdateDataFetcher fetcher = new WebApkUpdateDataFetcher(); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { + ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { WebApkInfo oldInfo = WebApkInfo.create("", "", scopeUrl, null, null, null, -1, -1, @@ -120,14 +122,15 @@ @MediumTest @Feature({"WebApk"}) public void testLaunchWithDesiredManifestUrl() throws Exception { + WebappTestPage.navigateToPageWithServiceWorkerAndManifest( + mTestServer, mTab, WEB_MANIFEST_URL1); + CallbackWaiter waiter = new CallbackWaiter(); startWebApkUpdateDataFetcher(mTestServer.getURL(WEB_MANIFEST_SCOPE), mTestServer.getURL(WEB_MANIFEST_URL1), waiter); - - WebappTestPage.navigateToPageWithServiceWorkerAndManifest( - mTestServer, mTab, WEB_MANIFEST_URL1); waiter.waitForCallback(0); + assertTrue(waiter.isWebApkCompatible()); assertEquals(WEB_MANIFEST_NAME1, waiter.name()); } @@ -140,31 +143,52 @@ @Feature({"Webapps"}) @RetryOnFailure public void testLaunchWithDifferentManifestUrl() throws Exception { + WebappTestPage.navigateToPageWithServiceWorkerAndManifest( + mTestServer, mTab, WEB_MANIFEST_URL1); + CallbackWaiter waiter = new CallbackWaiter(); startWebApkUpdateDataFetcher(mTestServer.getURL(WEB_MANIFEST_SCOPE), mTestServer.getURL(WEB_MANIFEST_URL2), waiter); + waiter.waitForCallback(0); + assertFalse(waiter.isWebApkCompatible()); WebappTestPage.navigateToPageWithServiceWorkerAndManifest( - mTestServer, mTab, WEB_MANIFEST_URL1); - WebappTestPage.navigateToPageWithServiceWorkerAndManifest( mTestServer, mTab, WEB_MANIFEST_URL2); - waiter.waitForCallback(0); - + waiter.waitForCallback(1); + assertTrue(waiter.isWebApkCompatible()); assertEquals(WEB_MANIFEST_NAME2, waiter.name()); } /** + * Test that {@link onWebManifestForInitialUrlNotWebApkCompatible()} is called after attempting + * to fetch Web Manifest for page with no Web Manifest. + */ + @MediumTest + @Feature({"Webapps"}) + public void testNoWebManifest() throws Exception { + new TabLoadObserver(mTab).fullyLoadUrl( + mTestServer.getURL("/chrome/test/data/banners/no_manifest_test_page.html")); + + CallbackWaiter waiter = new CallbackWaiter(); + startWebApkUpdateDataFetcher(mTestServer.getURL(WEB_MANIFEST_SCOPE), + mTestServer.getURL(WEB_MANIFEST_URL2), waiter); + waiter.waitForCallback(0); + assertFalse(waiter.isWebApkCompatible()); + } + + /** * Test that large icon murmur2 hashes are correctly plumbed to Java. The hash can take on * values up to 2^64 - 1 which is greater than {@link Long#MAX_VALUE}. */ @MediumTest @Feature({"Webapps"}) public void testLargeIconMurmur2Hash() throws Exception { + WebappTestPage.navigateToPageWithServiceWorkerAndManifest( + mTestServer, mTab, WEB_MANIFEST_WITH_LONG_ICON_MURMUR2_HASH); + CallbackWaiter waiter = new CallbackWaiter(); startWebApkUpdateDataFetcher(mTestServer.getURL(WEB_MANIFEST_SCOPE), mTestServer.getURL(WEB_MANIFEST_WITH_LONG_ICON_MURMUR2_HASH), waiter); - WebappTestPage.navigateToPageWithServiceWorkerAndManifest( - mTestServer, mTab, WEB_MANIFEST_WITH_LONG_ICON_MURMUR2_HASH); waiter.waitForCallback(0); assertEquals(LONG_ICON_MURMUR2_HASH, waiter.bestIconMurmur2Hash());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java index 6c2cbc2a..94e0b1c6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java
@@ -63,9 +63,8 @@ } @Override - public void onFinishedFetchingWebManifestForInitialUrl( - WebApkInfo fetchedInfo, String bestIconUrl) { - super.onFinishedFetchingWebManifestForInitialUrl(fetchedInfo, bestIconUrl); + public void onWebManifestForInitialUrlNotWebApkCompatible() { + super.onWebManifestForInitialUrlNotWebApkCompatible(); mWaiter.notifyCalled(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java index ba8cb74..db94191d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/findinpage/FindTest.java
@@ -227,29 +227,6 @@ } /** - * Verify that Next/Previous buttons are disabled whenever there is no match. - */ - @MediumTest - @Feature({"FindInPage"}) - @RetryOnFailure - public void testFindNextPreviousOnNoMatch() throws InterruptedException { - loadTestAndVerifyFindInPage("pp", "0/0"); - - final TextView findQueryText = getFindQueryText(); - View next = getActivity().findViewById(R.id.find_next_button); - View prev = getActivity().findViewById(R.id.find_prev_button); - assertFalse(next.isEnabled()); - assertFalse(prev.isEnabled()); - - KeyUtils.singleKeyEventView(getInstrumentation(), findQueryText, KeyEvent.KEYCODE_DEL); - KeyUtils.singleKeyEventView(getInstrumentation(), findQueryText, KeyEvent.KEYCODE_DEL); - - loadTestAndVerifyFindInPage("pitts", "1/7"); - assertTrue(next.isEnabled()); - assertTrue(prev.isEnabled()); - } - - /** * Verify that Find in page toolbar is dismissed on entering fullscreen. */ @MediumTest
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java index 616a1e2..bca36a9 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java
@@ -264,15 +264,8 @@ updateManager.updateIfNeeded(null, info); } - private static void onGotUnchangedWebManifestForInitialUrl(WebApkUpdateManager updateManager) { - onFinishedFetchingWebManifestForInitialUrl(updateManager, defaultManifestData()); - } - - private static void onFinishedFetchingWebManifestForInitialUrl( - WebApkUpdateManager updateManager, ManifestData fetchedManifestData) { - String bestIconUrl = randomIconUrl(fetchedManifestData); - updateManager.onFinishedFetchingWebManifestForInitialUrl( - infoFromManifestData(fetchedManifestData), bestIconUrl); + private static void onGotUnchangedWebManifestData(WebApkUpdateManager updateManager) { + onGotManifestData(updateManager, defaultManifestData()); } private static void onGotManifestData(WebApkUpdateManager updateManager, @@ -310,7 +303,7 @@ TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClock); updateIfNeeded(updateManager); assertTrue(updateManager.updateCheckStarted()); - updateManager.onFinishedFetchingWebManifestForInitialUrl( + updateManager.onGotManifestData( infoFromManifestData(fetchedManifestData), fetchedManifestData.bestIconUrl); return updateManager.updateRequested(); } @@ -406,15 +399,16 @@ assertTrue(updateManager.updateCheckStarted()); } - // Chrome is killed. - // {@link WebApkUpdateManager#onFinishedFetchingWebManifestForInitialUrl()} is never called. + // Chrome is killed. Neither + // {@link WebApkUpdateManager#onWebManifestForInitialUrlNotWebApkCompatible()} nor + // {@link WebApkUpdateManager#OnGotManifestData()} is called. { // Relaunching the WebAPK should do an is-update-needed check. TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClock); updateIfNeeded(updateManager); assertTrue(updateManager.updateCheckStarted()); - onGotUnchangedWebManifestForInitialUrl(updateManager); + onGotUnchangedWebManifestData(updateManager); } { @@ -439,7 +433,7 @@ TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClock); updateIfNeeded(updateManager); assertTrue(updateManager.updateCheckStarted()); - onGotUnchangedWebManifestForInitialUrl(updateManager); + onGotUnchangedWebManifestData(updateManager); assertFalse(updateManager.updateRequested()); WebappDataStorage storage = getStorage(); @@ -462,7 +456,7 @@ TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClock); updateIfNeeded(updateManager); assertTrue(updateManager.updateCheckStarted()); - onGotUnchangedWebManifestForInitialUrl(updateManager); + onGotUnchangedWebManifestData(updateManager); assertFalse(updateManager.updateRequested()); assertTrue(storage.getDidLastWebApkUpdateRequestSucceed()); @@ -483,7 +477,7 @@ assertTrue(updateManager.updateCheckStarted()); ManifestData manifestData = defaultManifestData(); manifestData.name = DIFFERENT_NAME; - onFinishedFetchingWebManifestForInitialUrl(updateManager, manifestData); + onGotManifestData(updateManager, manifestData); assertTrue(updateManager.updateRequested()); // Chrome is killed. {@link WebApkUpdateManager#onBuiltWebApk} is never called. @@ -513,12 +507,12 @@ updateIfNeeded(updateManager); assertTrue(updateManager.updateCheckStarted()); - onFinishedFetchingWebManifestForInitialUrl(updateManager, null); + updateManager.onWebManifestForInitialUrlNotWebApkCompatible(); assertTrue(updateManager.updateRequested()); assertEquals(NAME, updateManager.requestedUpdateName()); // Check that the {@link ManifestUpgradeDetector} has been destroyed. This prevents - // {@link #onFinishedFetchingWebManifestForInitialUrl()} and {@link #onGotManifestData()} + // {@link #onWebManifestForInitialUrlNotWebApkCompatible()} and {@link #onGotManifestData()} // from getting called. assertTrue(updateManager.destroyedFetcher()); } @@ -536,7 +530,7 @@ updateIfNeeded(updateManager); assertTrue(updateManager.updateCheckStarted()); - onFinishedFetchingWebManifestForInitialUrl(updateManager, defaultManifestData()); + onGotManifestData(updateManager, defaultManifestData()); assertTrue(updateManager.updateRequested()); assertEquals(NAME, updateManager.requestedUpdateName()); @@ -562,7 +556,7 @@ assertTrue(updateManager.updateCheckStarted()); // start_url does not have a Web Manifest. No update should be requested. - onFinishedFetchingWebManifestForInitialUrl(updateManager, null); + updateManager.onWebManifestForInitialUrlNotWebApkCompatible(); assertFalse(updateManager.updateRequested()); // {@link ManifestUpgradeDetector} should still be alive so that it can get // {@link #onGotManifestData} when page with the Web Manifest finishes loading. @@ -593,7 +587,7 @@ TestWebApkUpdateManager updateManager = new TestWebApkUpdateManager(mClock); updateIfNeeded(updateManager); - onFinishedFetchingWebManifestForInitialUrl(updateManager, null); + updateManager.onWebManifestForInitialUrlNotWebApkCompatible(); onGotManifestData(updateManager, defaultManifestData()); assertFalse(updateManager.updateRequested());
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 3b9ad979..11e4ded 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2002,6 +2002,7 @@ deps += [ "//chrome/browser/safe_browsing:chunk_proto", "//chrome/common/safe_browsing:proto", + "//components/safe_browsing:safe_browsing", "//components/safe_browsing/common:common", "//components/safe_browsing_db:metadata_proto", "//components/security_interstitials/content:unsafe_resource",
diff --git a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc index a5a20efe..c1179ee 100644 --- a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc +++ b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
@@ -55,6 +55,7 @@ : content::WebContentsObserver(nullptr), scope_(scope), web_manifest_url_(web_manifest_url), + is_initial_fetch_(false), info_(GURL()), weak_ptr_factory_(this) { java_ref_.Reset(env, obj); @@ -102,10 +103,13 @@ // installable data the first time. if (url == last_fetched_url_) return; + is_initial_fetch_ = last_fetched_url_.is_empty(); last_fetched_url_ = url; - if (!IsInScope(url, scope_)) + if (!IsInScope(url, scope_)) { + OnWebManifestNotWebApkCompatible(); return; + } InstallableParams params; params.ideal_icon_size_in_dp = @@ -125,21 +129,24 @@ void WebApkUpdateDataFetcher::OnDidGetInstallableData( const InstallableData& data) { - // If the manifest is empty, it means the current WebContents doesn't - // associate with a Web Manifest. In such case, we ignore the empty manifest - // and continue observing the WebContents's loading until we find a page that - // links to the Web Manifest that we are looking for. + // Determine whether or not the manifest is WebAPK-compatible. There are 3 + // cases: + // 1. the site isn't installable. + // 2. the URLs in the manifest expose passwords. + // 3. there is no manifest or the manifest is different to the one we're + // expecting. + // For case 3, if the manifest is empty, it means the current WebContents + // doesn't associate with a Web Manifest. In such case, we ignore the empty + // manifest and continue observing the WebContents's loading until we find a + // page that links to the Web Manifest that we are looking for. // If the manifest URL is different from the current one, we will continue // observing too. It is based on our assumption that it is invalid for // web developers to change the Web Manifest location. When it does // change, we will treat the new Web Manifest as the one of another WebAPK. - if (data.manifest.IsEmpty() || web_manifest_url_ != data.manifest_url) - return; - - // TODO(pkotwicz): Tell Java side that the Web Manifest was fetched but the - // Web Manifest is not WebAPK-compatible. (http://crbug.com/639536) if (data.error_code != NO_ERROR_DETECTED || + data.manifest.IsEmpty() || web_manifest_url_ != data.manifest_url || !AreWebManifestUrlsWebApkCompatible(data.manifest)) { + OnWebManifestNotWebApkCompatible(); return; } @@ -163,8 +170,7 @@ icon_hasher_.reset(); if (best_icon_murmur2_hash.empty()) { - // TODO(pkotwicz): Tell Java side that the Web Manifest was fetched but the - // Web Manifest is not WebAPK-compatible. (http://crbug.com/639536) + OnWebManifestNotWebApkCompatible(); return; } @@ -201,3 +207,11 @@ java_icon_urls, info.display, info.orientation, info.theme_color, info.background_color); } + +void WebApkUpdateDataFetcher::OnWebManifestNotWebApkCompatible() { + if (!is_initial_fetch_) + return; + + Java_WebApkUpdateDataFetcher_onWebManifestForInitialUrlNotWebApkCompatible( + base::android::AttachCurrentThread(), java_ref_); +}
diff --git a/chrome/browser/android/webapk/webapk_update_data_fetcher.h b/chrome/browser/android/webapk/webapk_update_data_fetcher.h index 6bc7885..03f3dac 100644 --- a/chrome/browser/android/webapk/webapk_update_data_fetcher.h +++ b/chrome/browser/android/webapk/webapk_update_data_fetcher.h
@@ -68,6 +68,10 @@ const std::string& best_icon_murmur2_hash, const SkBitmap& best_icon); + // Called when a page has no Web Manifest or the Web Manifest is not WebAPK + // compatible. + void OnWebManifestNotWebApkCompatible(); + // Points to the Java object. base::android::ScopedJavaGlobalRef<jobject> java_ref_; @@ -77,6 +81,9 @@ // The WebAPK's Web Manifest URL that the detector is looking for. const GURL web_manifest_url_; + // Whether this is the initial URL fetch. + bool is_initial_fetch_; + // The URL for which the installable data is being fetched / was last fetched. GURL last_fetched_url_;
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index ebb38e3f..974c2ff0 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -612,6 +612,10 @@ <include name="IDR_CHROME_CONTENT_PLUGIN_MANIFEST_OVERLAY" file="chrome_content_plugin_manifest_overlay.json" type="BINDATA" /> <include name="IDR_CHROME_CONTENT_RENDERER_MANIFEST_OVERLAY" file="chrome_content_renderer_manifest_overlay.json" type="BINDATA" /> <include name="IDR_CHROME_CONTENT_UTILITY_MANIFEST_OVERLAY" file="chrome_content_utility_manifest_overlay.json" type="BINDATA" /> + <include name="IDR_NACL_LOADER_MANIFEST" file="../../components/nacl/loader/nacl_loader_manifest.json" type="BINDATA" /> + <if expr="is_win"> + <include name="IDR_NACL_BROKER_MANIFEST" file="../../components/nacl/broker/nacl_broker_manifest.json" type="BINDATA" /> + </if> </includes> </release> </grit>
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index dbdaad2..7bfe7f13 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -134,6 +134,7 @@ #include "components/google/core/browser/google_util.h" #include "components/metrics/call_stack_profile_collector.h" #include "components/metrics/client_info.h" +#include "components/nacl/common/nacl_constants.h" #include "components/net_log/chrome_net_log.h" #include "components/password_manager/content/browser/content_password_manager_driver_factory.h" #include "components/payments/payment_request.mojom.h" @@ -3095,8 +3096,7 @@ } std::unique_ptr<base::Value> -ChromeContentBrowserClient::GetServiceManifestOverlay( - const std::string& name) { +ChromeContentBrowserClient::GetServiceManifestOverlay(base::StringPiece name) { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); int id = -1; if (name == content::mojom::kBrowserServiceName) @@ -3117,6 +3117,18 @@ return base::JSONReader::Read(manifest_contents); } +std::vector<content::ContentBrowserClient::ServiceManifestInfo> +ChromeContentBrowserClient::GetExtraServiceManifests() { + return std::vector<content::ContentBrowserClient::ServiceManifestInfo>({ +#if !defined(DISABLE_NACL) + {nacl::kNaClLoaderServiceName, IDR_NACL_LOADER_MANIFEST}, +#if defined(OS_WIN) + {nacl::kNaClBrokerServiceName, IDR_NACL_BROKER_MANIFEST}, +#endif // defined(OS_WIN) +#endif // !defined(DISABLE_NACL) + }); +} + void ChromeContentBrowserClient::OpenURL( content::BrowserContext* browser_context, const content::OpenURLParams& params,
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 509a4c5..b76e82eb 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -294,7 +294,9 @@ void RegisterOutOfProcessServices( OutOfProcessServiceMap* services) override; std::unique_ptr<base::Value> GetServiceManifestOverlay( - const std::string& name) override; + base::StringPiece name) override; + std::vector<content::ContentBrowserClient::ServiceManifestInfo> + GetExtraServiceManifests() override; void OpenURL(content::BrowserContext* browser_context, const content::OpenURLParams& params, const base::Callback<void(content::WebContents*)>& callback)
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json index 5d5b1e9..e217999 100644 --- a/chrome/browser/chrome_content_browser_manifest_overlay.json +++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -43,9 +43,11 @@ ] }, "requires": { + "accessibility_autoclick": [ "ash:autoclick" ], "ash": [ "ash" ], "image_decoder": [ "decode" ], - "accessibility_autoclick": [ "ash:autoclick" ], + "nacl_broker": [ "browser" ], + "nacl_loader": [ "browser" ], "preferences": [ "preferences_manager" ], "ui": [ "ime_registrar" ] }
diff --git a/chrome/browser/chromeos/system/system_clock.cc b/chrome/browser/chromeos/system/system_clock.cc index 2a300bd..3c9216615 100644 --- a/chrome/browser/chromeos/system/system_clock.cc +++ b/chrome/browser/chromeos/system/system_clock.cc
@@ -32,7 +32,8 @@ void SetShouldUse24HourClock(bool use_24_hour_clock) { user_manager::User* const user = user_manager::UserManager::Get()->GetActiveUser(); - CHECK(user); + if (!user) + return; // May occur if not running on a device. Profile* const profile = ProfileHelper::Get()->GetProfileByUser(user); if (!profile) return; // May occur in tests or if not running on a device.
diff --git a/chrome/browser/extensions/native_bindings_apitest.cc b/chrome/browser/extensions/native_bindings_apitest.cc new file mode 100644 index 0000000..1fc10e62 --- /dev/null +++ b/chrome/browser/extensions/native_bindings_apitest.cc
@@ -0,0 +1,33 @@ +// Copyright 2016 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. + +#include "base/command_line.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "extensions/common/switches.h" + +namespace extensions { + +// And end-to-end test for extension APIs using native bindings. +class NativeBindingsApiTest : public ExtensionApiTest { + public: + NativeBindingsApiTest() {} + ~NativeBindingsApiTest() override {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + ExtensionApiTest::SetUpCommandLine(command_line); + // Note: We don't use a FeatureSwitch::ScopedOverride here because we need + // the switch to be propogated to the renderer, which doesn't happen with + // a ScopedOverride. + command_line->AppendSwitchASCII(switches::kNativeCrxBindings, "1"); + } + + private: + DISALLOW_COPY_AND_ASSIGN(NativeBindingsApiTest); +}; + +IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, SimpleEndToEndTest) { + ASSERT_TRUE(RunExtensionTest("native_bindings")) << message_; +} + +} // namespace extensions
diff --git a/chrome/browser/google/google_brand_chromeos.cc b/chrome/browser/google/google_brand_chromeos.cc index 87a73226..58cd28b 100644 --- a/chrome/browser/google/google_brand_chromeos.cc +++ b/chrome/browser/google/google_brand_chromeos.cc
@@ -79,7 +79,7 @@ .WithShutdownBehavior( base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) .WithPriority(base::TaskPriority::BACKGROUND) - .WithFileIO(), + .MayBlock(), base::Bind(&ReadBrandFromFile), base::Bind(&SetBrand, callback)); }
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 48fff7ce..00f844c 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc
@@ -95,6 +95,7 @@ #include "net/proxy/proxy_config_service.h" #include "net/proxy/proxy_script_fetcher_impl.h" #include "net/proxy/proxy_service.h" +#include "net/quic/chromium/quic_utils_chromium.h" #include "net/socket/ssl_client_socket.h" #include "net/socket/tcp_client_socket.h" #include "net/ssl/channel_id_service.h" @@ -951,7 +952,7 @@ if (params->enable_quic) { if (command_line.HasSwitch(switches::kQuicConnectionOptions)) { params->quic_connection_options = - net::QuicUtils::ParseQuicConnectionOptions( + net::ParseQuicConnectionOptions( command_line.GetSwitchValueASCII( switches::kQuicConnectionOptions)); }
diff --git a/chrome/browser/resources/md_downloads/vulcanized.html b/chrome/browser/resources/md_downloads/vulcanized.html index fd1b423..ad971a0 100644 --- a/chrome/browser/resources/md_downloads/vulcanized.html +++ b/chrome/browser/resources/md_downloads/vulcanized.html
@@ -25,23 +25,6 @@ --> <meta charset="utf-8"> <title>$i18n{title}</title> - <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> - <style> -/* Copyright 2016 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. */ - -:root { - /* This is a custom, Chrome-specific color that does not have a --paper or - * --google equivalent. */ - --md-background-color: #f1f1f1; - --md-loading-message-color: #6e6e6e; - /* This is --google-blue-700, rewritten as a native custom property for speed. - */ - --md-toolbar-color: rgb(51, 103, 214); -} - -</style> <style> html { background: var(--md-background-color); @@ -63,9 +46,35 @@ } </style> </head> -<body><div hidden="" by-vulcanize=""><script src="chrome://resources/js/load_time_data.js"></script> -<script src="chrome://downloads/strings.js"></script> -<dom-module id="iron-list" assetpath="chrome://resources/polymer/v1_0/iron-list/" css-build="shadow"> +<body><div hidden="" by-vulcanize=""><link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"><style> +/* Copyright 2016 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. */ + +:root { + /* This is a custom, Chrome-specific color that does not have a --paper or + * --google equivalent. */ + --md-background-color: #f1f1f1; + --md-loading-message-color: #6e6e6e; + /* This is --google-blue-700, rewritten as a native custom property for speed. + */ + --md-toolbar-color: rgb(51, 103, 214); +} + +</style></div> + <downloads-manager></downloads-manager> +<if expr="is_macosx"> + <command id="clear-all-command" shortcut="Alt|c Alt|ç"></command> + <command id="undo-command" shortcut="Meta|z"></command> + <command id="find-command" shortcut="Meta|f"></command> +</if> +<if expr="not is_macosx"> + <command id="clear-all-command" shortcut="Alt|c"></command> + <command id="undo-command" shortcut="Ctrl|z"></command> + <command id="find-command" shortcut="Ctrl|f"></command> +</if> + <div hidden="" by-vulcanize=""></div><link rel="import" href="chrome://resources/html/polymer.html"> + <div hidden="" by-vulcanize=""><script src="chrome://resources/js/load_time_data.js"></script><script src="chrome://downloads/strings.js"></script></div><div hidden="" by-vulcanize=""><dom-module id="iron-list" assetpath="chrome://resources/polymer/v1_0/iron-list/" css-build="shadow"> <template> <style scope="iron-list">:host { display: block; @@ -234,8 +243,6 @@ } </style> - - <dom-module id="iron-icon" assetpath="chrome://resources/polymer/v1_0/iron-icon/" css-build="shadow"> <template> <style scope="iron-icon">:host { @@ -381,8 +388,6 @@ </style> </template> </dom-module> - - <dom-module id="paper-button" assetpath="chrome://resources/polymer/v1_0/paper-button/" css-build="shadow"> <template strip-whitespace=""> <style scope="paper-button">:host { @@ -825,8 +830,6 @@ } </style> - - <dom-module id="paper-progress" assetpath="chrome://resources/polymer/v1_0/paper-progress/" css-build="shadow"> <template> <style scope="paper-progress">:host { @@ -854,7 +857,7 @@ } #progressContainer, .indeterminate::after { - background: var(--paper-progress-container-color,var(--google-grey-300));; + background: var(--paper-progress-container-color,var(--google-grey-300)); } :host(.transiting) #primaryProgress, :host(.transiting) #secondaryProgress { @@ -884,19 +887,19 @@ } #primaryProgress { - background: var(--paper-progress-active-color,var(--google-green-500));; + background: var(--paper-progress-active-color,var(--google-green-500)); } #secondaryProgress { - background: var(--paper-progress-secondary-color,var(--google-green-100));; + background: var(--paper-progress-secondary-color,var(--google-green-100)); } :host([disabled]) #primaryProgress { - background: var(--paper-progress-disabled-active-color,var(--google-grey-500));; + background: var(--paper-progress-disabled-active-color,var(--google-grey-500)); } :host([disabled]) #secondaryProgress { - background: var(--paper-progress-disabled-secondary-color,var(--google-grey-300));; + background: var(--paper-progress-disabled-secondary-color,var(--google-grey-300)); } :host(:not([disabled])) #primaryProgress.indeterminate { @@ -1313,6 +1316,8 @@ </dom-module> + + <style is="custom-style" css-build="shadow">html { --primary-text-color: var(--light-theme-text-color); --primary-background-color: var(--light-theme-background-color); @@ -1353,38 +1358,6 @@ } </style> -<style> -/* Copyright 2015 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. */ - -<if expr="not chromeos and not is_android"> -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), - url("chrome://resources/roboto/roboto-regular.woff2") format('woff2'); -} - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), - url("chrome://resources/roboto/roboto-medium.woff2") format('woff2'); -} - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), - url("chrome://resources/roboto/roboto-bold.woff2") format('woff2'); -} -</if> - -</style> <style is="custom-style" css-build="shadow">html { --paper-font-common-base_-_font-family: 'Roboto', 'Noto', sans-serif; --paper-font-common-base_-_-webkit-font-smoothing: antialiased;; @@ -1426,7 +1399,38 @@ } </style> -<dom-module id="paper-item-shared-styles" assetpath="chrome://resources/polymer/v1_0/paper-item/" css-build="shadow"> +<style> +/* Copyright 2015 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. */ + +<if expr="not chromeos and not is_android"> +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), + url("chrome://resources/roboto/roboto-regular.woff2") format('woff2'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), + url("chrome://resources/roboto/roboto-medium.woff2") format('woff2'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), + url("chrome://resources/roboto/roboto-bold.woff2") format('woff2'); +} +</if> + +</style><dom-module id="paper-item-shared-styles" assetpath="chrome://resources/polymer/v1_0/paper-item/" css-build="shadow"> <template> <style scope="paper-item-shared-styles">:host, .paper-item { display: block; @@ -1455,7 +1459,7 @@ } :host([disabled]), .paper-item[disabled] { - color: var(--paper-item-disabled-color,var(--disabled-text-color));; + color: var(--paper-item-disabled-color,var(--disabled-text-color)); ; } @@ -1481,8 +1485,6 @@ </style> </template> </dom-module> - - <dom-module id="paper-item" assetpath="chrome://resources/polymer/v1_0/paper-item/" css-build="shadow"> <template> @@ -1513,7 +1515,7 @@ } :host([disabled]), .paper-item[disabled] { - color: var(--paper-item-disabled-color,var(--disabled-text-color));; + color: var(--paper-item-disabled-color,var(--disabled-text-color)); ; } @@ -1559,7 +1561,7 @@ } .selectable-content > ::content > [disabled] { - color: var(--paper-menu-disabled-color,var(--disabled-text-color));; + color: var(--paper-menu-disabled-color,var(--disabled-text-color)); } .selectable-content > ::content > *:focus { @@ -1586,8 +1588,6 @@ </style> </template> </dom-module> - - <dom-module id="paper-menu" assetpath="chrome://resources/polymer/v1_0/paper-menu/" css-build="shadow"> <template> @@ -1598,7 +1598,7 @@ } .selectable-content > ::content > [disabled] { - color: var(--paper-menu-disabled-color,var(--disabled-text-color));; + color: var(--paper-menu-disabled-color,var(--disabled-text-color)); } .selectable-content > ::content > *:focus { @@ -1626,8 +1626,8 @@ display: block; padding: 8px 0; - background: var(--paper-menu-background-color,var(--primary-background-color));; - color: var(--paper-menu-color,var(--primary-text-color));; + background: var(--paper-menu-background-color,var(--primary-background-color)); + color: var(--paper-menu-color,var(--primary-text-color)); ; } @@ -1640,7 +1640,7 @@ </template> </dom-module> -<dom-module id="iron-overlay-backdrop" assetpath="chrome://resources/polymer/v1_0/iron-overlay-behavior/" css-build="shadow"> +<dom-module id="iron-overlay-backdrop" assetpath="/" css-build="shadow"> <template> <style scope="iron-overlay-backdrop">:host { @@ -1669,10 +1669,7 @@ </dom-module> -<script src="chrome://resources/polymer/v1_0/web-animations-js/web-animations-next-lite.min.js"></script> - - -<dom-module id="iron-dropdown" assetpath="chrome://resources/polymer/v1_0/iron-dropdown/" css-build="shadow"> +<script src="chrome://resources/polymer/v1_0/web-animations-js/web-animations-next-lite.min.js"></script><dom-module id="iron-dropdown" assetpath="chrome://resources/polymer/v1_0/iron-dropdown/" css-build="shadow"> <template> <style scope="iron-dropdown">:host { position: fixed; @@ -1721,7 +1718,7 @@ position: relative; border-radius: 2px; - background-color: var(--paper-menu-button-dropdown-background,var(--primary-background-color));; + background-color: var(--paper-menu-button-dropdown-background,var(--primary-background-color)); ; } @@ -1785,12 +1782,12 @@ } :host #ink { - color: var(--paper-icon-button-ink-color,var(--primary-text-color));; + color: var(--paper-icon-button-ink-color,var(--primary-text-color)); opacity: 0.6; } :host([disabled]) { - color: var(--paper-icon-button-disabled-text,var(--disabled-text-color));; + color: var(--paper-icon-button-disabled-text,var(--disabled-text-color)); pointer-events: none; cursor: auto; @@ -1866,23 +1863,23 @@ height: 100%; opacity: 0; white-space: nowrap; - border-color: var(--paper-spinner-color,var(--google-blue-500));; + border-color: var(--paper-spinner-color,var(--google-blue-500)); } .layer-1 { - border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500));; + border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500)); } .layer-2 { - border-color: var(--paper-spinner-layer-2-color,var(--google-red-500));; + border-color: var(--paper-spinner-layer-2-color,var(--google-red-500)); } .layer-3 { - border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500));; + border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500)); } .layer-4 { - border-color: var(--paper-spinner-layer-4-color,var(--google-green-500));; + border-color: var(--paper-spinner-layer-4-color,var(--google-green-500)); } .active .spinner-layer { @@ -2350,8 +2347,6 @@ </style> </template> </dom-module> - - <dom-module id="paper-spinner-lite" assetpath="chrome://resources/polymer/v1_0/paper-spinner/" css-build="shadow"> <template strip-whitespace=""> <style scope="paper-spinner-lite">:host { @@ -2406,23 +2401,23 @@ height: 100%; opacity: 0; white-space: nowrap; - border-color: var(--paper-spinner-color,var(--google-blue-500));; + border-color: var(--paper-spinner-color,var(--google-blue-500)); } .layer-1 { - border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500));; + border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500)); } .layer-2 { - border-color: var(--paper-spinner-layer-2-color,var(--google-red-500));; + border-color: var(--paper-spinner-layer-2-color,var(--google-red-500)); } .layer-3 { - border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500));; + border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500)); } .layer-4 { - border-color: var(--paper-spinner-layer-4-color,var(--google-green-500));; + border-color: var(--paper-spinner-layer-4-color,var(--google-green-500)); } .active .spinner-layer { @@ -3288,9 +3283,7 @@ --md-toolbar-color: rgb(51, 103, 214); } -</style> - -<dom-module id="downloads-manager" assetpath="chrome://downloads/" css-build="shadow"> +</style><dom-module id="downloads-manager" assetpath="chrome://downloads/" css-build="shadow"> <template> <style scope="downloads-manager">:host { display: flex; @@ -3382,17 +3375,4 @@ </div> </template> </dom-module> -</div> - <downloads-manager></downloads-manager> -<if expr="is_macosx"> - <command id="clear-all-command" shortcut="Alt|c Alt|ç"></command> - <command id="undo-command" shortcut="Meta|z"></command> - <command id="find-command" shortcut="Meta|f"></command> -</if> -<if expr="not is_macosx"> - <command id="clear-all-command" shortcut="Alt|c"></command> - <command id="undo-command" shortcut="Ctrl|z"></command> - <command id="find-command" shortcut="Ctrl|f"></command> -</if> - <link rel="import" href="chrome://resources/html/polymer.html"> - <script src="crisper.js"></script></body></html> \ No newline at end of file +</div><script src="crisper.js"></script></body></html> \ No newline at end of file
diff --git a/chrome/browser/resources/md_history/app.crisper.js b/chrome/browser/resources/md_history/app.crisper.js index 7e2dece..bedb8855 100644 --- a/chrome/browser/resources/md_history/app.crisper.js +++ b/chrome/browser/resources/md_history/app.crisper.js
@@ -57,7 +57,7 @@ // Copyright 2015 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. -function HistoryFocusRow(root,boundary,delegate){cr.ui.FocusRow.call(this,root,boundary,delegate);this.addItems()}HistoryFocusRow.prototype={__proto__:cr.ui.FocusRow.prototype,getCustomEquivalent:function(sampleElement){var equivalent;if(this.getTypeForElement(sampleElement)=="star")equivalent=this.getFirstFocusable("title");return equivalent||cr.ui.FocusRow.prototype.getCustomEquivalent.call(this,sampleElement)},addItems:function(){this.destroy();assert(this.addItem("checkbox","#checkbox"));assert(this.addItem("title","#title"));assert(this.addItem("menu-button","#menu-button"));this.addItem("star","#bookmark-star")}};cr.define("md_history",function(){function FocusRowDelegate(historyItemElement){this.historyItemElement=historyItemElement}FocusRowDelegate.prototype={onFocus:function(row,e){this.historyItemElement.lastFocused=e.path[0]},onKeydown:function(row,e){if(e.key=="Enter")e.stopPropagation();return false}};var HistoryItem=Polymer({is:"history-item",properties:{item:{type:Object,observer:"showIcon_"},selected:{type:Boolean,reflectToAttribute:true},isCardStart:{type:Boolean,reflectToAttribute:true},isCardEnd:{type:Boolean,reflectToAttribute:true},embedded:{type:Boolean,reflectToAttribute:true},lastFocused:{type:Object,notify:true},ironListTabIndex:{type:Number,observer:"ironListTabIndexChanged_"},hasTimeGap:Boolean,index:Number,numberOfItems:Number,path:String,searchTerm:String},row_:null,attached:function(){Polymer.RenderStatus.afterNextRender(this,function(){this.row_=new HistoryFocusRow(this.$["main-container"],null,new FocusRowDelegate(this));this.row_.makeActive(this.ironListTabIndex==0);this.listen(this,"focus","onFocus_");this.listen(this,"dom-change","onDomChange_")})},detached:function(){this.unlisten(this,"focus","onFocus_");this.unlisten(this,"dom-change","onDomChange_");if(this.row_)this.row_.destroy()},onFocus_:function(){if(this.lastFocused)this.row_.getEquivalentElement(this.lastFocused).focus();else this.row_.getFirstFocusable().focus();this.tabIndex=-1},ironListTabIndexChanged_:function(){if(this.row_)this.row_.makeActive(this.ironListTabIndex==0)},onDomChange_:function(){if(this.row_)this.row_.addItems()},onItemClick_:function(e){for(var i=0;i<e.path.length;i++){var elem=e.path[i];if(elem.id!="checkbox"&&(elem.nodeName=="A"||elem.nodeName=="BUTTON")){return}}if(this.selectionNotAllowed_())return;this.$.checkbox.focus();this.fire("history-checkbox-select",{element:this,shiftKey:e.shiftKey})},onItemMousedown_:function(e){if(e.shiftKey)e.preventDefault()},getEntrySummary_:function(){var item=this.item;return loadTimeData.getStringF("entrySummary",item.dateTimeOfDay,item.starred?loadTimeData.getString("bookmarked"):"",item.title,item.domain)},getAriaChecked_:function(selected){return selected?"true":"false"},onRemoveBookmarkTap_:function(){if(!this.item.starred)return;if(this.$$("#bookmark-star")==this.root.activeElement)this.$["menu-button"].focus();var browserService=md_history.BrowserService.getInstance();browserService.removeBookmark(this.item.url);browserService.recordAction("BookmarkStarClicked");this.fire("remove-bookmark-stars",this.item.url)},onMenuButtonTap_:function(e){this.fire("toggle-menu",{target:Polymer.dom(e).localTarget,index:this.index,item:this.item,path:this.path});e.stopPropagation()},onLinkClick_:function(){var browserService=md_history.BrowserService.getInstance();browserService.recordAction("EntryLinkClick");if(this.searchTerm)browserService.recordAction("SearchResultClick");if(this.index==undefined)return;browserService.recordHistogram("HistoryPage.ClickPosition",Math.min(this.index,UMA_MAX_BUCKET_VALUE),UMA_MAX_BUCKET_VALUE);if(this.index<=UMA_MAX_SUBSET_BUCKET_VALUE){browserService.recordHistogram("HistoryPage.ClickPositionSubset",this.index,UMA_MAX_SUBSET_BUCKET_VALUE)}},onLinkRightClick_:function(){md_history.BrowserService.getInstance().recordAction("EntryLinkRightClick")},showIcon_:function(){this.$.icon.style.backgroundImage=cr.icon.getFavicon(this.item.url)},selectionNotAllowed_:function(){return!loadTimeData.getBoolean("allowDeletingHistory")},cardTitle_:function(numberOfItems,historyDate,search){if(!search)return this.item.dateRelativeDay;return HistoryItem.searchResultsTitle(numberOfItems,search)},addTimeTitle_:function(){var el=this.$["time-accessed"];el.setAttribute("title",new Date(this.item.time).toString());this.unlisten(el,"mouseover","addTimeTitle_")}});HistoryItem.needsTimeGap=function(visits,currentIndex,searchedTerm){if(currentIndex>=visits.length-1||visits.length==0)return false;var currentItem=visits[currentIndex];var nextItem=visits[currentIndex+1];if(searchedTerm)return currentItem.dateShort!=nextItem.dateShort;return currentItem.time-nextItem.time>BROWSING_GAP_TIME&¤tItem.dateRelativeDay==nextItem.dateRelativeDay};HistoryItem.searchResultsTitle=function(numberOfResults,searchTerm){var resultId=numberOfResults==1?"searchResult":"searchResults";return loadTimeData.getStringF("foundSearchResults",numberOfResults,loadTimeData.getString(resultId),searchTerm)};return{HistoryItem:HistoryItem}}); +function HistoryFocusRow(root,boundary,delegate){cr.ui.FocusRow.call(this,root,boundary,delegate);this.addItems()}HistoryFocusRow.prototype={__proto__:cr.ui.FocusRow.prototype,getCustomEquivalent:function(sampleElement){var equivalent;if(this.getTypeForElement(sampleElement)=="star")equivalent=this.getFirstFocusable("title");return equivalent||cr.ui.FocusRow.prototype.getCustomEquivalent.call(this,sampleElement)},addItems:function(){this.destroy();assert(this.addItem("checkbox","#checkbox"));assert(this.addItem("title","#title"));assert(this.addItem("menu-button","#menu-button"));this.addItem("star","#bookmark-star")}};cr.define("md_history",function(){function FocusRowDelegate(historyItemElement){this.historyItemElement=historyItemElement}FocusRowDelegate.prototype={onFocus:function(row,e){this.historyItemElement.lastFocused=e.path[0]},onKeydown:function(row,e){if(e.key=="Enter")e.stopPropagation();return false}};var HistoryItem=Polymer({is:"history-item",properties:{item:{type:Object,observer:"showIcon_"},selected:{type:Boolean,reflectToAttribute:true},isCardStart:{type:Boolean,reflectToAttribute:true},isCardEnd:{type:Boolean,reflectToAttribute:true},embedded:{type:Boolean,reflectToAttribute:true},lastFocused:{type:Object,notify:true},ironListTabIndex:{type:Number,observer:"ironListTabIndexChanged_"},hasTimeGap:Boolean,index:Number,numberOfItems:Number,path:String,searchTerm:String},row_:null,attached:function(){Polymer.RenderStatus.afterNextRender(this,function(){this.row_=new HistoryFocusRow(this.$["main-container"],null,new FocusRowDelegate(this));this.row_.makeActive(this.ironListTabIndex==0);this.listen(this,"focus","onFocus_");this.listen(this,"dom-change","onDomChange_")})},detached:function(){this.unlisten(this,"focus","onFocus_");this.unlisten(this,"dom-change","onDomChange_");if(this.row_)this.row_.destroy()},onFocus_:function(){if(this.lastFocused)this.row_.getEquivalentElement(this.lastFocused).focus();else this.row_.getFirstFocusable().focus();this.tabIndex=-1},ironListTabIndexChanged_:function(){if(this.row_)this.row_.makeActive(this.ironListTabIndex==0)},onDomChange_:function(){if(this.row_)this.row_.addItems()},onItemClick_:function(e){for(var i=0;i<e.path.length;i++){var elem=e.path[i];if(elem.id!="checkbox"&&(elem.nodeName=="A"||elem.nodeName=="BUTTON")){return}}if(this.selectionNotAllowed_())return;this.$.checkbox.focus();this.fire("history-checkbox-select",{element:this,shiftKey:e.shiftKey})},onItemMousedown_:function(e){if(e.shiftKey)e.preventDefault()},getEntrySummary_:function(){var item=this.item;return loadTimeData.getStringF("entrySummary",item.dateTimeOfDay,item.starred?loadTimeData.getString("bookmarked"):"",item.title,item.domain)},getAriaChecked_:function(selected){return selected?"true":"false"},onRemoveBookmarkTap_:function(){if(!this.item.starred)return;if(this.$$("#bookmark-star")==this.root.activeElement)this.$["menu-button"].focus();var browserService=md_history.BrowserService.getInstance();browserService.removeBookmark(this.item.url);browserService.recordAction("BookmarkStarClicked");this.fire("remove-bookmark-stars",this.item.url)},onMenuButtonTap_:function(e){this.fire("open-menu",{target:Polymer.dom(e).localTarget,index:this.index,item:this.item,path:this.path});e.stopPropagation()},onLinkClick_:function(){var browserService=md_history.BrowserService.getInstance();browserService.recordAction("EntryLinkClick");if(this.searchTerm)browserService.recordAction("SearchResultClick");if(this.index==undefined)return;browserService.recordHistogram("HistoryPage.ClickPosition",Math.min(this.index,UMA_MAX_BUCKET_VALUE),UMA_MAX_BUCKET_VALUE);if(this.index<=UMA_MAX_SUBSET_BUCKET_VALUE){browserService.recordHistogram("HistoryPage.ClickPositionSubset",this.index,UMA_MAX_SUBSET_BUCKET_VALUE)}},onLinkRightClick_:function(){md_history.BrowserService.getInstance().recordAction("EntryLinkRightClick")},showIcon_:function(){this.$.icon.style.backgroundImage=cr.icon.getFavicon(this.item.url)},selectionNotAllowed_:function(){return!loadTimeData.getBoolean("allowDeletingHistory")},cardTitle_:function(numberOfItems,historyDate,search){if(!search)return this.item.dateRelativeDay;return HistoryItem.searchResultsTitle(numberOfItems,search)},addTimeTitle_:function(){var el=this.$["time-accessed"];el.setAttribute("title",new Date(this.item.time).toString());this.unlisten(el,"mouseover","addTimeTitle_")}});HistoryItem.needsTimeGap=function(visits,currentIndex,searchedTerm){if(currentIndex>=visits.length-1||visits.length==0)return false;var currentItem=visits[currentIndex];var nextItem=visits[currentIndex+1];if(searchedTerm)return currentItem.dateShort!=nextItem.dateShort;return currentItem.time-nextItem.time>BROWSING_GAP_TIME&¤tItem.dateRelativeDay==nextItem.dateRelativeDay};HistoryItem.searchResultsTitle=function(numberOfResults,searchTerm){var resultId=numberOfResults==1?"searchResult":"searchResults";return loadTimeData.getStringF("foundSearchResults",numberOfResults,loadTimeData.getString(resultId),searchTerm)};return{HistoryItem:HistoryItem}}); // Copyright 2016 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. @@ -65,11 +65,11 @@ // Copyright 2015 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. -Polymer({is:"history-list",behaviors:[HistoryListBehavior],properties:{searchedTerm:{type:String,value:""},resultLoadingDisabled_:{type:Boolean,value:false},historyData_:Array,lastFocused_:Object,querying:Boolean},listeners:{scroll:"notifyListScroll_","remove-bookmark-stars":"removeBookmarkStars_"},attached:function(){this.$["infinite-list"].notifyResize();this.$["infinite-list"].scrollTarget=this;this.$["scroll-threshold"].scrollTarget=this},removeBookmarkStars_:function(e){var url=e.detail;if(this.historyData_===undefined)return;for(var i=0;i<this.historyData_.length;i++){if(this.historyData_[i].url==url)this.set("historyData_."+i+".starred",false)}},addNewResults:function(historyResults,incremental,finished){var results=historyResults.slice();this.$["scroll-threshold"].clearTriggers();if(!incremental){this.resultLoadingDisabled_=false;if(this.historyData_)this.splice("historyData_",0,this.historyData_.length);this.fire("unselect-all")}if(this.historyData_){results.unshift("historyData_");this.push.apply(this,results)}else{this.set("historyData_",results)}this.resultLoadingDisabled_=finished},loadMoreData_:function(){if(this.resultLoadingDisabled_||this.querying)return;this.fire("load-more-history")},needsTimeGap_:function(item,index,length){return md_history.HistoryItem.needsTimeGap(this.historyData_,index,this.searchedTerm)},isCardStart_:function(item,i,length){if(length==0||i>length-1)return false;return i==0||this.historyData_[i].dateRelativeDay!=this.historyData_[i-1].dateRelativeDay},isCardEnd_:function(item,i,length){if(length==0||i>length-1)return false;return i==length-1||this.historyData_[i].dateRelativeDay!=this.historyData_[i+1].dateRelativeDay},notifyListScroll_:function(){this.fire("history-list-scrolled")},pathForItem_:function(index){return"historyData_."+index}}); +Polymer({is:"history-list",behaviors:[HistoryListBehavior],properties:{searchedTerm:{type:String,value:""},resultLoadingDisabled_:{type:Boolean,value:false},historyData_:Array,lastFocused_:Object,querying:Boolean},listeners:{"remove-bookmark-stars":"removeBookmarkStars_"},attached:function(){this.$["infinite-list"].notifyResize();this.$["infinite-list"].scrollTarget=this;this.$["scroll-threshold"].scrollTarget=this},removeBookmarkStars_:function(e){var url=e.detail;if(this.historyData_===undefined)return;for(var i=0;i<this.historyData_.length;i++){if(this.historyData_[i].url==url)this.set("historyData_."+i+".starred",false)}},addNewResults:function(historyResults,incremental,finished){var results=historyResults.slice();this.$["scroll-threshold"].clearTriggers();if(!incremental){this.resultLoadingDisabled_=false;if(this.historyData_)this.splice("historyData_",0,this.historyData_.length);this.fire("unselect-all")}if(this.historyData_){results.unshift("historyData_");this.push.apply(this,results)}else{this.set("historyData_",results)}this.resultLoadingDisabled_=finished},loadMoreData_:function(){if(this.resultLoadingDisabled_||this.querying)return;this.fire("load-more-history")},needsTimeGap_:function(item,index,length){return md_history.HistoryItem.needsTimeGap(this.historyData_,index,this.searchedTerm)},isCardStart_:function(item,i,length){if(length==0||i>length-1)return false;return i==0||this.historyData_[i].dateRelativeDay!=this.historyData_[i-1].dateRelativeDay},isCardEnd_:function(item,i,length){if(length==0||i>length-1)return false;return i==length-1||this.historyData_[i].dateRelativeDay!=this.historyData_[i+1].dateRelativeDay},pathForItem_:function(index){return"historyData_."+index}}); // Copyright 2016 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. -Polymer({is:"history-list-container",properties:{groupedRange:{type:Number,observer:"groupedRangeChanged_"},selectedPage_:String,grouped:Boolean,queryState:Object,queryResult:Object},observers:["searchTermChanged_(queryState.searchTerm)","groupedOffsetChanged_(queryState.groupedOffset)"],listeners:{"history-list-scrolled":"closeMenu_","load-more-history":"loadMoreHistory_","toggle-menu":"toggleMenu_"},historyResult:function(info,results){this.initializeResults_(info,results);this.closeMenu_();if(info.term&&!this.queryState.incremental){Polymer.IronA11yAnnouncer.requestAvailability();this.fire("iron-announce",{text:md_history.HistoryItem.searchResultsTitle(results.length,info.term)})}var list=this.getSelectedList_();list.addNewResults(results,this.queryState.incremental,info.finished)},queryHistory:function(incremental){var queryState=this.queryState;var noResults=!this.queryResult||this.queryResult.results==null;if(queryState.queryingDisabled||!this.queryState.searchTerm&&noResults){return}var dialog=this.$.dialog.getIfExists();if(!incremental&&dialog&&dialog.open)dialog.close();this.set("queryState.querying",true);this.set("queryState.incremental",incremental);var lastVisitTime=0;if(incremental){var lastVisit=this.queryResult.results.slice(-1)[0];lastVisitTime=lastVisit?Math.floor(lastVisit.time):0}var maxResults=this.groupedRange==HistoryRange.ALL_TIME?RESULTS_PER_PAGE:0;chrome.send("queryHistory",[queryState.searchTerm,queryState.groupedOffset,queryState.range,lastVisitTime,maxResults])},historyDeleted:function(){if(this.getSelectedItemCount()>0)return;this.queryHistory(false)},getContentScrollTarget:function(){return this.getSelectedList_()},getSelectedItemCount:function(){return this.getSelectedList_().selectedPaths.size},unselectAllItems:function(count){var selectedList=this.getSelectedList_();if(selectedList)selectedList.unselectAllItems(count)},deleteSelectedWithPrompt:function(){if(!loadTimeData.getBoolean("allowDeletingHistory"))return;var browserService=md_history.BrowserService.getInstance();browserService.recordAction("RemoveSelected");if(this.queryState.searchTerm!="")browserService.recordAction("SearchResultRemove");this.$.dialog.get().showModal();this.$$(".action-button").focus()},groupedRangeChanged_:function(range,oldRange){this.selectedPage_=range==HistoryRange.ALL_TIME?"infinite-list":"grouped-list";if(oldRange==undefined)return;this.set("queryState.groupedOffset",0);if(this.queryResult.info){this.set("queryResult.results",[]);this.historyResult(this.queryResult.info,[])}this.queryHistory(false);this.fire("history-view-changed")},searchTermChanged_:function(){this.queryHistory(false);if(this.queryState.searchTerm)md_history.BrowserService.getInstance().recordAction("Search")},groupedOffsetChanged_:function(){this.queryHistory(false)},loadMoreHistory_:function(){this.queryHistory(true)},initializeResults_:function(info,results){if(results.length==0)return;var currentDate=results[0].dateRelativeDay;for(var i=0;i<results.length;i++){results[i].selected=false;results[i].readableTimestamp=info.term==""?results[i].dateTimeOfDay:results[i].dateShort;if(results[i].dateRelativeDay!=currentDate){currentDate=results[i].dateRelativeDay}}},onDialogConfirmTap_:function(){md_history.BrowserService.getInstance().recordAction("ConfirmRemoveSelected");this.getSelectedList_().deleteSelected();var dialog=assert(this.$.dialog.getIfExists());dialog.close()},onDialogCancelTap_:function(){md_history.BrowserService.getInstance().recordAction("CancelRemoveSelected");var dialog=assert(this.$.dialog.getIfExists());dialog.close()},closeMenu_:function(){var menu=this.$.sharedMenu.getIfExists();if(menu)menu.closeMenu()},toggleMenu_:function(e){var target=e.detail.target;var menu=this.$.sharedMenu.get();menu.toggleMenu(target,e.detail)},onMoreFromSiteTap_:function(){md_history.BrowserService.getInstance().recordAction("EntryMenuShowMoreFromSite");var menu=assert(this.$.sharedMenu.getIfExists());this.set("queryState.searchTerm",menu.itemData.item.domain);menu.closeMenu()},onRemoveFromHistoryTap_:function(){var browserService=md_history.BrowserService.getInstance();browserService.recordAction("EntryMenuRemoveFromHistory");var menu=assert(this.$.sharedMenu.getIfExists());var itemData=menu.itemData;browserService.deleteItems([itemData.item]).then(function(items){this.fire("unselect-all");this.getSelectedList_().removeItemsByPath([itemData.path]);var index=itemData.index;if(index==undefined)return;var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram("HistoryPage.RemoveEntryPosition",Math.min(index,UMA_MAX_BUCKET_VALUE),UMA_MAX_BUCKET_VALUE);if(index<=UMA_MAX_SUBSET_BUCKET_VALUE){browserService.recordHistogram("HistoryPage.RemoveEntryPositionSubset",index,UMA_MAX_SUBSET_BUCKET_VALUE)}}.bind(this));menu.closeMenu()},getSelectedList_:function(){return this.$$("#"+this.selectedPage_)},canDeleteHistory_:function(){return loadTimeData.getBoolean("allowDeletingHistory")}});(function(){"use strict";Polymer({is:"iron-location",properties:{path:{type:String,notify:true,value:function(){return window.decodeURIComponent(window.location.pathname)}},query:{type:String,notify:true,value:function(){return window.decodeURIComponent(window.location.search.slice(1))}},hash:{type:String,notify:true,value:function(){return window.decodeURIComponent(window.location.hash.slice(1))}},dwellTime:{type:Number,value:2e3},urlSpaceRegex:{type:String,value:""},_urlSpaceRegExp:{computed:"_makeRegExp(urlSpaceRegex)"},_lastChangedAt:{type:Number},_initialized:{type:Boolean,value:false}},hostAttributes:{hidden:true},observers:["_updateUrl(path, query, hash)"],attached:function(){this.listen(window,"hashchange","_hashChanged");this.listen(window,"location-changed","_urlChanged");this.listen(window,"popstate","_urlChanged");this.listen(document.body,"click","_globalOnClick");this._lastChangedAt=window.performance.now()-(this.dwellTime-200);this._initialized=true;this._urlChanged()},detached:function(){this.unlisten(window,"hashchange","_hashChanged");this.unlisten(window,"location-changed","_urlChanged");this.unlisten(window,"popstate","_urlChanged");this.unlisten(document.body,"click","_globalOnClick");this._initialized=false},_hashChanged:function(){this.hash=window.decodeURIComponent(window.location.hash.substring(1))},_urlChanged:function(){this._dontUpdateUrl=true;this._hashChanged();this.path=window.decodeURIComponent(window.location.pathname);this.query=window.decodeURIComponent(window.location.search.substring(1));this._dontUpdateUrl=false;this._updateUrl()},_getUrl:function(){var partiallyEncodedPath=window.encodeURI(this.path).replace(/\#/g,"%23").replace(/\?/g,"%3F");var partiallyEncodedQuery="";if(this.query){partiallyEncodedQuery="?"+window.encodeURI(this.query).replace(/\#/g,"%23")}var partiallyEncodedHash="";if(this.hash){partiallyEncodedHash="#"+window.encodeURI(this.hash)}return partiallyEncodedPath+partiallyEncodedQuery+partiallyEncodedHash},_updateUrl:function(){if(this._dontUpdateUrl||!this._initialized){return}if(this.path===window.decodeURIComponent(window.location.pathname)&&this.query===window.decodeURIComponent(window.location.search.substring(1))&&this.hash===window.decodeURIComponent(window.location.hash.substring(1))){return}var newUrl=this._getUrl();var fullNewUrl=new URL(newUrl,window.location.protocol+"//"+window.location.host).href;var now=window.performance.now();var shouldReplace=this._lastChangedAt+this.dwellTime>now;this._lastChangedAt=now;if(shouldReplace){window.history.replaceState({},"",fullNewUrl)}else{window.history.pushState({},"",fullNewUrl)}this.fire("location-changed",{},{node:window})},_globalOnClick:function(event){if(event.defaultPrevented){return}var href=this._getSameOriginLinkHref(event);if(!href){return}event.preventDefault();if(href===window.location.href){return}window.history.pushState({},"",href);this.fire("location-changed",{},{node:window})},_getSameOriginLinkHref:function(event){if(event.button!==0){return null}if(event.metaKey||event.ctrlKey){return null}var eventPath=Polymer.dom(event).path;var anchor=null;for(var i=0;i<eventPath.length;i++){var element=eventPath[i];if(element.tagName==="A"&&element.href){anchor=element;break}}if(!anchor){return null}if(anchor.target==="_blank"){return null}if((anchor.target==="_top"||anchor.target==="_parent")&&window.top!==window){return null}var href=anchor.href;var url;if(document.baseURI!=null){url=new URL(href,document.baseURI)}else{url=new URL(href)}var origin;if(window.location.origin){origin=window.location.origin}else{origin=window.location.protocol+"//"+window.location.hostname;if(window.location.port){origin+=":"+window.location.port}}if(url.origin!==origin){return null}var normalizedHref=url.pathname+url.search+url.hash;if(this._urlSpaceRegExp&&!this._urlSpaceRegExp.test(normalizedHref)){return null}var fullNormalizedHref=new URL(normalizedHref,window.location.href).href;return fullNormalizedHref},_makeRegExp:function(urlSpaceRegex){return RegExp(urlSpaceRegex)}})})();"use strict";Polymer({is:"iron-query-params",properties:{paramsString:{type:String,notify:true,observer:"paramsStringChanged"},paramsObject:{type:Object,notify:true,value:function(){return{}}},_dontReact:{type:Boolean,value:false}},hostAttributes:{hidden:true},observers:["paramsObjectChanged(paramsObject.*)"],paramsStringChanged:function(){this._dontReact=true;this.paramsObject=this._decodeParams(this.paramsString);this._dontReact=false},paramsObjectChanged:function(){if(this._dontReact){return}this.paramsString=this._encodeParams(this.paramsObject)},_encodeParams:function(params){var encodedParams=[];for(var key in params){var value=params[key];if(value===""){encodedParams.push(encodeURIComponent(key))}else if(value){encodedParams.push(encodeURIComponent(key)+"="+encodeURIComponent(value.toString()))}}return encodedParams.join("&")},_decodeParams:function(paramString){var params={};paramString=(paramString||"").replace(/\+/g,"%20");var paramList=paramString.split("&");for(var i=0;i<paramList.length;i++){var param=paramList[i].split("=");if(param[0]){params[decodeURIComponent(param[0])]=decodeURIComponent(param[1]||"")}}return params}}); +Polymer({is:"history-list-container",properties:{groupedRange:{type:Number,observer:"groupedRangeChanged_"},selectedPage_:String,grouped:Boolean,queryState:Object,queryResult:Object,actionMenuModel_:Object},observers:["searchTermChanged_(queryState.searchTerm)","groupedOffsetChanged_(queryState.groupedOffset)"],listeners:{"load-more-history":"loadMoreHistory_","open-menu":"openMenu_"},historyResult:function(info,results){this.initializeResults_(info,results);this.closeMenu_();if(info.term&&!this.queryState.incremental){Polymer.IronA11yAnnouncer.requestAvailability();this.fire("iron-announce",{text:md_history.HistoryItem.searchResultsTitle(results.length,info.term)})}var list=this.getSelectedList_();list.addNewResults(results,this.queryState.incremental,info.finished)},queryHistory:function(incremental){var queryState=this.queryState;var noResults=!this.queryResult||this.queryResult.results==null;if(queryState.queryingDisabled||!this.queryState.searchTerm&&noResults){return}var dialog=this.$.dialog.getIfExists();if(!incremental&&dialog&&dialog.open)dialog.close();this.set("queryState.querying",true);this.set("queryState.incremental",incremental);var lastVisitTime=0;if(incremental){var lastVisit=this.queryResult.results.slice(-1)[0];lastVisitTime=lastVisit?Math.floor(lastVisit.time):0}var maxResults=this.groupedRange==HistoryRange.ALL_TIME?RESULTS_PER_PAGE:0;chrome.send("queryHistory",[queryState.searchTerm,queryState.groupedOffset,queryState.range,lastVisitTime,maxResults])},historyDeleted:function(){if(this.getSelectedItemCount()>0)return;this.queryHistory(false)},getContentScrollTarget:function(){return this.getSelectedList_()},getSelectedItemCount:function(){return this.getSelectedList_().selectedPaths.size},unselectAllItems:function(count){var selectedList=this.getSelectedList_();if(selectedList)selectedList.unselectAllItems(count)},deleteSelectedWithPrompt:function(){if(!loadTimeData.getBoolean("allowDeletingHistory"))return;var browserService=md_history.BrowserService.getInstance();browserService.recordAction("RemoveSelected");if(this.queryState.searchTerm!="")browserService.recordAction("SearchResultRemove");this.$.dialog.get().showModal();this.$$(".action-button").focus()},groupedRangeChanged_:function(range,oldRange){this.selectedPage_=range==HistoryRange.ALL_TIME?"infinite-list":"grouped-list";if(oldRange==undefined)return;this.set("queryState.groupedOffset",0);if(this.queryResult.info){this.set("queryResult.results",[]);this.historyResult(this.queryResult.info,[])}this.queryHistory(false);this.fire("history-view-changed")},searchTermChanged_:function(){this.queryHistory(false);if(this.queryState.searchTerm)md_history.BrowserService.getInstance().recordAction("Search")},groupedOffsetChanged_:function(){this.queryHistory(false)},loadMoreHistory_:function(){this.queryHistory(true)},initializeResults_:function(info,results){if(results.length==0)return;var currentDate=results[0].dateRelativeDay;for(var i=0;i<results.length;i++){results[i].selected=false;results[i].readableTimestamp=info.term==""?results[i].dateTimeOfDay:results[i].dateShort;if(results[i].dateRelativeDay!=currentDate){currentDate=results[i].dateRelativeDay}}},onDialogConfirmTap_:function(){md_history.BrowserService.getInstance().recordAction("ConfirmRemoveSelected");this.getSelectedList_().deleteSelected();var dialog=assert(this.$.dialog.getIfExists());dialog.close()},onDialogCancelTap_:function(){md_history.BrowserService.getInstance().recordAction("CancelRemoveSelected");var dialog=assert(this.$.dialog.getIfExists());dialog.close()},closeMenu_:function(){var menu=this.$.sharedMenu.getIfExists();if(menu&&menu.open){this.actionMenuModel_=null;menu.close()}},openMenu_:function(e){var target=e.detail.target;this.actionMenuModel_=e.detail;var menu=this.$.sharedMenu.get();menu.showAt(target)},onMoreFromSiteTap_:function(){md_history.BrowserService.getInstance().recordAction("EntryMenuShowMoreFromSite");var menu=assert(this.$.sharedMenu.getIfExists());this.set("queryState.searchTerm",this.actionMenuModel_.item.domain);this.actionMenuModel_=null;this.closeMenu_()},onRemoveFromHistoryTap_:function(){var browserService=md_history.BrowserService.getInstance();browserService.recordAction("EntryMenuRemoveFromHistory");var menu=assert(this.$.sharedMenu.getIfExists());var itemData=this.actionMenuModel_;browserService.deleteItems([itemData.item]).then(function(items){this.fire("unselect-all");this.getSelectedList_().removeItemsByPath([itemData.path]);var index=itemData.index;if(index==undefined)return;var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram("HistoryPage.RemoveEntryPosition",Math.min(index,UMA_MAX_BUCKET_VALUE),UMA_MAX_BUCKET_VALUE);if(index<=UMA_MAX_SUBSET_BUCKET_VALUE){browserService.recordHistogram("HistoryPage.RemoveEntryPositionSubset",index,UMA_MAX_SUBSET_BUCKET_VALUE)}}.bind(this));this.closeMenu_()},getSelectedList_:function(){return this.$$("#"+this.selectedPage_)},canDeleteHistory_:function(){return loadTimeData.getBoolean("allowDeletingHistory")}});(function(){"use strict";Polymer({is:"iron-location",properties:{path:{type:String,notify:true,value:function(){return window.decodeURIComponent(window.location.pathname)}},query:{type:String,notify:true,value:function(){return window.decodeURIComponent(window.location.search.slice(1))}},hash:{type:String,notify:true,value:function(){return window.decodeURIComponent(window.location.hash.slice(1))}},dwellTime:{type:Number,value:2e3},urlSpaceRegex:{type:String,value:""},_urlSpaceRegExp:{computed:"_makeRegExp(urlSpaceRegex)"},_lastChangedAt:{type:Number},_initialized:{type:Boolean,value:false}},hostAttributes:{hidden:true},observers:["_updateUrl(path, query, hash)"],attached:function(){this.listen(window,"hashchange","_hashChanged");this.listen(window,"location-changed","_urlChanged");this.listen(window,"popstate","_urlChanged");this.listen(document.body,"click","_globalOnClick");this._lastChangedAt=window.performance.now()-(this.dwellTime-200);this._initialized=true;this._urlChanged()},detached:function(){this.unlisten(window,"hashchange","_hashChanged");this.unlisten(window,"location-changed","_urlChanged");this.unlisten(window,"popstate","_urlChanged");this.unlisten(document.body,"click","_globalOnClick");this._initialized=false},_hashChanged:function(){this.hash=window.decodeURIComponent(window.location.hash.substring(1))},_urlChanged:function(){this._dontUpdateUrl=true;this._hashChanged();this.path=window.decodeURIComponent(window.location.pathname);this.query=window.decodeURIComponent(window.location.search.substring(1));this._dontUpdateUrl=false;this._updateUrl()},_getUrl:function(){var partiallyEncodedPath=window.encodeURI(this.path).replace(/\#/g,"%23").replace(/\?/g,"%3F");var partiallyEncodedQuery="";if(this.query){partiallyEncodedQuery="?"+window.encodeURI(this.query).replace(/\#/g,"%23")}var partiallyEncodedHash="";if(this.hash){partiallyEncodedHash="#"+window.encodeURI(this.hash)}return partiallyEncodedPath+partiallyEncodedQuery+partiallyEncodedHash},_updateUrl:function(){if(this._dontUpdateUrl||!this._initialized){return}if(this.path===window.decodeURIComponent(window.location.pathname)&&this.query===window.decodeURIComponent(window.location.search.substring(1))&&this.hash===window.decodeURIComponent(window.location.hash.substring(1))){return}var newUrl=this._getUrl();var fullNewUrl=new URL(newUrl,window.location.protocol+"//"+window.location.host).href;var now=window.performance.now();var shouldReplace=this._lastChangedAt+this.dwellTime>now;this._lastChangedAt=now;if(shouldReplace){window.history.replaceState({},"",fullNewUrl)}else{window.history.pushState({},"",fullNewUrl)}this.fire("location-changed",{},{node:window})},_globalOnClick:function(event){if(event.defaultPrevented){return}var href=this._getSameOriginLinkHref(event);if(!href){return}event.preventDefault();if(href===window.location.href){return}window.history.pushState({},"",href);this.fire("location-changed",{},{node:window})},_getSameOriginLinkHref:function(event){if(event.button!==0){return null}if(event.metaKey||event.ctrlKey){return null}var eventPath=Polymer.dom(event).path;var anchor=null;for(var i=0;i<eventPath.length;i++){var element=eventPath[i];if(element.tagName==="A"&&element.href){anchor=element;break}}if(!anchor){return null}if(anchor.target==="_blank"){return null}if((anchor.target==="_top"||anchor.target==="_parent")&&window.top!==window){return null}var href=anchor.href;var url;if(document.baseURI!=null){url=new URL(href,document.baseURI)}else{url=new URL(href)}var origin;if(window.location.origin){origin=window.location.origin}else{origin=window.location.protocol+"//"+window.location.hostname;if(window.location.port){origin+=":"+window.location.port}}if(url.origin!==origin){return null}var normalizedHref=url.pathname+url.search+url.hash;if(this._urlSpaceRegExp&&!this._urlSpaceRegExp.test(normalizedHref)){return null}var fullNormalizedHref=new URL(normalizedHref,window.location.href).href;return fullNormalizedHref},_makeRegExp:function(urlSpaceRegex){return RegExp(urlSpaceRegex)}})})();"use strict";Polymer({is:"iron-query-params",properties:{paramsString:{type:String,notify:true,observer:"paramsStringChanged"},paramsObject:{type:Object,notify:true,value:function(){return{}}},_dontReact:{type:Boolean,value:false}},hostAttributes:{hidden:true},observers:["paramsObjectChanged(paramsObject.*)"],paramsStringChanged:function(){this._dontReact=true;this.paramsObject=this._decodeParams(this.paramsString);this._dontReact=false},paramsObjectChanged:function(){if(this._dontReact){return}this.paramsString=this._encodeParams(this.paramsObject)},_encodeParams:function(params){var encodedParams=[];for(var key in params){var value=params[key];if(value===""){encodedParams.push(encodeURIComponent(key))}else if(value){encodedParams.push(encodeURIComponent(key)+"="+encodeURIComponent(value.toString()))}}return encodedParams.join("&")},_decodeParams:function(paramString){var params={};paramString=(paramString||"").replace(/\+/g,"%20");var paramList=paramString.split("&");for(var i=0;i<paramList.length;i++){var param=paramList[i].split("=");if(param[0]){params[decodeURIComponent(param[0])]=decodeURIComponent(param[1]||"")}}return params}}); // Copyright 2016 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.
diff --git a/chrome/browser/resources/md_history/app.vulcanized.html b/chrome/browser/resources/md_history/app.vulcanized.html index 303a644..ebc7206 100644 --- a/chrome/browser/resources/md_history/app.vulcanized.html +++ b/chrome/browser/resources/md_history/app.vulcanized.html
@@ -22,27 +22,9 @@ The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as part of the polymer project is also subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---><meta charset="UTF-8"><link rel="import" href="chrome://resources/html/polymer.html"> -<style> -/* Copyright 2016 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. */ +--><meta charset="UTF-8"> -:root { - /* This is a custom, Chrome-specific color that does not have a --paper or - * --google equivalent. */ - --md-background-color: #f1f1f1; - --md-loading-message-color: #6e6e6e; - /* This is --google-blue-700, rewritten as a native custom property for speed. - */ - --md-toolbar-color: rgb(51, 103, 214); -} - -</style> - - - -</head><body><div hidden="" by-vulcanize=""><dom-module id="iron-pages" assetpath="chrome://resources/polymer/v1_0/iron-pages/" css-build="shadow"> +</head><body><div hidden="" by-vulcanize=""><link rel="import" href="chrome://resources/html/polymer.html"><dom-module id="iron-pages" assetpath="chrome://resources/polymer/v1_0/iron-pages/" css-build="shadow"> <template> <style scope="iron-pages">:host { @@ -185,8 +167,6 @@ } </style> - - <dom-module id="iron-icon" assetpath="chrome://resources/polymer/v1_0/iron-icon/" css-build="shadow"> <template> <style scope="iron-icon">:host { @@ -299,6 +279,46 @@ </template> </dom-module> <style is="custom-style" css-build="shadow">html { + --primary-text-color: var(--light-theme-text-color); + --primary-background-color: var(--light-theme-background-color); + --secondary-text-color: var(--light-theme-secondary-color); + --disabled-text-color: var(--light-theme-disabled-color); + --divider-color: var(--light-theme-divider-color); + --error-color: var(--paper-deep-orange-a700); + + + --primary-color: var(--paper-indigo-500); + --light-primary-color: var(--paper-indigo-100); + --dark-primary-color: var(--paper-indigo-700); + + --accent-color: var(--paper-pink-a200); + --light-accent-color: var(--paper-pink-a100); + --dark-accent-color: var(--paper-pink-a400); + + + + --light-theme-background-color: #ffffff; + --light-theme-base-color: #000000; + --light-theme-text-color: var(--paper-grey-900); + --light-theme-secondary-color: #737373; + --light-theme-disabled-color: #9b9b9b; + --light-theme-divider-color: #dbdbdb; + + + --dark-theme-background-color: var(--paper-grey-900); + --dark-theme-base-color: #ffffff; + --dark-theme-text-color: #ffffff; + --dark-theme-secondary-color: #bcbcbc; + --dark-theme-disabled-color: #646464; + --dark-theme-divider-color: #3c3c3c; + + + --text-primary-color: var(--dark-theme-text-color); + --default-primary-color: var(--primary-color); +} + +</style> +<style is="custom-style" css-build="shadow">html { --google-red-100: #f4c7c3; --google-red-300: #e67c73; --google-red-500: #db4437; @@ -613,50 +633,6 @@ } </style> - - -<style is="custom-style" css-build="shadow">html { - --primary-text-color: var(--light-theme-text-color); - --primary-background-color: var(--light-theme-background-color); - --secondary-text-color: var(--light-theme-secondary-color); - --disabled-text-color: var(--light-theme-disabled-color); - --divider-color: var(--light-theme-divider-color); - --error-color: var(--paper-deep-orange-a700); - - - --primary-color: var(--paper-indigo-500); - --light-primary-color: var(--paper-indigo-100); - --dark-primary-color: var(--paper-indigo-700); - - --accent-color: var(--paper-pink-a200); - --light-accent-color: var(--paper-pink-a100); - --dark-accent-color: var(--paper-pink-a400); - - - - --light-theme-background-color: #ffffff; - --light-theme-base-color: #000000; - --light-theme-text-color: var(--paper-grey-900); - --light-theme-secondary-color: #737373; - --light-theme-disabled-color: #9b9b9b; - --light-theme-divider-color: #dbdbdb; - - - --dark-theme-background-color: var(--paper-grey-900); - --dark-theme-base-color: #ffffff; - --dark-theme-text-color: #ffffff; - --dark-theme-secondary-color: #bcbcbc; - --dark-theme-disabled-color: #646464; - --dark-theme-divider-color: #3c3c3c; - - - --text-primary-color: var(--dark-theme-text-color); - --default-primary-color: var(--primary-color); -} - -</style> - - <dom-module id="paper-icon-button" assetpath="chrome://resources/polymer/v1_0/paper-icon-button/" css-build="shadow"> <template strip-whitespace=""> <style scope="paper-icon-button">:host { @@ -686,12 +662,12 @@ } :host #ink { - color: var(--paper-icon-button-ink-color,var(--primary-text-color));; + color: var(--paper-icon-button-ink-color,var(--primary-text-color)); opacity: 0.6; } :host([disabled]) { - color: var(--paper-icon-button-disabled-text,var(--disabled-text-color));; + color: var(--paper-icon-button-disabled-text,var(--disabled-text-color)); pointer-events: none; cursor: auto; @@ -767,23 +743,23 @@ height: 100%; opacity: 0; white-space: nowrap; - border-color: var(--paper-spinner-color,var(--google-blue-500));; + border-color: var(--paper-spinner-color,var(--google-blue-500)); } .layer-1 { - border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500));; + border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500)); } .layer-2 { - border-color: var(--paper-spinner-layer-2-color,var(--google-red-500));; + border-color: var(--paper-spinner-layer-2-color,var(--google-red-500)); } .layer-3 { - border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500));; + border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500)); } .layer-4 { - border-color: var(--paper-spinner-layer-4-color,var(--google-green-500));; + border-color: var(--paper-spinner-layer-4-color,var(--google-green-500)); } .active .spinner-layer { @@ -1251,8 +1227,6 @@ </style> </template> </dom-module> - - <dom-module id="paper-spinner-lite" assetpath="chrome://resources/polymer/v1_0/paper-spinner/" css-build="shadow"> <template strip-whitespace=""> <style scope="paper-spinner-lite">:host { @@ -1307,23 +1281,23 @@ height: 100%; opacity: 0; white-space: nowrap; - border-color: var(--paper-spinner-color,var(--google-blue-500));; + border-color: var(--paper-spinner-color,var(--google-blue-500)); } .layer-1 { - border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500));; + border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500)); } .layer-2 { - border-color: var(--paper-spinner-layer-2-color,var(--google-red-500));; + border-color: var(--paper-spinner-layer-2-color,var(--google-red-500)); } .layer-3 { - border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500));; + border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500)); } .layer-4 { - border-color: var(--paper-spinner-layer-4-color,var(--google-green-500));; + border-color: var(--paper-spinner-layer-4-color,var(--google-green-500)); } .active .spinner-layer { @@ -2081,8 +2055,7 @@ </div> </template> </dom-module> -<link rel="import" href="chrome://history/constants.html"> -<iron-iconset-svg size="24" name="history"> +<link rel="import" href="chrome://history/constants.html"><iron-iconset-svg size="24" name="history"> <svg> <defs> @@ -2152,13 +2125,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat; @@ -2205,8 +2171,6 @@ </style> </template> </dom-module> - - <dom-module id="history-toolbar" assetpath="chrome://history/" css-build="shadow"> <template> <style scope="history-toolbar">[hidden] { @@ -2243,13 +2207,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat; @@ -2492,6 +2449,9 @@ </template> </dom-module> + + + <style is="custom-style" css-build="shadow">html { --cr-actionable_-_cursor: pointer;; --cr-focused-item-color: var(--google-grey-300); @@ -2512,7 +2472,6 @@ } </style> - <dom-module id="cr-shared-style" assetpath="chrome://resources/cr_elements/" css-build="shadow"> <template> <style scope="cr-shared-style">paper-spinner { @@ -2723,12 +2682,9 @@ } </style> -<link rel="import" href="chrome://resources/html/util.html"> -<dom-module id="history-searched-label" assetpath="chrome://history/" css-build="shadow"> +<link rel="import" href="chrome://resources/html/util.html"><dom-module id="history-searched-label" assetpath="/" css-build="shadow"> </dom-module> - - -<dom-module id="history-item" assetpath="chrome://history/" css-build="shadow"> +<dom-module id="history-item" assetpath="/" css-build="shadow"> <template> <style scope="history-item">[hidden] { display: none !important; @@ -2764,13 +2720,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat; @@ -3076,13 +3025,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat; @@ -3151,8 +3093,6 @@ </iron-scroll-threshold> </template> </dom-module> - - <dom-module id="history-list-container" assetpath="chrome://history/" css-build="shadow"> <template> <style scope="history-list-container">[hidden] { @@ -3189,13 +3129,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat; @@ -3376,14 +3309,14 @@ </template> <template is="cr-lazy-render" id="sharedMenu"> - <cr-shared-menu> - <paper-item id="menuMoreButton" class="menu-item" on-tap="onMoreFromSiteTap_"> + <dialog is="cr-action-menu"> + <button id="menuMoreButton" class="dropdown-item" on-tap="onMoreFromSiteTap_"> $i18n{moreFromSite} - </paper-item> - <paper-item id="menuRemoveButton" class="menu-item" disabled="[[!canDeleteHistory_()]]" on-tap="onRemoveFromHistoryTap_"> + </button> + <button id="menuRemoveButton" class="dropdown-item" disabled="[[!canDeleteHistory_()]]" on-tap="onRemoveFromHistoryTap_"> $i18n{removeFromHistory} - </paper-item> - </cr-shared-menu> + </button> + </dialog> </template> </template> </dom-module> @@ -3395,38 +3328,6 @@ </iron-query-params> </template> </dom-module> -<style> -/* Copyright 2015 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. */ - -<if expr="not chromeos and not is_android"> -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), - url("chrome://resources/roboto/roboto-regular.woff2") format('woff2'); -} - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), - url("chrome://resources/roboto/roboto-medium.woff2") format('woff2'); -} - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), - url("chrome://resources/roboto/roboto-bold.woff2") format('woff2'); -} -</if> - -</style> <style is="custom-style" css-build="shadow">html { --paper-font-common-base_-_font-family: 'Roboto', 'Noto', sans-serif; --paper-font-common-base_-_-webkit-font-smoothing: antialiased;; @@ -3468,7 +3369,38 @@ } </style> -<dom-module id="history-side-bar" assetpath="chrome://history/" css-build="shadow"> +<style> +/* Copyright 2015 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. */ + +<if expr="not chromeos and not is_android"> +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 400; + src: local('Roboto'), local('Roboto-Regular'), + url("chrome://resources/roboto/roboto-regular.woff2") format('woff2'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 500; + src: local('Roboto Medium'), local('Roboto-Medium'), + url("chrome://resources/roboto/roboto-medium.woff2") format('woff2'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 700; + src: local('Roboto Bold'), local('Roboto-Bold'), + url("chrome://resources/roboto/roboto-bold.woff2") format('woff2'); +} +</if> + +</style><dom-module id="history-side-bar" assetpath="chrome://history/" css-build="shadow"> <template> <style scope="history-side-bar">[hidden] { display: none !important; @@ -3504,13 +3436,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat; @@ -3662,7 +3587,22 @@ </iron-selector> </template> </dom-module> -</div><dom-module id="history-app" css-build="shadow"> +<style> +/* Copyright 2016 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. */ + +:root { + /* This is a custom, Chrome-specific color that does not have a --paper or + * --google equivalent. */ + --md-background-color: #f1f1f1; + --md-loading-message-color: #6e6e6e; + /* This is --google-blue-700, rewritten as a native custom property for speed. + */ + --md-toolbar-color: rgb(51, 103, 214); +} + +</style></div><dom-module id="history-app" css-build="shadow"> <template> <style scope="history-app">[hidden] { display: none !important; @@ -3698,13 +3638,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat;
diff --git a/chrome/browser/resources/md_history/compiled_resources2.gyp b/chrome/browser/resources/md_history/compiled_resources2.gyp index 4bdffd09..f4cdc90d 100644 --- a/chrome/browser/resources/md_history/compiled_resources2.gyp +++ b/chrome/browser/resources/md_history/compiled_resources2.gyp
@@ -52,7 +52,7 @@ 'dependencies': [ '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-list/compiled_resources2.gyp:iron-list-extracted', '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-scroll-threshold/compiled_resources2.gyp:iron-scroll-threshold-extracted', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp:cr_shared_menu', + '<(DEPTH)/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp:cr_action_menu', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', 'constants', @@ -154,7 +154,7 @@ 'target_name': 'synced_device_manager', 'dependencies': [ '<(DEPTH)/ui/webui/resources/cr_elements/cr_lazy_render/compiled_resources2.gyp:cr_lazy_render', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp:cr_shared_menu', + '<(DEPTH)/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp:cr_action_menu', '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_grid', 'browser_service', 'synced_device_card',
diff --git a/chrome/browser/resources/md_history/history_item.js b/chrome/browser/resources/md_history/history_item.js index 0b77b36..dbd8b19 100644 --- a/chrome/browser/resources/md_history/history_item.js +++ b/chrome/browser/resources/md_history/history_item.js
@@ -258,7 +258,7 @@ * of the history item and where the menu should appear. */ onMenuButtonTap_: function(e) { - this.fire('toggle-menu', { + this.fire('open-menu', { target: Polymer.dom(e).localTarget, index: this.index, item: this.item,
diff --git a/chrome/browser/resources/md_history/history_list.js b/chrome/browser/resources/md_history/history_list.js index 608b05a4..4cfb8ca 100644 --- a/chrome/browser/resources/md_history/history_list.js +++ b/chrome/browser/resources/md_history/history_list.js
@@ -28,7 +28,6 @@ }, listeners: { - 'scroll': 'notifyListScroll_', 'remove-bookmark-stars': 'removeBookmarkStars_', }, @@ -152,11 +151,6 @@ }, /** - * @private - */ - notifyListScroll_: function() { this.fire('history-list-scrolled'); }, - - /** * @param {number} index * @return {string} * @private
diff --git a/chrome/browser/resources/md_history/lazy_load.crisper.js b/chrome/browser/resources/md_history/lazy_load.crisper.js index bc07832..ae0f1d9 100644 --- a/chrome/browser/resources/md_history/lazy_load.crisper.js +++ b/chrome/browser/resources/md_history/lazy_load.crisper.js
@@ -6,21 +6,20 @@ // Copyright 2014 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. -cr.define("cr.ui",function(){function FocusGrid(){this.rows=[]}FocusGrid.prototype={ignoreFocusChange_:false,onFocus:function(row,e){if(this.ignoreFocusChange_)this.ignoreFocusChange_=false;else this.lastFocused_=e.currentTarget;this.rows.forEach(function(r){r.makeActive(r==row)})},onKeydown:function(row,e){var rowIndex=this.rows.indexOf(row);assert(rowIndex>=0);var newRow=-1;if(e.key=="ArrowUp")newRow=rowIndex-1;else if(e.key=="ArrowDown")newRow=rowIndex+1;else if(e.key=="PageUp")newRow=0;else if(e.key=="PageDown")newRow=this.rows.length-1;var rowToFocus=this.rows[newRow];if(rowToFocus){this.ignoreFocusChange_=true;rowToFocus.getEquivalentElement(this.lastFocused_).focus();e.preventDefault();return true}return false},destroy:function(){this.rows.forEach(function(row){row.destroy()});this.rows.length=0},getRowIndexForTarget:function(target){for(var i=0;i<this.rows.length;++i){if(this.rows[i].getElements().indexOf(target)>=0)return i}return-1},getRowForRoot:function(root){for(var i=0;i<this.rows.length;++i){if(this.rows[i].root==root)return this.rows[i]}return null},addRow:function(row){this.addRowBefore(row,null)},addRowBefore:function(row,nextRow){row.delegate=row.delegate||this;var nextRowIndex=nextRow?this.rows.indexOf(nextRow):-1;if(nextRowIndex==-1)this.rows.push(row);else this.rows.splice(nextRowIndex,0,row)},removeRow:function(row){var nextRowIndex=row?this.rows.indexOf(row):-1;if(nextRowIndex>-1)this.rows.splice(nextRowIndex,1)},ensureRowActive:function(){if(this.rows.length==0)return;for(var i=0;i<this.rows.length;++i){if(this.rows[i].isActive())return}this.rows[0].makeActive(true)}};return{FocusGrid:FocusGrid}});Polymer.PaperButtonBehaviorImpl={properties:{elevation:{type:Number,reflectToAttribute:true,readOnly:true}},observers:["_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)","_computeKeyboardClass(receivedFocusFromKeyboard)"],hostAttributes:{role:"button",tabindex:"0",animated:true},_calculateElevation:function(){var e=1;if(this.disabled){e=0}else if(this.active||this.pressed){e=4}else if(this.receivedFocusFromKeyboard){e=3}this._setElevation(e)},_computeKeyboardClass:function(receivedFocusFromKeyboard){this.toggleClass("keyboard-focus",receivedFocusFromKeyboard)},_spaceKeyDownHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this,event);if(this.hasRipple()&&this.getRipple().ripples.length<1){this._ripple.uiDownAction()}},_spaceKeyUpHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this,event);if(this.hasRipple()){this._ripple.uiUpAction()}}};Polymer.PaperButtonBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperButtonBehaviorImpl];Polymer({is:"paper-button",behaviors:[Polymer.PaperButtonBehavior],properties:{raised:{type:Boolean,reflectToAttribute:true,value:false,observer:"_calculateElevation"}},_calculateElevation:function(){if(!this.raised){this._setElevation(0)}else{Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this)}}});Polymer.PaperItemBehaviorImpl={hostAttributes:{role:"option",tabindex:"0"}};Polymer.PaperItemBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperItemBehaviorImpl];Polymer({is:"paper-item",behaviors:[Polymer.PaperItemBehavior]});Polymer.IronFitBehavior={properties:{sizingTarget:{type:Object,value:function(){return this}},fitInto:{type:Object,value:window},noOverlap:{type:Boolean},positionTarget:{type:Element},horizontalAlign:{type:String},verticalAlign:{type:String},dynamicAlign:{type:Boolean},horizontalOffset:{type:Number,value:0,notify:true},verticalOffset:{type:Number,value:0,notify:true},autoFitOnAttach:{type:Boolean,value:false},_fitInfo:{type:Object}},get _fitWidth(){var fitWidth;if(this.fitInto===window){fitWidth=this.fitInto.innerWidth}else{fitWidth=this.fitInto.getBoundingClientRect().width}return fitWidth},get _fitHeight(){var fitHeight;if(this.fitInto===window){fitHeight=this.fitInto.innerHeight}else{fitHeight=this.fitInto.getBoundingClientRect().height}return fitHeight},get _fitLeft(){var fitLeft;if(this.fitInto===window){fitLeft=0}else{fitLeft=this.fitInto.getBoundingClientRect().left}return fitLeft},get _fitTop(){var fitTop;if(this.fitInto===window){fitTop=0}else{fitTop=this.fitInto.getBoundingClientRect().top}return fitTop},get _defaultPositionTarget(){var parent=Polymer.dom(this).parentNode;if(parent&&parent.nodeType===Node.DOCUMENT_FRAGMENT_NODE){parent=parent.host}return parent},get _localeHorizontalAlign(){if(this._isRTL){if(this.horizontalAlign==="right"){return"left"}if(this.horizontalAlign==="left"){return"right"}}return this.horizontalAlign},attached:function(){this._isRTL=window.getComputedStyle(this).direction=="rtl";this.positionTarget=this.positionTarget||this._defaultPositionTarget;if(this.autoFitOnAttach){if(window.getComputedStyle(this).display==="none"){setTimeout(function(){this.fit()}.bind(this))}else{this.fit()}}},fit:function(){this.position();this.constrain();this.center()},_discoverInfo:function(){if(this._fitInfo){return}var target=window.getComputedStyle(this);var sizer=window.getComputedStyle(this.sizingTarget);this._fitInfo={inlineStyle:{top:this.style.top||"",left:this.style.left||"",position:this.style.position||""},sizerInlineStyle:{maxWidth:this.sizingTarget.style.maxWidth||"",maxHeight:this.sizingTarget.style.maxHeight||"",boxSizing:this.sizingTarget.style.boxSizing||""},positionedBy:{vertically:target.top!=="auto"?"top":target.bottom!=="auto"?"bottom":null,horizontally:target.left!=="auto"?"left":target.right!=="auto"?"right":null},sizedBy:{height:sizer.maxHeight!=="none",width:sizer.maxWidth!=="none",minWidth:parseInt(sizer.minWidth,10)||0,minHeight:parseInt(sizer.minHeight,10)||0},margin:{top:parseInt(target.marginTop,10)||0,right:parseInt(target.marginRight,10)||0,bottom:parseInt(target.marginBottom,10)||0,left:parseInt(target.marginLeft,10)||0}};if(this.verticalOffset){this._fitInfo.margin.top=this._fitInfo.margin.bottom=this.verticalOffset;this._fitInfo.inlineStyle.marginTop=this.style.marginTop||"";this._fitInfo.inlineStyle.marginBottom=this.style.marginBottom||"";this.style.marginTop=this.style.marginBottom=this.verticalOffset+"px"}if(this.horizontalOffset){this._fitInfo.margin.left=this._fitInfo.margin.right=this.horizontalOffset;this._fitInfo.inlineStyle.marginLeft=this.style.marginLeft||"";this._fitInfo.inlineStyle.marginRight=this.style.marginRight||"";this.style.marginLeft=this.style.marginRight=this.horizontalOffset+"px"}},resetFit:function(){var info=this._fitInfo||{};for(var property in info.sizerInlineStyle){this.sizingTarget.style[property]=info.sizerInlineStyle[property]}for(var property in info.inlineStyle){this.style[property]=info.inlineStyle[property]}this._fitInfo=null},refit:function(){var scrollLeft=this.sizingTarget.scrollLeft;var scrollTop=this.sizingTarget.scrollTop;this.resetFit();this.fit();this.sizingTarget.scrollLeft=scrollLeft;this.sizingTarget.scrollTop=scrollTop},position:function(){if(!this.horizontalAlign&&!this.verticalAlign){return}this._discoverInfo();this.style.position="fixed";this.sizingTarget.style.boxSizing="border-box";this.style.left="0px";this.style.top="0px";var rect=this.getBoundingClientRect();var positionRect=this.__getNormalizedRect(this.positionTarget);var fitRect=this.__getNormalizedRect(this.fitInto);var margin=this._fitInfo.margin;var size={width:rect.width+margin.left+margin.right,height:rect.height+margin.top+margin.bottom};var position=this.__getPosition(this._localeHorizontalAlign,this.verticalAlign,size,positionRect,fitRect);var left=position.left+margin.left;var top=position.top+margin.top;var right=Math.min(fitRect.right-margin.right,left+rect.width);var bottom=Math.min(fitRect.bottom-margin.bottom,top+rect.height);var minWidth=this._fitInfo.sizedBy.minWidth;var minHeight=this._fitInfo.sizedBy.minHeight;if(left<margin.left){left=margin.left;if(right-left<minWidth){left=right-minWidth}}if(top<margin.top){top=margin.top;if(bottom-top<minHeight){top=bottom-minHeight}}this.sizingTarget.style.maxWidth=right-left+"px";this.sizingTarget.style.maxHeight=bottom-top+"px";this.style.left=left-rect.left+"px";this.style.top=top-rect.top+"px"},constrain:function(){if(this.horizontalAlign||this.verticalAlign){return}this._discoverInfo();var info=this._fitInfo;if(!info.positionedBy.vertically){this.style.position="fixed";this.style.top="0px"}if(!info.positionedBy.horizontally){this.style.position="fixed";this.style.left="0px"}this.sizingTarget.style.boxSizing="border-box";var rect=this.getBoundingClientRect();if(!info.sizedBy.height){this.__sizeDimension(rect,info.positionedBy.vertically,"top","bottom","Height")}if(!info.sizedBy.width){this.__sizeDimension(rect,info.positionedBy.horizontally,"left","right","Width")}},_sizeDimension:function(rect,positionedBy,start,end,extent){this.__sizeDimension(rect,positionedBy,start,end,extent)},__sizeDimension:function(rect,positionedBy,start,end,extent){var info=this._fitInfo;var fitRect=this.__getNormalizedRect(this.fitInto);var max=extent==="Width"?fitRect.width:fitRect.height;var flip=positionedBy===end;var offset=flip?max-rect[end]:rect[start];var margin=info.margin[flip?start:end];var offsetExtent="offset"+extent;var sizingOffset=this[offsetExtent]-this.sizingTarget[offsetExtent];this.sizingTarget.style["max"+extent]=max-margin-offset-sizingOffset+"px"},center:function(){if(this.horizontalAlign||this.verticalAlign){return}this._discoverInfo();var positionedBy=this._fitInfo.positionedBy;if(positionedBy.vertically&&positionedBy.horizontally){return}this.style.position="fixed";if(!positionedBy.vertically){this.style.top="0px"}if(!positionedBy.horizontally){this.style.left="0px"}var rect=this.getBoundingClientRect();var fitRect=this.__getNormalizedRect(this.fitInto);if(!positionedBy.vertically){var top=fitRect.top-rect.top+(fitRect.height-rect.height)/2;this.style.top=top+"px"}if(!positionedBy.horizontally){var left=fitRect.left-rect.left+(fitRect.width-rect.width)/2;this.style.left=left+"px"}},__getNormalizedRect:function(target){if(target===document.documentElement||target===window){return{top:0,left:0,width:window.innerWidth,height:window.innerHeight,right:window.innerWidth,bottom:window.innerHeight}}return target.getBoundingClientRect()},__getCroppedArea:function(position,size,fitRect){var verticalCrop=Math.min(0,position.top)+Math.min(0,fitRect.bottom-(position.top+size.height));var horizontalCrop=Math.min(0,position.left)+Math.min(0,fitRect.right-(position.left+size.width));return Math.abs(verticalCrop)*size.width+Math.abs(horizontalCrop)*size.height},__getPosition:function(hAlign,vAlign,size,positionRect,fitRect){var positions=[{verticalAlign:"top",horizontalAlign:"left",top:positionRect.top,left:positionRect.left},{verticalAlign:"top",horizontalAlign:"right",top:positionRect.top,left:positionRect.right-size.width},{verticalAlign:"bottom",horizontalAlign:"left",top:positionRect.bottom-size.height,left:positionRect.left},{verticalAlign:"bottom",horizontalAlign:"right",top:positionRect.bottom-size.height,left:positionRect.right-size.width}];if(this.noOverlap){for(var i=0,l=positions.length;i<l;i++){var copy={};for(var key in positions[i]){copy[key]=positions[i][key]}positions.push(copy)}positions[0].top=positions[1].top+=positionRect.height;positions[2].top=positions[3].top-=positionRect.height;positions[4].left=positions[6].left+=positionRect.width;positions[5].left=positions[7].left-=positionRect.width}vAlign=vAlign==="auto"?null:vAlign;hAlign=hAlign==="auto"?null:hAlign;var position;for(var i=0;i<positions.length;i++){var pos=positions[i];if(!this.dynamicAlign&&!this.noOverlap&&pos.verticalAlign===vAlign&&pos.horizontalAlign===hAlign){position=pos;break}var alignOk=(!vAlign||pos.verticalAlign===vAlign)&&(!hAlign||pos.horizontalAlign===hAlign);if(!this.dynamicAlign&&!alignOk){continue}position=position||pos;pos.croppedArea=this.__getCroppedArea(pos,size,fitRect);var diff=pos.croppedArea-position.croppedArea;if(diff<0||diff===0&&alignOk){position=pos}if(position.croppedArea===0&&alignOk){break}}return position}};(function(){"use strict";Polymer({is:"iron-overlay-backdrop",properties:{opened:{reflectToAttribute:true,type:Boolean,value:false,observer:"_openedChanged"}},listeners:{transitionend:"_onTransitionend"},created:function(){this.__openedRaf=null},attached:function(){this.opened&&this._openedChanged(this.opened)},prepare:function(){if(this.opened&&!this.parentNode){Polymer.dom(document.body).appendChild(this)}},open:function(){this.opened=true},close:function(){this.opened=false},complete:function(){if(!this.opened&&this.parentNode===document.body){Polymer.dom(this.parentNode).removeChild(this)}},_onTransitionend:function(event){if(event&&event.target===this){this.complete()}},_openedChanged:function(opened){if(opened){this.prepare()}else{var cs=window.getComputedStyle(this);if(cs.transitionDuration==="0s"||cs.opacity==0){this.complete()}}if(!this.isAttached){return}if(this.__openedRaf){window.cancelAnimationFrame(this.__openedRaf);this.__openedRaf=null}this.scrollTop=this.scrollTop;this.__openedRaf=window.requestAnimationFrame(function(){this.__openedRaf=null;this.toggleClass("opened",this.opened)}.bind(this))}})})();Polymer.IronOverlayManagerClass=function(){this._overlays=[];this._minimumZ=101;this._backdropElement=null;Polymer.Gestures.add(document,"tap",this._onCaptureClick.bind(this));document.addEventListener("focus",this._onCaptureFocus.bind(this),true);document.addEventListener("keydown",this._onCaptureKeyDown.bind(this),true)};Polymer.IronOverlayManagerClass.prototype={constructor:Polymer.IronOverlayManagerClass,get backdropElement(){if(!this._backdropElement){this._backdropElement=document.createElement("iron-overlay-backdrop")}return this._backdropElement},get deepActiveElement(){var active=document.activeElement||document.body;while(active.root&&Polymer.dom(active.root).activeElement){active=Polymer.dom(active.root).activeElement}return active},_bringOverlayAtIndexToFront:function(i){var overlay=this._overlays[i];if(!overlay){return}var lastI=this._overlays.length-1;var currentOverlay=this._overlays[lastI];if(currentOverlay&&this._shouldBeBehindOverlay(overlay,currentOverlay)){lastI--}if(i>=lastI){return}var minimumZ=Math.max(this.currentOverlayZ(),this._minimumZ);if(this._getZ(overlay)<=minimumZ){this._applyOverlayZ(overlay,minimumZ)}while(i<lastI){this._overlays[i]=this._overlays[i+1];i++}this._overlays[lastI]=overlay},addOrRemoveOverlay:function(overlay){if(overlay.opened){this.addOverlay(overlay)}else{this.removeOverlay(overlay)}},addOverlay:function(overlay){var i=this._overlays.indexOf(overlay);if(i>=0){this._bringOverlayAtIndexToFront(i);this.trackBackdrop();return}var insertionIndex=this._overlays.length;var currentOverlay=this._overlays[insertionIndex-1];var minimumZ=Math.max(this._getZ(currentOverlay),this._minimumZ);var newZ=this._getZ(overlay);if(currentOverlay&&this._shouldBeBehindOverlay(overlay,currentOverlay)){this._applyOverlayZ(currentOverlay,minimumZ);insertionIndex--;var previousOverlay=this._overlays[insertionIndex-1];minimumZ=Math.max(this._getZ(previousOverlay),this._minimumZ)}if(newZ<=minimumZ){this._applyOverlayZ(overlay,minimumZ)}this._overlays.splice(insertionIndex,0,overlay);this.trackBackdrop()},removeOverlay:function(overlay){var i=this._overlays.indexOf(overlay);if(i===-1){return}this._overlays.splice(i,1);this.trackBackdrop()},currentOverlay:function(){var i=this._overlays.length-1;return this._overlays[i]},currentOverlayZ:function(){return this._getZ(this.currentOverlay())},ensureMinimumZ:function(minimumZ){this._minimumZ=Math.max(this._minimumZ,minimumZ)},focusOverlay:function(){var current=this.currentOverlay();if(current){current._applyFocus()}},trackBackdrop:function(){var overlay=this._overlayWithBackdrop();if(!overlay&&!this._backdropElement){return}this.backdropElement.style.zIndex=this._getZ(overlay)-1;this.backdropElement.opened=!!overlay},getBackdrops:function(){var backdrops=[];for(var i=0;i<this._overlays.length;i++){if(this._overlays[i].withBackdrop){backdrops.push(this._overlays[i])}}return backdrops},backdropZ:function(){return this._getZ(this._overlayWithBackdrop())-1},_overlayWithBackdrop:function(){for(var i=0;i<this._overlays.length;i++){if(this._overlays[i].withBackdrop){return this._overlays[i]}}},_getZ:function(overlay){var z=this._minimumZ;if(overlay){var z1=Number(overlay.style.zIndex||window.getComputedStyle(overlay).zIndex);if(z1===z1){z=z1}}return z},_setZ:function(element,z){element.style.zIndex=z},_applyOverlayZ:function(overlay,aboveZ){this._setZ(overlay,aboveZ+2)},_overlayInPath:function(path){path=path||[];for(var i=0;i<path.length;i++){if(path[i]._manager===this){return path[i]}}},_onCaptureClick:function(event){var overlay=this.currentOverlay();if(overlay&&this._overlayInPath(Polymer.dom(event).path)!==overlay){overlay._onCaptureClick(event)}},_onCaptureFocus:function(event){var overlay=this.currentOverlay();if(overlay){overlay._onCaptureFocus(event)}},_onCaptureKeyDown:function(event){var overlay=this.currentOverlay();if(overlay){if(Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event,"esc")){overlay._onCaptureEsc(event)}else if(Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event,"tab")){overlay._onCaptureTab(event)}}},_shouldBeBehindOverlay:function(overlay1,overlay2){return!overlay1.alwaysOnTop&&overlay2.alwaysOnTop}};Polymer.IronOverlayManager=new Polymer.IronOverlayManagerClass;(function(){"use strict";Polymer.IronOverlayBehaviorImpl={properties:{opened:{observer:"_openedChanged",type:Boolean,value:false,notify:true},canceled:{observer:"_canceledChanged",readOnly:true,type:Boolean,value:false},withBackdrop:{observer:"_withBackdropChanged",type:Boolean},noAutoFocus:{type:Boolean,value:false},noCancelOnEscKey:{type:Boolean,value:false},noCancelOnOutsideClick:{type:Boolean,value:false},closingReason:{type:Object},restoreFocusOnClose:{type:Boolean,value:false},alwaysOnTop:{type:Boolean},_manager:{type:Object,value:Polymer.IronOverlayManager},_focusedChild:{type:Object}},listeners:{"iron-resize":"_onIronResize"},get backdropElement(){return this._manager.backdropElement},get _focusNode(){return this._focusedChild||Polymer.dom(this).querySelector("[autofocus]")||this},get _focusableNodes(){var FOCUSABLE_WITH_DISABLED=["a[href]","area[href]","iframe","[tabindex]","[contentEditable=true]"];var FOCUSABLE_WITHOUT_DISABLED=["input","select","textarea","button"];var selector=FOCUSABLE_WITH_DISABLED.join(':not([tabindex="-1"]),')+':not([tabindex="-1"]),'+FOCUSABLE_WITHOUT_DISABLED.join(':not([disabled]):not([tabindex="-1"]),')+':not([disabled]):not([tabindex="-1"])';var focusables=Polymer.dom(this).querySelectorAll(selector);if(this.tabIndex>=0){focusables.splice(0,0,this)}return focusables.sort(function(a,b){if(a.tabIndex===b.tabIndex){return 0}if(a.tabIndex===0||a.tabIndex>b.tabIndex){return 1}return-1})},ready:function(){this.__isAnimating=false;this.__shouldRemoveTabIndex=false;this.__firstFocusableNode=this.__lastFocusableNode=null;this.__raf=null;this.__restoreFocusNode=null;this._ensureSetup()},attached:function(){if(this.opened){this._openedChanged(this.opened)}this._observer=Polymer.dom(this).observeNodes(this._onNodesChange)},detached:function(){Polymer.dom(this).unobserveNodes(this._observer);this._observer=null;if(this.__raf){window.cancelAnimationFrame(this.__raf);this.__raf=null}this._manager.removeOverlay(this)},toggle:function(){this._setCanceled(false);this.opened=!this.opened},open:function(){this._setCanceled(false);this.opened=true},close:function(){this._setCanceled(false);this.opened=false},cancel:function(event){var cancelEvent=this.fire("iron-overlay-canceled",event,{cancelable:true});if(cancelEvent.defaultPrevented){return}this._setCanceled(true);this.opened=false},_ensureSetup:function(){if(this._overlaySetup){return}this._overlaySetup=true;this.style.outline="none";this.style.display="none"},_openedChanged:function(opened){if(opened){this.removeAttribute("aria-hidden")}else{this.setAttribute("aria-hidden","true")}if(!this.isAttached){return}this.__isAnimating=true;this.__onNextAnimationFrame(this.__openedChanged)},_canceledChanged:function(){this.closingReason=this.closingReason||{};this.closingReason.canceled=this.canceled},_withBackdropChanged:function(){if(this.withBackdrop&&!this.hasAttribute("tabindex")){this.setAttribute("tabindex","-1");this.__shouldRemoveTabIndex=true}else if(this.__shouldRemoveTabIndex){this.removeAttribute("tabindex");this.__shouldRemoveTabIndex=false}if(this.opened&&this.isAttached){this._manager.trackBackdrop()}},_prepareRenderOpened:function(){this.__restoreFocusNode=this._manager.deepActiveElement;this._preparePositioning();this.refit();this._finishPositioning();if(this.noAutoFocus&&document.activeElement===this._focusNode){this._focusNode.blur();this.__restoreFocusNode.focus()}},_renderOpened:function(){this._finishRenderOpened()},_renderClosed:function(){this._finishRenderClosed()},_finishRenderOpened:function(){this.notifyResize();this.__isAnimating=false;var focusableNodes=this._focusableNodes;this.__firstFocusableNode=focusableNodes[0];this.__lastFocusableNode=focusableNodes[focusableNodes.length-1];this.fire("iron-overlay-opened")},_finishRenderClosed:function(){this.style.display="none";this.style.zIndex="";this.notifyResize();this.__isAnimating=false;this.fire("iron-overlay-closed",this.closingReason)},_preparePositioning:function(){this.style.transition=this.style.webkitTransition="none";this.style.transform=this.style.webkitTransform="none";this.style.display=""},_finishPositioning:function(){this.style.display="none";this.scrollTop=this.scrollTop;this.style.transition=this.style.webkitTransition="";this.style.transform=this.style.webkitTransform="";this.style.display="";this.scrollTop=this.scrollTop},_applyFocus:function(){if(this.opened){if(!this.noAutoFocus){this._focusNode.focus()}}else{this._focusNode.blur();this._focusedChild=null;if(this.restoreFocusOnClose&&this.__restoreFocusNode){this.__restoreFocusNode.focus()}this.__restoreFocusNode=null;var currentOverlay=this._manager.currentOverlay();if(currentOverlay&&this!==currentOverlay){currentOverlay._applyFocus()}}},_onCaptureClick:function(event){if(!this.noCancelOnOutsideClick){this.cancel(event)}},_onCaptureFocus:function(event){if(!this.withBackdrop){return}var path=Polymer.dom(event).path;if(path.indexOf(this)===-1){event.stopPropagation();this._applyFocus()}else{this._focusedChild=path[0]}},_onCaptureEsc:function(event){if(!this.noCancelOnEscKey){this.cancel(event)}},_onCaptureTab:function(event){if(!this.withBackdrop){return}var shift=event.shiftKey;var nodeToCheck=shift?this.__firstFocusableNode:this.__lastFocusableNode;var nodeToSet=shift?this.__lastFocusableNode:this.__firstFocusableNode;var shouldWrap=false;if(nodeToCheck===nodeToSet){shouldWrap=true}else{var focusedNode=this._manager.deepActiveElement;shouldWrap=focusedNode===nodeToCheck||focusedNode===this}if(shouldWrap){event.preventDefault();this._focusedChild=nodeToSet;this._applyFocus()}},_onIronResize:function(){if(this.opened&&!this.__isAnimating){this.__onNextAnimationFrame(this.refit)}},_onNodesChange:function(){if(this.opened&&!this.__isAnimating){this.notifyResize()}},__openedChanged:function(){if(this.opened){this._prepareRenderOpened();this._manager.addOverlay(this);this._applyFocus();this._renderOpened()}else{this._manager.removeOverlay(this);this._applyFocus();this._renderClosed()}},__onNextAnimationFrame:function(callback){if(this.__raf){window.cancelAnimationFrame(this.__raf)}var self=this;this.__raf=window.requestAnimationFrame(function nextAnimationFrame(){self.__raf=null;callback.call(self)})}};Polymer.IronOverlayBehavior=[Polymer.IronFitBehavior,Polymer.IronResizableBehavior,Polymer.IronOverlayBehaviorImpl]})();Polymer.NeonAnimatableBehavior={properties:{animationConfig:{type:Object},entryAnimation:{observer:"_entryAnimationChanged",type:String},exitAnimation:{observer:"_exitAnimationChanged",type:String}},_entryAnimationChanged:function(){this.animationConfig=this.animationConfig||{};this.animationConfig["entry"]=[{name:this.entryAnimation,node:this}]},_exitAnimationChanged:function(){this.animationConfig=this.animationConfig||{};this.animationConfig["exit"]=[{name:this.exitAnimation,node:this}]},_copyProperties:function(config1,config2){for(var property in config2){config1[property]=config2[property]}},_cloneConfig:function(config){var clone={isClone:true};this._copyProperties(clone,config);return clone},_getAnimationConfigRecursive:function(type,map,allConfigs){if(!this.animationConfig){return}if(this.animationConfig.value&&typeof this.animationConfig.value==="function"){this._warn(this._logf("playAnimation","Please put 'animationConfig' inside of your components 'properties' object instead of outside of it."));return}var thisConfig;if(type){thisConfig=this.animationConfig[type]}else{thisConfig=this.animationConfig}if(!Array.isArray(thisConfig)){thisConfig=[thisConfig]}if(thisConfig){for(var config,index=0;config=thisConfig[index];index++){if(config.animatable){config.animatable._getAnimationConfigRecursive(config.type||type,map,allConfigs)}else{if(config.id){var cachedConfig=map[config.id];if(cachedConfig){if(!cachedConfig.isClone){map[config.id]=this._cloneConfig(cachedConfig);cachedConfig=map[config.id]}this._copyProperties(cachedConfig,config)}else{map[config.id]=config}}else{allConfigs.push(config)}}}}},getAnimationConfig:function(type){var map={};var allConfigs=[];this._getAnimationConfigRecursive(type,map,allConfigs);for(var key in map){allConfigs.push(map[key])}return allConfigs}};Polymer.NeonAnimationRunnerBehaviorImpl={_configureAnimations:function(configs){var results=[];if(configs.length>0){for(var config,index=0;config=configs[index];index++){var neonAnimation=document.createElement(config.name);if(neonAnimation.isNeonAnimation){var result=null;try{result=neonAnimation.configure(config);if(typeof result.cancel!="function"){result=document.timeline.play(result)}}catch(e){result=null;console.warn("Couldnt play","(",config.name,").",e)}if(result){results.push({neonAnimation:neonAnimation,config:config,animation:result})}}else{console.warn(this.is+":",config.name,"not found!")}}}return results},_shouldComplete:function(activeEntries){var finished=true;for(var i=0;i<activeEntries.length;i++){if(activeEntries[i].animation.playState!="finished"){finished=false;break}}return finished},_complete:function(activeEntries){for(var i=0;i<activeEntries.length;i++){activeEntries[i].neonAnimation.complete(activeEntries[i].config)}for(var i=0;i<activeEntries.length;i++){activeEntries[i].animation.cancel()}},playAnimation:function(type,cookie){var configs=this.getAnimationConfig(type);if(!configs){return}this._active=this._active||{};if(this._active[type]){this._complete(this._active[type]);delete this._active[type]}var activeEntries=this._configureAnimations(configs);if(activeEntries.length==0){this.fire("neon-animation-finish",cookie,{bubbles:false});return}this._active[type]=activeEntries;for(var i=0;i<activeEntries.length;i++){activeEntries[i].animation.onfinish=function(){if(this._shouldComplete(activeEntries)){this._complete(activeEntries);delete this._active[type];this.fire("neon-animation-finish",cookie,{bubbles:false})}}.bind(this)}},cancelAnimation:function(){for(var k in this._animations){this._animations[k].cancel()}this._animations={}}};Polymer.NeonAnimationRunnerBehavior=[Polymer.NeonAnimatableBehavior,Polymer.NeonAnimationRunnerBehaviorImpl];Polymer.NeonAnimationBehavior={properties:{animationTiming:{type:Object,value:function(){return{duration:500,easing:"cubic-bezier(0.4, 0, 0.2, 1)",fill:"both"}}}},isNeonAnimation:true,timingFromConfig:function(config){if(config.timing){for(var property in config.timing){this.animationTiming[property]=config.timing[property]}}return this.animationTiming},setPrefixedProperty:function(node,property,value){var map={transform:["webkitTransform"],transformOrigin:["mozTransformOrigin","webkitTransformOrigin"]};var prefixes=map[property];for(var prefix,index=0;prefix=prefixes[index];index++){node.style[prefix]=value}node.style[property]=value},complete:function(){}};Polymer({is:"opaque-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;this._effect=new KeyframeEffect(node,[{opacity:"1"},{opacity:"1"}],this.timingFromConfig(config));node.style.opacity="0";return this._effect},complete:function(config){config.node.style.opacity=""}});(function(){"use strict";var LAST_TOUCH_POSITION={pageX:0,pageY:0};var ROOT_TARGET=null;var SCROLLABLE_NODES=[];Polymer.IronDropdownScrollManager={get currentLockingElement(){return this._lockingElements[this._lockingElements.length-1]},elementIsScrollLocked:function(element){var currentLockingElement=this.currentLockingElement;if(currentLockingElement===undefined)return false;var scrollLocked;if(this._hasCachedLockedElement(element)){return true}if(this._hasCachedUnlockedElement(element)){return false}scrollLocked=!!currentLockingElement&¤tLockingElement!==element&&!this._composedTreeContains(currentLockingElement,element);if(scrollLocked){this._lockedElementCache.push(element)}else{this._unlockedElementCache.push(element)}return scrollLocked},pushScrollLock:function(element){if(this._lockingElements.indexOf(element)>=0){return}if(this._lockingElements.length===0){this._lockScrollInteractions()}this._lockingElements.push(element);this._lockedElementCache=[];this._unlockedElementCache=[]},removeScrollLock:function(element){var index=this._lockingElements.indexOf(element);if(index===-1){return}this._lockingElements.splice(index,1);this._lockedElementCache=[];this._unlockedElementCache=[];if(this._lockingElements.length===0){this._unlockScrollInteractions()}},_lockingElements:[],_lockedElementCache:null,_unlockedElementCache:null,_hasCachedLockedElement:function(element){return this._lockedElementCache.indexOf(element)>-1},_hasCachedUnlockedElement:function(element){return this._unlockedElementCache.indexOf(element)>-1},_composedTreeContains:function(element,child){var contentElements;var distributedNodes;var contentIndex;var nodeIndex;if(element.contains(child)){return true}contentElements=Polymer.dom(element).querySelectorAll("content");for(contentIndex=0;contentIndex<contentElements.length;++contentIndex){distributedNodes=Polymer.dom(contentElements[contentIndex]).getDistributedNodes();for(nodeIndex=0;nodeIndex<distributedNodes.length;++nodeIndex){if(this._composedTreeContains(distributedNodes[nodeIndex],child)){return true}}}return false},_scrollInteractionHandler:function(event){if(event.cancelable&&this._shouldPreventScrolling(event)){event.preventDefault()}if(event.targetTouches){var touch=event.targetTouches[0];LAST_TOUCH_POSITION.pageX=touch.pageX;LAST_TOUCH_POSITION.pageY=touch.pageY}},_lockScrollInteractions:function(){this._boundScrollHandler=this._boundScrollHandler||this._scrollInteractionHandler.bind(this);document.addEventListener("wheel",this._boundScrollHandler,true);document.addEventListener("mousewheel",this._boundScrollHandler,true);document.addEventListener("DOMMouseScroll",this._boundScrollHandler,true);document.addEventListener("touchstart",this._boundScrollHandler,true);document.addEventListener("touchmove",this._boundScrollHandler,true)},_unlockScrollInteractions:function(){document.removeEventListener("wheel",this._boundScrollHandler,true);document.removeEventListener("mousewheel",this._boundScrollHandler,true);document.removeEventListener("DOMMouseScroll",this._boundScrollHandler,true);document.removeEventListener("touchstart",this._boundScrollHandler,true);document.removeEventListener("touchmove",this._boundScrollHandler,true)},_shouldPreventScrolling:function(event){var target=Polymer.dom(event).rootTarget;if(event.type!=="touchmove"&&ROOT_TARGET!==target){ROOT_TARGET=target;SCROLLABLE_NODES=this._getScrollableNodes(Polymer.dom(event).path)}if(!SCROLLABLE_NODES.length){return true}if(event.type==="touchstart"){ -return false}var info=this._getScrollInfo(event);return!this._getScrollingNode(SCROLLABLE_NODES,info.deltaX,info.deltaY)},_getScrollableNodes:function(nodes){var scrollables=[];var lockingIndex=nodes.indexOf(this.currentLockingElement);for(var i=0;i<=lockingIndex;i++){var node=nodes[i];if(node.nodeType===11){continue}var style=node.style;if(style.overflow!=="scroll"&&style.overflow!=="auto"){style=window.getComputedStyle(node)}if(style.overflow==="scroll"||style.overflow==="auto"){scrollables.push(node)}}return scrollables},_getScrollingNode:function(nodes,deltaX,deltaY){if(!deltaX&&!deltaY){return}var verticalScroll=Math.abs(deltaY)>=Math.abs(deltaX);for(var i=0;i<nodes.length;i++){var node=nodes[i];var canScroll=false;if(verticalScroll){canScroll=deltaY<0?node.scrollTop>0:node.scrollTop<node.scrollHeight-node.clientHeight}else{canScroll=deltaX<0?node.scrollLeft>0:node.scrollLeft<node.scrollWidth-node.clientWidth}if(canScroll){return node}}},_getScrollInfo:function(event){var info={deltaX:event.deltaX,deltaY:event.deltaY};if("deltaX"in event){}else if("wheelDeltaX"in event){info.deltaX=-event.wheelDeltaX;info.deltaY=-event.wheelDeltaY}else if("axis"in event){info.deltaX=event.axis===1?event.detail:0;info.deltaY=event.axis===2?event.detail:0}else if(event.targetTouches){var touch=event.targetTouches[0];info.deltaX=LAST_TOUCH_POSITION.pageX-touch.pageX;info.deltaY=LAST_TOUCH_POSITION.pageY-touch.pageY}return info}}})();(function(){"use strict";Polymer({is:"iron-dropdown",behaviors:[Polymer.IronControlState,Polymer.IronA11yKeysBehavior,Polymer.IronOverlayBehavior,Polymer.NeonAnimationRunnerBehavior],properties:{horizontalAlign:{type:String,value:"left",reflectToAttribute:true},verticalAlign:{type:String,value:"top",reflectToAttribute:true},openAnimationConfig:{type:Object},closeAnimationConfig:{type:Object},focusTarget:{type:Object},noAnimations:{type:Boolean,value:false},allowOutsideScroll:{type:Boolean,value:false},_boundOnCaptureScroll:{type:Function,value:function(){return this._onCaptureScroll.bind(this)}}},listeners:{"neon-animation-finish":"_onNeonAnimationFinish"},observers:["_updateOverlayPosition(positionTarget, verticalAlign, horizontalAlign, verticalOffset, horizontalOffset)"],get containedElement(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},get _focusTarget(){return this.focusTarget||this.containedElement},ready:function(){this._scrollTop=0;this._scrollLeft=0;this._refitOnScrollRAF=null},attached:function(){if(!this.sizingTarget||this.sizingTarget===this){this.sizingTarget=this.containedElement}},detached:function(){this.cancelAnimation();document.removeEventListener("scroll",this._boundOnCaptureScroll);Polymer.IronDropdownScrollManager.removeScrollLock(this)},_openedChanged:function(){if(this.opened&&this.disabled){this.cancel()}else{this.cancelAnimation();this._updateAnimationConfig();this._saveScrollPosition();if(this.opened){document.addEventListener("scroll",this._boundOnCaptureScroll);!this.allowOutsideScroll&&Polymer.IronDropdownScrollManager.pushScrollLock(this)}else{document.removeEventListener("scroll",this._boundOnCaptureScroll);Polymer.IronDropdownScrollManager.removeScrollLock(this)}Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this,arguments)}},_renderOpened:function(){if(!this.noAnimations&&this.animationConfig.open){this.$.contentWrapper.classList.add("animating");this.playAnimation("open")}else{Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this,arguments)}},_renderClosed:function(){if(!this.noAnimations&&this.animationConfig.close){this.$.contentWrapper.classList.add("animating");this.playAnimation("close")}else{Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this,arguments)}},_onNeonAnimationFinish:function(){this.$.contentWrapper.classList.remove("animating");if(this.opened){this._finishRenderOpened()}else{this._finishRenderClosed()}},_onCaptureScroll:function(){if(!this.allowOutsideScroll){this._restoreScrollPosition()}else{this._refitOnScrollRAF&&window.cancelAnimationFrame(this._refitOnScrollRAF);this._refitOnScrollRAF=window.requestAnimationFrame(this.refit.bind(this))}},_saveScrollPosition:function(){if(document.scrollingElement){this._scrollTop=document.scrollingElement.scrollTop;this._scrollLeft=document.scrollingElement.scrollLeft}else{this._scrollTop=Math.max(document.documentElement.scrollTop,document.body.scrollTop);this._scrollLeft=Math.max(document.documentElement.scrollLeft,document.body.scrollLeft)}},_restoreScrollPosition:function(){if(document.scrollingElement){document.scrollingElement.scrollTop=this._scrollTop;document.scrollingElement.scrollLeft=this._scrollLeft}else{document.documentElement.scrollTop=this._scrollTop;document.documentElement.scrollLeft=this._scrollLeft;document.body.scrollTop=this._scrollTop;document.body.scrollLeft=this._scrollLeft}},_updateAnimationConfig:function(){var animations=(this.openAnimationConfig||[]).concat(this.closeAnimationConfig||[]);for(var i=0;i<animations.length;i++){animations[i].node=this.containedElement}this.animationConfig={open:this.openAnimationConfig,close:this.closeAnimationConfig}},_updateOverlayPosition:function(){if(this.isAttached){this.notifyResize()}},_applyFocus:function(){var focusTarget=this.focusTarget||this.containedElement;if(focusTarget&&this.opened&&!this.noAutoFocus){focusTarget.focus()}else{Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this,arguments)}}})})();Polymer({is:"fade-in-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;this._effect=new KeyframeEffect(node,[{opacity:"0"},{opacity:"1"}],this.timingFromConfig(config));return this._effect}});Polymer({is:"fade-out-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;this._effect=new KeyframeEffect(node,[{opacity:"1"},{opacity:"0"}],this.timingFromConfig(config));return this._effect}});Polymer.IronMenuBehaviorImpl={properties:{focusedItem:{observer:"_focusedItemChanged",readOnly:true,type:Object},attrForItemTitle:{type:String}},hostAttributes:{role:"menu",tabindex:"0"},observers:["_updateMultiselectable(multi)"],listeners:{focus:"_onFocus",keydown:"_onKeydown","iron-items-changed":"_onIronItemsChanged"},keyBindings:{up:"_onUpKey",down:"_onDownKey",esc:"_onEscKey","shift+tab:keydown":"_onShiftTabDown"},attached:function(){this._resetTabindices()},select:function(value){if(this._defaultFocusAsync){this.cancelAsync(this._defaultFocusAsync);this._defaultFocusAsync=null}var item=this._valueToItem(value);if(item&&item.hasAttribute("disabled"))return;this._setFocusedItem(item);Polymer.IronMultiSelectableBehaviorImpl.select.apply(this,arguments)},_resetTabindices:function(){var selectedItem=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this.items.forEach(function(item){item.setAttribute("tabindex",item===selectedItem?"0":"-1")},this)},_updateMultiselectable:function(multi){if(multi){this.setAttribute("aria-multiselectable","true")}else{this.removeAttribute("aria-multiselectable")}},_focusWithKeyboardEvent:function(event){for(var i=0,item;item=this.items[i];i++){var attr=this.attrForItemTitle||"textContent";var title=item[attr]||item.getAttribute(attr);if(!item.hasAttribute("disabled")&&title&&title.trim().charAt(0).toLowerCase()===String.fromCharCode(event.keyCode).toLowerCase()){this._setFocusedItem(item);break}}},_focusPrevious:function(){var length=this.items.length;var curFocusIndex=Number(this.indexOf(this.focusedItem));for(var i=1;i<length+1;i++){var item=this.items[(curFocusIndex-i+length)%length];if(!item.hasAttribute("disabled")){var owner=Polymer.dom(item).getOwnerRoot()||document;this._setFocusedItem(item);if(Polymer.dom(owner).activeElement==item){return}}}},_focusNext:function(){var length=this.items.length;var curFocusIndex=Number(this.indexOf(this.focusedItem));for(var i=1;i<length+1;i++){var item=this.items[(curFocusIndex+i)%length];if(!item.hasAttribute("disabled")){var owner=Polymer.dom(item).getOwnerRoot()||document;this._setFocusedItem(item);if(Polymer.dom(owner).activeElement==item){return}}}},_applySelection:function(item,isSelected){if(isSelected){item.setAttribute("aria-selected","true")}else{item.removeAttribute("aria-selected")}Polymer.IronSelectableBehavior._applySelection.apply(this,arguments)},_focusedItemChanged:function(focusedItem,old){old&&old.setAttribute("tabindex","-1");if(focusedItem){focusedItem.setAttribute("tabindex","0");focusedItem.focus()}},_onIronItemsChanged:function(event){if(event.detail.addedNodes.length){this._resetTabindices()}},_onShiftTabDown:function(event){var oldTabIndex=this.getAttribute("tabindex");Polymer.IronMenuBehaviorImpl._shiftTabPressed=true;this._setFocusedItem(null);this.setAttribute("tabindex","-1");this.async(function(){this.setAttribute("tabindex",oldTabIndex);Polymer.IronMenuBehaviorImpl._shiftTabPressed=false},1)},_onFocus:function(event){if(Polymer.IronMenuBehaviorImpl._shiftTabPressed){return}var rootTarget=Polymer.dom(event).rootTarget;if(rootTarget!==this&&typeof rootTarget.tabIndex!=="undefined"&&!this.isLightDescendant(rootTarget)){return}this._defaultFocusAsync=this.async(function(){var selectedItem=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this._setFocusedItem(null);if(selectedItem){this._setFocusedItem(selectedItem)}else if(this.items[0]){this._focusNext()}})},_onUpKey:function(event){this._focusPrevious();event.detail.keyboardEvent.preventDefault()},_onDownKey:function(event){this._focusNext();event.detail.keyboardEvent.preventDefault()},_onEscKey:function(event){this.focusedItem.blur()},_onKeydown:function(event){if(!this.keyboardEventMatchesKeys(event,"up down esc")){this._focusWithKeyboardEvent(event)}event.stopPropagation()},_activateHandler:function(event){Polymer.IronSelectableBehavior._activateHandler.call(this,event);event.stopPropagation()}};Polymer.IronMenuBehaviorImpl._shiftTabPressed=false;Polymer.IronMenuBehavior=[Polymer.IronMultiSelectableBehavior,Polymer.IronA11yKeysBehavior,Polymer.IronMenuBehaviorImpl];(function(){Polymer({is:"paper-listbox",behaviors:[Polymer.IronMenuBehavior],hostAttributes:{role:"listbox"}})})();Polymer({is:"paper-menu-grow-height-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;var rect=node.getBoundingClientRect();var height=rect.height;this._effect=new KeyframeEffect(node,[{height:height/2+"px"},{height:height+"px"}],this.timingFromConfig(config));return this._effect}});Polymer({is:"paper-menu-grow-width-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;var rect=node.getBoundingClientRect();var width=rect.width;this._effect=new KeyframeEffect(node,[{width:width/2+"px"},{width:width+"px"}],this.timingFromConfig(config));return this._effect}});Polymer({is:"paper-menu-shrink-width-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;var rect=node.getBoundingClientRect();var width=rect.width;this._effect=new KeyframeEffect(node,[{width:width+"px"},{width:width-width/20+"px"}],this.timingFromConfig(config));return this._effect}});Polymer({is:"paper-menu-shrink-height-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;var rect=node.getBoundingClientRect();var height=rect.height;var top=rect.top;this.setPrefixedProperty(node,"transformOrigin","0 0");this._effect=new KeyframeEffect(node,[{height:height+"px",transform:"translateY(0)"},{height:height/2+"px",transform:"translateY(-20px)"}],this.timingFromConfig(config));return this._effect}}); +cr.define("cr.ui",function(){function FocusGrid(){this.rows=[]}FocusGrid.prototype={ignoreFocusChange_:false,onFocus:function(row,e){if(this.ignoreFocusChange_)this.ignoreFocusChange_=false;else this.lastFocused_=e.currentTarget;this.rows.forEach(function(r){r.makeActive(r==row)})},onKeydown:function(row,e){var rowIndex=this.rows.indexOf(row);assert(rowIndex>=0);var newRow=-1;if(e.key=="ArrowUp")newRow=rowIndex-1;else if(e.key=="ArrowDown")newRow=rowIndex+1;else if(e.key=="PageUp")newRow=0;else if(e.key=="PageDown")newRow=this.rows.length-1;var rowToFocus=this.rows[newRow];if(rowToFocus){this.ignoreFocusChange_=true;rowToFocus.getEquivalentElement(this.lastFocused_).focus();e.preventDefault();return true}return false},destroy:function(){this.rows.forEach(function(row){row.destroy()});this.rows.length=0},getRowIndexForTarget:function(target){for(var i=0;i<this.rows.length;++i){if(this.rows[i].getElements().indexOf(target)>=0)return i}return-1},getRowForRoot:function(root){for(var i=0;i<this.rows.length;++i){if(this.rows[i].root==root)return this.rows[i]}return null},addRow:function(row){this.addRowBefore(row,null)},addRowBefore:function(row,nextRow){row.delegate=row.delegate||this;var nextRowIndex=nextRow?this.rows.indexOf(nextRow):-1;if(nextRowIndex==-1)this.rows.push(row);else this.rows.splice(nextRowIndex,0,row)},removeRow:function(row){var nextRowIndex=row?this.rows.indexOf(row):-1;if(nextRowIndex>-1)this.rows.splice(nextRowIndex,1)},ensureRowActive:function(){if(this.rows.length==0)return;for(var i=0;i<this.rows.length;++i){if(this.rows[i].isActive())return}this.rows[0].makeActive(true)}};return{FocusGrid:FocusGrid}});Polymer.PaperButtonBehaviorImpl={properties:{elevation:{type:Number,reflectToAttribute:true,readOnly:true}},observers:["_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)","_computeKeyboardClass(receivedFocusFromKeyboard)"],hostAttributes:{role:"button",tabindex:"0",animated:true},_calculateElevation:function(){var e=1;if(this.disabled){e=0}else if(this.active||this.pressed){e=4}else if(this.receivedFocusFromKeyboard){e=3}this._setElevation(e)},_computeKeyboardClass:function(receivedFocusFromKeyboard){this.toggleClass("keyboard-focus",receivedFocusFromKeyboard)},_spaceKeyDownHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this,event);if(this.hasRipple()&&this.getRipple().ripples.length<1){this._ripple.uiDownAction()}},_spaceKeyUpHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this,event);if(this.hasRipple()){this._ripple.uiUpAction()}}};Polymer.PaperButtonBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperButtonBehaviorImpl];Polymer({is:"paper-button",behaviors:[Polymer.PaperButtonBehavior],properties:{raised:{type:Boolean,reflectToAttribute:true,value:false,observer:"_calculateElevation"}},_calculateElevation:function(){if(!this.raised){this._setElevation(0)}else{Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this)}}});Polymer.PaperItemBehaviorImpl={hostAttributes:{role:"option",tabindex:"0"}};Polymer.PaperItemBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperItemBehaviorImpl];Polymer({is:"paper-item",behaviors:[Polymer.PaperItemBehavior]}); // Copyright 2016 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. -var SLIDE_CUBIC_BEZIER="cubic-bezier(0.3, 0.95, 0.5, 1)";Polymer({is:"cr-shared-menu",properties:{menuOpen:{type:Boolean,observer:"menuOpenChanged_",value:false,notify:true},itemData:{type:Object,value:null},openAnimationConfig:{type:Object,value:function(){return[{name:"fade-in-animation",timing:{delay:50,duration:200}},{name:"paper-menu-grow-width-animation",timing:{delay:50,duration:150,easing:SLIDE_CUBIC_BEZIER}},{name:"paper-menu-grow-height-animation",timing:{delay:100,duration:275,easing:SLIDE_CUBIC_BEZIER}}]}},closeAnimationConfig:{type:Object,value:function(){return[{name:"fade-out-animation",timing:{duration:150}}]}}},listeners:{"dropdown.iron-overlay-canceled":"onOverlayCanceled_"},lastAnchor_:null,keyHandler_:null,attached:function(){window.addEventListener("resize",this.closeMenu.bind(this));this.keyHandler_=this.onCaptureKeyDown_.bind(this);this.$.menu.addEventListener("keydown",this.keyHandler_,true)},detached:function(){this.$.menu.removeEventListener("keydown",this.keyHandler_,true)},closeMenu:function(){if(this.root.activeElement==null){this.$.dropdown.restoreFocusOnClose=false}this.menuOpen=false},openMenu:function(anchor,opt_itemData){if(this.lastAnchor_==anchor&&this.menuOpen)return;if(this.menuOpen)this.closeMenu();this.itemData=opt_itemData||null;this.lastAnchor_=anchor;this.$.dropdown.restoreFocusOnClose=true;this.$.menu.selected=-1;this.$.dropdown.positionTarget=anchor;this.menuOpen=true},toggleMenu:function(anchor,opt_itemData){if(anchor==this.lastAnchor_&&this.menuOpen)this.closeMenu();else this.openMenu(anchor,opt_itemData)},onCaptureKeyDown_:function(e){if(Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(e,"tab")){this.$.dropdown.restoreFocusOnClose=false;this.lastAnchor_.focus();this.closeMenu()}},menuOpenChanged_:function(){if(!this.menuOpen){this.itemData=null;this.lastAnchor_=null}},onOverlayCanceled_:function(e){if(e.detail.type=="tap")this.$.dropdown.restoreFocusOnClose=false}});Polymer({is:"paper-icon-button-light","extends":"button",behaviors:[Polymer.PaperRippleBehavior],listeners:{down:"_rippleDown",up:"_rippleUp",focus:"_rippleDown",blur:"_rippleUp"},_rippleDown:function(){this.getRipple().downAction()},_rippleUp:function(){this.getRipple().upAction()},ensureRipple:function(var_args){var lastRipple=this._ripple;Polymer.PaperRippleBehavior.ensureRipple.apply(this,arguments);if(this._ripple&&this._ripple!==lastRipple){this._ripple.center=true;this._ripple.classList.add("circle")}}}); +Polymer({is:"cr-action-menu","extends":"dialog",options_:null,anchorElement_:null,onWindowResize_:null,hostAttributes:{tabindex:0},listeners:{keydown:"onKeyDown_",tap:"onTap_"},attached:function(){this.options_=this.querySelectorAll(".dropdown-item")},detached:function(){this.removeResizeListener_()},removeResizeListener_:function(){window.removeEventListener("resize",this.onWindowResize_)},onTap_:function(e){if(e.target==this){this.close();e.stopPropagation()}},onKeyDown_:function(e){if(e.key=="Tab"||e.key=="Escape"){this.close();e.preventDefault();return}if(e.key!=="ArrowDown"&&e.key!=="ArrowUp")return;var nextOption=this.getNextOption_(e.key=="ArrowDown"?1:-1);if(nextOption)nextOption.focus();e.preventDefault()},getNextOption_:function(step){var counter=0;var nextOption=null;var numOptions=this.options_.length;var focusedIndex=Array.prototype.indexOf.call(this.options_,this.root.activeElement);do{focusedIndex=(numOptions+focusedIndex+step)%numOptions;nextOption=this.options_[focusedIndex];if(nextOption.disabled||nextOption.hidden)nextOption=null;counter++}while(!nextOption&&counter<numOptions);return nextOption},close:function(){this.removeResizeListener_();HTMLDialogElement.prototype.close.call(this);this.anchorElement_.focus();this.anchorElement_=null},showAt:function(anchorElement){this.anchorElement_=anchorElement;this.onWindowResize_=this.onWindowResize_||function(){if(this.open)this.close()}.bind(this);window.addEventListener("resize",this.onWindowResize_);this.showModal();var rect=this.anchorElement_.getBoundingClientRect();if(getComputedStyle(this.anchorElement_).direction=="rtl"){var right=window.innerWidth-rect.left-this.offsetWidth;this.style.right=right+"px"}else{var left=rect.right-this.offsetWidth;this.style.left=left+"px"}var top=rect.top+this.offsetHeight<=window.innerHeight?rect.top:rect.bottom-this.offsetHeight-Math.max(rect.bottom-window.innerHeight,0);this.style.top=top+"px"}});Polymer({is:"paper-icon-button-light","extends":"button",behaviors:[Polymer.PaperRippleBehavior],listeners:{down:"_rippleDown",up:"_rippleUp",focus:"_rippleDown",blur:"_rippleUp"},_rippleDown:function(){this.getRipple().downAction()},_rippleUp:function(){this.getRipple().upAction()},ensureRipple:function(var_args){var lastRipple=this._ripple;Polymer.PaperRippleBehavior.ensureRipple.apply(this,arguments);if(this._ripple&&this._ripple!==lastRipple){this._ripple.center=true;this._ripple.classList.add("circle")}}}); // Copyright 2016 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. -Polymer({is:"history-synced-device-card",properties:{tabs:{type:Array,value:function(){return[]},observer:"updateIcons_"},device:String,lastUpdateTime:String,opened:Boolean,searchTerm:String,separatorIndexes:Array,sessionTag:String},listeners:{"dom-change":"notifyFocusUpdate_"},createFocusRows:function(){var titleRow=new cr.ui.FocusRow(this.$["card-heading"],null);titleRow.addItem("menu","#menu-button");titleRow.addItem("collapse","#collapse-button");var rows=[titleRow];if(this.opened){Polymer.dom(this.root).querySelectorAll(".item-container").forEach(function(el){var row=new cr.ui.FocusRow(el,null);row.addItem("title",".website-title");rows.push(row)})}return rows},openTab_:function(e){var tab=e.model.tab;var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.LINK_CLICKED,SyncedTabsHistogram.LIMIT);browserService.openForeignSessionTab(this.sessionTag,tab.windowId,tab.sessionId,e);e.preventDefault()},toggleTabCard:function(){var histogramValue=this.$.collapse.opened?SyncedTabsHistogram.COLLAPSE_SESSION:SyncedTabsHistogram.EXPAND_SESSION;md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,histogramValue,SyncedTabsHistogram.LIMIT);this.$.collapse.toggle();this.$["dropdown-indicator"].icon=this.$.collapse.opened?"cr:expand-less":"cr:expand-more";this.fire("update-focus-grid")},notifyFocusUpdate_:function(){this.fire("update-focus-grid")},updateIcons_:function(){this.async(function(){var icons=Polymer.dom(this.root).querySelectorAll(".website-icon");for(var i=0;i<this.tabs.length;i++){icons[i].style.backgroundImage=cr.icon.getFavicon(this.tabs[i].url)}})},isWindowSeparatorIndex_:function(index,separatorIndexes){return this.separatorIndexes.indexOf(index)!=-1},getCollapseIcon_:function(opened){return opened?"cr:expand-less":"cr:expand-more"},getCollapseTitle_:function(opened){return opened?loadTimeData.getString("collapseSessionButton"):loadTimeData.getString("expandSessionButton")},onMenuButtonTap_:function(e){this.fire("toggle-menu",{target:Polymer.dom(e).localTarget,tag:this.sessionTag});e.stopPropagation()},onLinkRightClick_:function(){md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.LINK_RIGHT_CLICKED,SyncedTabsHistogram.LIMIT)}}); +Polymer({is:"history-synced-device-card",properties:{tabs:{type:Array,value:function(){return[]},observer:"updateIcons_"},device:String,lastUpdateTime:String,opened:Boolean,searchTerm:String,separatorIndexes:Array,sessionTag:String},listeners:{"dom-change":"notifyFocusUpdate_"},createFocusRows:function(){var titleRow=new cr.ui.FocusRow(this.$["card-heading"],null);titleRow.addItem("menu","#menu-button");titleRow.addItem("collapse","#collapse-button");var rows=[titleRow];if(this.opened){Polymer.dom(this.root).querySelectorAll(".item-container").forEach(function(el){var row=new cr.ui.FocusRow(el,null);row.addItem("title",".website-title");rows.push(row)})}return rows},openTab_:function(e){var tab=e.model.tab;var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.LINK_CLICKED,SyncedTabsHistogram.LIMIT);browserService.openForeignSessionTab(this.sessionTag,tab.windowId,tab.sessionId,e);e.preventDefault()},toggleTabCard:function(){var histogramValue=this.$.collapse.opened?SyncedTabsHistogram.COLLAPSE_SESSION:SyncedTabsHistogram.EXPAND_SESSION;md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,histogramValue,SyncedTabsHistogram.LIMIT);this.$.collapse.toggle();this.$["dropdown-indicator"].icon=this.$.collapse.opened?"cr:expand-less":"cr:expand-more";this.fire("update-focus-grid")},notifyFocusUpdate_:function(){this.fire("update-focus-grid")},updateIcons_:function(){this.async(function(){var icons=Polymer.dom(this.root).querySelectorAll(".website-icon");for(var i=0;i<this.tabs.length;i++){icons[i].style.backgroundImage=cr.icon.getFavicon(this.tabs[i].url)}})},isWindowSeparatorIndex_:function(index,separatorIndexes){return this.separatorIndexes.indexOf(index)!=-1},getCollapseIcon_:function(opened){return opened?"cr:expand-less":"cr:expand-more"},getCollapseTitle_:function(opened){return opened?loadTimeData.getString("collapseSessionButton"):loadTimeData.getString("expandSessionButton")},onMenuButtonTap_:function(e){this.fire("open-menu",{target:Polymer.dom(e).localTarget,tag:this.sessionTag});e.stopPropagation()},onLinkRightClick_:function(){md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.LINK_RIGHT_CLICKED,SyncedTabsHistogram.LIMIT)}}); // Copyright 2016 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. -var ForeignDeviceInternal;Polymer({is:"history-synced-device-manager",properties:{sessionList:{type:Array,observer:"updateSyncedDevices"},searchTerm:{type:String,observer:"searchTermChanged"},syncedDevices_:{type:Array,value:function(){return[]}},signInState:{type:Boolean,observer:"signInStateChanged_"},guestSession_:{type:Boolean,value:loadTimeData.getBoolean("isGuestSession")},fetchingSyncedTabs_:{type:Boolean,value:false},hasSeenForeignData_:Boolean},listeners:{"toggle-menu":"onToggleMenu_",scroll:"onListScroll_","update-focus-grid":"updateFocusGrid_"},focusGrid_:null,attached:function(){this.focusGrid_=new cr.ui.FocusGrid;chrome.send("otherDevicesInitialized");md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.INITIALIZED,SyncedTabsHistogram.LIMIT)},detached:function(){this.focusGrid_.destroy()},getContentScrollTarget:function(){return this},createInternalDevice_:function(session){var tabs=[];var separatorIndexes=[];for(var i=0;i<session.windows.length;i++){var windowId=session.windows[i].sessionId;var newTabs=session.windows[i].tabs;if(newTabs.length==0)continue;newTabs.forEach(function(tab){tab.windowId=windowId});var windowAdded=false;if(!this.searchTerm){tabs=tabs.concat(newTabs);windowAdded=true}else{var searchText=this.searchTerm.toLowerCase();for(var j=0;j<newTabs.length;j++){var tab=newTabs[j];if(tab.title.toLowerCase().indexOf(searchText)!=-1){tabs.push(tab);windowAdded=true}}}if(windowAdded&&i!=session.windows.length-1)separatorIndexes.push(tabs.length-1)}return{device:session.name,lastUpdateTime:"– "+session.modifiedTime,opened:true,separatorIndexes:separatorIndexes,timestamp:session.timestamp,tabs:tabs,tag:session.tag}},onSignInTap_:function(){chrome.send("startSignInFlow")},onListScroll_:function(){var menu=this.$.menu.getIfExists();if(menu)menu.closeMenu()},onToggleMenu_:function(e){var menu=this.$.menu.get();menu.toggleMenu(e.detail.target,e.detail.tag);if(menu.menuOpen){md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.SHOW_SESSION_MENU,SyncedTabsHistogram.LIMIT)}},onOpenAllTap_:function(){var menu=assert(this.$.menu.getIfExists());var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.OPEN_ALL,SyncedTabsHistogram.LIMIT);browserService.openForeignSessionAllTabs(menu.itemData);menu.closeMenu()},updateFocusGrid_:function(){if(!this.focusGrid_)return;this.focusGrid_.destroy();this.debounce("updateFocusGrid",function(){Polymer.dom(this.root).querySelectorAll("history-synced-device-card").reduce(function(prev,cur){return prev.concat(cur.createFocusRows())},[]).forEach(function(row){this.focusGrid_.addRow(row)}.bind(this));this.focusGrid_.ensureRowActive()})},onDeleteSessionTap_:function(){var menu=assert(this.$.menu.getIfExists());var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.HIDE_FOR_NOW,SyncedTabsHistogram.LIMIT);browserService.deleteForeignSession(menu.itemData);menu.closeMenu()},clearDisplayedSyncedDevices_:function(){this.syncedDevices_=[]},showNoSyncedMessage:function(signInState,syncedDevicesLength,guestSession){if(guestSession)return true;return signInState&&syncedDevicesLength==0},showSignInGuide:function(signInState,guestSession){var show=!signInState&&!guestSession;if(show){md_history.BrowserService.getInstance().recordAction("Signin_Impression_FromRecentTabs")}return show},noSyncedTabsMessage:function(){var stringName=this.fetchingSyncedTabs_?"loading":"noSyncedResults";if(this.searchTerm!=="")stringName="noSearchResults";return loadTimeData.getString(stringName)},updateSyncedDevices:function(sessionList){this.fetchingSyncedTabs_=false;if(!sessionList)return;if(sessionList.length>0&&!this.hasSeenForeignData_){this.hasSeenForeignData_=true;md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.HAS_FOREIGN_DATA,SyncedTabsHistogram.LIMIT)}var devices=[];sessionList.forEach(function(session){var device=this.createInternalDevice_(session);if(device.tabs.length!=0)devices.push(device)}.bind(this));this.syncedDevices_=devices},signInStateChanged_:function(){this.fire("history-view-changed");if(!this.signInState){this.clearDisplayedSyncedDevices_();return}this.fetchingSyncedTabs_=true},searchTermChanged:function(searchTerm){this.clearDisplayedSyncedDevices_();this.updateSyncedDevices(this.sessionList)}}); +var ForeignDeviceInternal;Polymer({is:"history-synced-device-manager",properties:{sessionList:{type:Array,observer:"updateSyncedDevices"},searchTerm:{type:String,observer:"searchTermChanged"},syncedDevices_:{type:Array,value:function(){return[]}},signInState:{type:Boolean,observer:"signInStateChanged_"},guestSession_:{type:Boolean,value:loadTimeData.getBoolean("isGuestSession")},fetchingSyncedTabs_:{type:Boolean,value:false},hasSeenForeignData_:Boolean,actionMenuModel_:String},listeners:{"open-menu":"onOpenMenu_","update-focus-grid":"updateFocusGrid_"},focusGrid_:null,attached:function(){this.focusGrid_=new cr.ui.FocusGrid;chrome.send("otherDevicesInitialized");md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.INITIALIZED,SyncedTabsHistogram.LIMIT)},detached:function(){this.focusGrid_.destroy()},getContentScrollTarget:function(){return this},createInternalDevice_:function(session){var tabs=[];var separatorIndexes=[];for(var i=0;i<session.windows.length;i++){var windowId=session.windows[i].sessionId;var newTabs=session.windows[i].tabs;if(newTabs.length==0)continue;newTabs.forEach(function(tab){tab.windowId=windowId});var windowAdded=false;if(!this.searchTerm){tabs=tabs.concat(newTabs);windowAdded=true}else{var searchText=this.searchTerm.toLowerCase();for(var j=0;j<newTabs.length;j++){var tab=newTabs[j];if(tab.title.toLowerCase().indexOf(searchText)!=-1){tabs.push(tab);windowAdded=true}}}if(windowAdded&&i!=session.windows.length-1)separatorIndexes.push(tabs.length-1)}return{device:session.name,lastUpdateTime:"– "+session.modifiedTime,opened:true,separatorIndexes:separatorIndexes,timestamp:session.timestamp,tabs:tabs,tag:session.tag}},onSignInTap_:function(){chrome.send("startSignInFlow")},onOpenMenu_:function(e){var menu=this.$.menu.get();this.actionMenuModel_=e.detail.tag;menu.showAt(e.detail.target);md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.SHOW_SESSION_MENU,SyncedTabsHistogram.LIMIT)},onOpenAllTap_:function(){var menu=assert(this.$.menu.getIfExists());var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.OPEN_ALL,SyncedTabsHistogram.LIMIT);browserService.openForeignSessionAllTabs(assert(this.actionMenuModel_));this.actionMenuModel_=null;menu.close()},updateFocusGrid_:function(){if(!this.focusGrid_)return;this.focusGrid_.destroy();this.debounce("updateFocusGrid",function(){Polymer.dom(this.root).querySelectorAll("history-synced-device-card").reduce(function(prev,cur){return prev.concat(cur.createFocusRows())},[]).forEach(function(row){this.focusGrid_.addRow(row)}.bind(this));this.focusGrid_.ensureRowActive()})},onDeleteSessionTap_:function(){var menu=assert(this.$.menu.getIfExists());var browserService=md_history.BrowserService.getInstance();browserService.recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.HIDE_FOR_NOW,SyncedTabsHistogram.LIMIT);browserService.deleteForeignSession(assert(this.actionMenuModel_));this.actionMenuModel_=null;menu.close()},clearDisplayedSyncedDevices_:function(){this.syncedDevices_=[]},showNoSyncedMessage:function(signInState,syncedDevicesLength,guestSession){if(guestSession)return true;return signInState&&syncedDevicesLength==0},showSignInGuide:function(signInState,guestSession){var show=!signInState&&!guestSession;if(show){md_history.BrowserService.getInstance().recordAction("Signin_Impression_FromRecentTabs")}return show},noSyncedTabsMessage:function(){var stringName=this.fetchingSyncedTabs_?"loading":"noSyncedResults";if(this.searchTerm!=="")stringName="noSearchResults";return loadTimeData.getString(stringName)},updateSyncedDevices:function(sessionList){this.fetchingSyncedTabs_=false;if(!sessionList)return;if(sessionList.length>0&&!this.hasSeenForeignData_){this.hasSeenForeignData_=true;md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRAM_NAME,SyncedTabsHistogram.HAS_FOREIGN_DATA,SyncedTabsHistogram.LIMIT)}var devices=[];sessionList.forEach(function(session){var device=this.createInternalDevice_(session);if(device.tabs.length!=0)devices.push(device)}.bind(this));this.syncedDevices_=devices},signInStateChanged_:function(){this.fire("history-view-changed");if(!this.signInState){this.clearDisplayedSyncedDevices_();return}this.fetchingSyncedTabs_=true},searchTermChanged:function(searchTerm){this.clearDisplayedSyncedDevices_();this.updateSyncedDevices(this.sessionList)}}); // Copyright 2016 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. -Polymer({is:"cr-dialog","extends":"dialog",properties:{closeText:String,ignorePopstate:{type:Boolean,value:false}},ready:function(){window.addEventListener("popstate",function(){if(!this.ignorePopstate&&this.open)this.cancel()}.bind(this))},cancel:function(){this.fire("cancel");HTMLDialogElement.prototype.close.call(this,"")},close:function(opt_returnValue){HTMLDialogElement.prototype.close.call(this,"success")},getCloseButton:function(){return this.$.close}});Polymer({is:"app-drawer",properties:{opened:{type:Boolean,value:false,notify:true,reflectToAttribute:true},persistent:{type:Boolean,value:false,reflectToAttribute:true},align:{type:String,value:"left"},position:{type:String,readOnly:true,value:"left",reflectToAttribute:true},swipeOpen:{type:Boolean,value:false,reflectToAttribute:true},noFocusTrap:{type:Boolean,value:false}},observers:["resetLayout(position)","_resetPosition(align, isAttached)"],_translateOffset:0,_trackDetails:null,_drawerState:0,_boundEscKeydownHandler:null,_firstTabStop:null,_lastTabStop:null,ready:function(){this.setScrollDirection("y");this._setTransitionDuration("0s")},attached:function(){Polymer.RenderStatus.afterNextRender(this,function(){this._setTransitionDuration("");this._boundEscKeydownHandler=this._escKeydownHandler.bind(this);this._resetDrawerState();this.listen(this,"track","_track");this.addEventListener("transitionend",this._transitionend.bind(this));this.addEventListener("keydown",this._tabKeydownHandler.bind(this))})},detached:function(){document.removeEventListener("keydown",this._boundEscKeydownHandler)},open:function(){this.opened=true},close:function(){this.opened=false},toggle:function(){this.opened=!this.opened},getWidth:function(){return this.$.contentContainer.offsetWidth},resetLayout:function(){this.debounce("_resetLayout",function(){this.fire("app-drawer-reset-layout")},1)},_isRTL:function(){return window.getComputedStyle(this).direction==="rtl"},_resetPosition:function(){switch(this.align){case"start":this._setPosition(this._isRTL()?"right":"left");return;case"end":this._setPosition(this._isRTL()?"left":"right");return}this._setPosition(this.align)},_escKeydownHandler:function(event){var ESC_KEYCODE=27;if(event.keyCode===ESC_KEYCODE){event.preventDefault();this.close()}},_track:function(event){if(this.persistent){return}event.preventDefault();switch(event.detail.state){case"start":this._trackStart(event);break;case"track":this._trackMove(event);break;case"end":this._trackEnd(event);break}},_trackStart:function(event){this._drawerState=this._DRAWER_STATE.TRACKING;this._setTransitionDuration("0s");this.style.visibility="visible";var rect=this.$.contentContainer.getBoundingClientRect();if(this.position==="left"){this._translateOffset=rect.left}else{this._translateOffset=rect.right-window.innerWidth}this._trackDetails=[]},_trackMove:function(event){this._translateDrawer(event.detail.dx+this._translateOffset);this._trackDetails.push({dx:event.detail.dx,timeStamp:Date.now()})},_trackEnd:function(event){var x=event.detail.dx+this._translateOffset;var drawerWidth=this.getWidth();var isPositionLeft=this.position==="left";var isInEndState=isPositionLeft?x>=0||x<=-drawerWidth:x<=0||x>=drawerWidth;if(!isInEndState){var trackDetails=this._trackDetails;this._trackDetails=null;this._flingDrawer(event,trackDetails);if(this._drawerState===this._DRAWER_STATE.FLINGING){return}}var halfWidth=drawerWidth/2;if(event.detail.dx<-halfWidth){this.opened=this.position==="right"}else if(event.detail.dx>halfWidth){this.opened=this.position==="left"}if(isInEndState){this._resetDrawerState()}this._setTransitionDuration("");this._resetDrawerTranslate();this.style.visibility=""},_calculateVelocity:function(event,trackDetails){var now=Date.now();var timeLowerBound=now-100;var trackDetail;var min=0;var max=trackDetails.length-1;while(min<=max){var mid=min+max>>1;var d=trackDetails[mid];if(d.timeStamp>=timeLowerBound){trackDetail=d;max=mid-1}else{min=mid+1}}if(trackDetail){var dx=event.detail.dx-trackDetail.dx;var dt=now-trackDetail.timeStamp||1;return dx/dt}return 0},_flingDrawer:function(event,trackDetails){var velocity=this._calculateVelocity(event,trackDetails);if(Math.abs(velocity)<this._MIN_FLING_THRESHOLD){return}this._drawerState=this._DRAWER_STATE.FLINGING;var x=event.detail.dx+this._translateOffset;var drawerWidth=this.getWidth();var isPositionLeft=this.position==="left";var isVelocityPositive=velocity>0;var isClosingLeft=!isVelocityPositive&&isPositionLeft;var isClosingRight=isVelocityPositive&&!isPositionLeft;var dx;if(isClosingLeft){dx=-(x+drawerWidth)}else if(isClosingRight){dx=drawerWidth-x}else{dx=-x}if(isVelocityPositive){velocity=Math.max(velocity,this._MIN_TRANSITION_VELOCITY);this.opened=this.position==="left"}else{velocity=Math.min(velocity,-this._MIN_TRANSITION_VELOCITY);this.opened=this.position==="right"}this._setTransitionDuration(this._FLING_INITIAL_SLOPE*dx/velocity+"ms");this._setTransitionTimingFunction(this._FLING_TIMING_FUNCTION);this._resetDrawerTranslate()},_transitionend:function(event){var target=Polymer.dom(event).rootTarget;if(target===this.$.contentContainer||target===this.$.scrim){if(this._drawerState===this._DRAWER_STATE.FLINGING){this._setTransitionDuration("");this._setTransitionTimingFunction("");this.style.visibility=""}this._resetDrawerState()}},_setTransitionDuration:function(duration){this.$.contentContainer.style.transitionDuration=duration;this.$.scrim.style.transitionDuration=duration},_setTransitionTimingFunction:function(timingFunction){this.$.contentContainer.style.transitionTimingFunction=timingFunction;this.$.scrim.style.transitionTimingFunction=timingFunction},_translateDrawer:function(x){var drawerWidth=this.getWidth();if(this.position==="left"){x=Math.max(-drawerWidth,Math.min(x,0));this.$.scrim.style.opacity=1+x/drawerWidth}else{x=Math.max(0,Math.min(x,drawerWidth));this.$.scrim.style.opacity=1-x/drawerWidth}this.translate3d(x+"px","0","0",this.$.contentContainer)},_resetDrawerTranslate:function(){this.$.scrim.style.opacity="";this.transform("",this.$.contentContainer)},_resetDrawerState:function(){var oldState=this._drawerState;if(this.opened){this._drawerState=this.persistent?this._DRAWER_STATE.OPENED_PERSISTENT:this._DRAWER_STATE.OPENED}else{this._drawerState=this._DRAWER_STATE.CLOSED}if(oldState!==this._drawerState){if(this._drawerState===this._DRAWER_STATE.OPENED){this._setKeyboardFocusTrap();document.addEventListener("keydown",this._boundEscKeydownHandler);document.body.style.overflow="hidden"}else{document.removeEventListener("keydown",this._boundEscKeydownHandler);document.body.style.overflow=""}if(oldState!==this._DRAWER_STATE.INIT){this.fire("app-drawer-transitioned")}}},_setKeyboardFocusTrap:function(){if(this.noFocusTrap){return}var focusableElementsSelector=['a[href]:not([tabindex="-1"])','area[href]:not([tabindex="-1"])','input:not([disabled]):not([tabindex="-1"])','select:not([disabled]):not([tabindex="-1"])','textarea:not([disabled]):not([tabindex="-1"])','button:not([disabled]):not([tabindex="-1"])','iframe:not([tabindex="-1"])','[tabindex]:not([tabindex="-1"])','[contentEditable=true]:not([tabindex="-1"])'].join(",");var focusableElements=Polymer.dom(this).querySelectorAll(focusableElementsSelector);if(focusableElements.length>0){this._firstTabStop=focusableElements[0];this._lastTabStop=focusableElements[focusableElements.length-1]}else{this._firstTabStop=null;this._lastTabStop=null}var tabindex=this.getAttribute("tabindex");if(tabindex&&parseInt(tabindex,10)>-1){this.focus()}else if(this._firstTabStop){this._firstTabStop.focus()}},_tabKeydownHandler:function(event){if(this.noFocusTrap){return}var TAB_KEYCODE=9;if(this._drawerState===this._DRAWER_STATE.OPENED&&event.keyCode===TAB_KEYCODE){if(event.shiftKey){if(this._firstTabStop&&Polymer.dom(event).localTarget===this._firstTabStop){event.preventDefault();this._lastTabStop.focus()}}else{if(this._lastTabStop&&Polymer.dom(event).localTarget===this._lastTabStop){event.preventDefault();this._firstTabStop.focus()}}}},_MIN_FLING_THRESHOLD:.2,_MIN_TRANSITION_VELOCITY:1.2,_FLING_TIMING_FUNCTION:"cubic-bezier(0.667, 1, 0.667, 1)",_FLING_INITIAL_SLOPE:1.5,_DRAWER_STATE:{INIT:0,OPENED:1,OPENED_PERSISTENT:2,CLOSED:3,TRACKING:4,FLINGING:5}});Polymer({is:"paper-tab",behaviors:[Polymer.IronControlState,Polymer.IronButtonState,Polymer.PaperRippleBehavior],properties:{link:{type:Boolean,value:false,reflectToAttribute:true}},hostAttributes:{role:"tab"},listeners:{down:"_updateNoink",tap:"_onTap"},attached:function(){this._updateNoink()},get _parentNoink(){var parent=Polymer.dom(this).parentNode;return!!parent&&!!parent.noink},_updateNoink:function(){this.noink=!!this.noink||!!this._parentNoink},_onTap:function(event){if(this.link){var anchor=this.queryEffectiveChildren("a");if(!anchor){return}if(event.target===anchor){return}anchor.click()}}});Polymer.IronMenubarBehaviorImpl={hostAttributes:{role:"menubar"},keyBindings:{left:"_onLeftKey",right:"_onRightKey"},_onUpKey:function(event){this.focusedItem.click();event.detail.keyboardEvent.preventDefault()},_onDownKey:function(event){this.focusedItem.click();event.detail.keyboardEvent.preventDefault()},get _isRTL(){return window.getComputedStyle(this)["direction"]==="rtl"},_onLeftKey:function(event){if(this._isRTL){this._focusNext()}else{this._focusPrevious()}event.detail.keyboardEvent.preventDefault()},_onRightKey:function(event){if(this._isRTL){this._focusPrevious()}else{this._focusNext()}event.detail.keyboardEvent.preventDefault()},_onKeydown:function(event){if(this.keyboardEventMatchesKeys(event,"up down left right esc")){return}this._focusWithKeyboardEvent(event)}};Polymer.IronMenubarBehavior=[Polymer.IronMenuBehavior,Polymer.IronMenubarBehaviorImpl];Polymer({is:"paper-tabs",behaviors:[Polymer.IronResizableBehavior,Polymer.IronMenubarBehavior],properties:{noink:{type:Boolean,value:false,observer:"_noinkChanged"},noBar:{type:Boolean,value:false},noSlide:{type:Boolean,value:false},scrollable:{type:Boolean,value:false},fitContainer:{type:Boolean,value:false},disableDrag:{type:Boolean,value:false},hideScrollButtons:{type:Boolean,value:false},alignBottom:{type:Boolean,value:false},selectable:{type:String,value:"paper-tab"},autoselect:{type:Boolean,value:false},autoselectDelay:{type:Number,value:0},_step:{type:Number,value:10},_holdDelay:{type:Number,value:1},_leftHidden:{type:Boolean,value:false},_rightHidden:{type:Boolean,value:false},_previousTab:{type:Object}},hostAttributes:{role:"tablist"},listeners:{"iron-resize":"_onTabSizingChanged","iron-items-changed":"_onTabSizingChanged","iron-select":"_onIronSelect","iron-deselect":"_onIronDeselect"},keyBindings:{"left:keyup right:keyup":"_onArrowKeyup"},created:function(){this._holdJob=null;this._pendingActivationItem=undefined;this._pendingActivationTimeout=undefined;this._bindDelayedActivationHandler=this._delayedActivationHandler.bind(this);this.addEventListener("blur",this._onBlurCapture.bind(this),true)},ready:function(){this.setScrollDirection("y",this.$.tabsContainer)},detached:function(){this._cancelPendingActivation()},_noinkChanged:function(noink){var childTabs=Polymer.dom(this).querySelectorAll("paper-tab");childTabs.forEach(noink?this._setNoinkAttribute:this._removeNoinkAttribute)},_setNoinkAttribute:function(element){element.setAttribute("noink","")},_removeNoinkAttribute:function(element){element.removeAttribute("noink")},_computeScrollButtonClass:function(hideThisButton,scrollable,hideScrollButtons){if(!scrollable||hideScrollButtons){return"hidden"}if(hideThisButton){return"not-visible"}return""},_computeTabsContentClass:function(scrollable,fitContainer){return scrollable?"scrollable"+(fitContainer?" fit-container":""):" fit-container"},_computeSelectionBarClass:function(noBar,alignBottom){if(noBar){return"hidden"}else if(alignBottom){return"align-bottom"}return""},_onTabSizingChanged:function(){this.debounce("_onTabSizingChanged",function(){this._scroll();this._tabChanged(this.selectedItem)},10)},_onIronSelect:function(event){this._tabChanged(event.detail.item,this._previousTab);this._previousTab=event.detail.item;this.cancelDebouncer("tab-changed")},_onIronDeselect:function(event){this.debounce("tab-changed",function(){this._tabChanged(null,this._previousTab);this._previousTab=null},1)},_activateHandler:function(){this._cancelPendingActivation();Polymer.IronMenuBehaviorImpl._activateHandler.apply(this,arguments)},_scheduleActivation:function(item,delay){this._pendingActivationItem=item;this._pendingActivationTimeout=this.async(this._bindDelayedActivationHandler,delay)},_delayedActivationHandler:function(){var item=this._pendingActivationItem;this._pendingActivationItem=undefined;this._pendingActivationTimeout=undefined;item.fire(this.activateEvent,null,{bubbles:true,cancelable:true})},_cancelPendingActivation:function(){if(this._pendingActivationTimeout!==undefined){this.cancelAsync(this._pendingActivationTimeout);this._pendingActivationItem=undefined;this._pendingActivationTimeout=undefined}},_onArrowKeyup:function(event){if(this.autoselect){this._scheduleActivation(this.focusedItem,this.autoselectDelay)}},_onBlurCapture:function(event){if(event.target===this._pendingActivationItem){this._cancelPendingActivation()}},get _tabContainerScrollSize(){return Math.max(0,this.$.tabsContainer.scrollWidth-this.$.tabsContainer.offsetWidth)},_scroll:function(e,detail){if(!this.scrollable){return}var ddx=detail&&-detail.ddx||0;this._affectScroll(ddx)},_down:function(e){this.async(function(){if(this._defaultFocusAsync){this.cancelAsync(this._defaultFocusAsync);this._defaultFocusAsync=null}},1)},_affectScroll:function(dx){this.$.tabsContainer.scrollLeft+=dx;var scrollLeft=this.$.tabsContainer.scrollLeft;this._leftHidden=scrollLeft===0;this._rightHidden=scrollLeft===this._tabContainerScrollSize},_onLeftScrollButtonDown:function(){this._scrollToLeft();this._holdJob=setInterval(this._scrollToLeft.bind(this),this._holdDelay)},_onRightScrollButtonDown:function(){this._scrollToRight();this._holdJob=setInterval(this._scrollToRight.bind(this),this._holdDelay)},_onScrollButtonUp:function(){clearInterval(this._holdJob);this._holdJob=null},_scrollToLeft:function(){this._affectScroll(-this._step)},_scrollToRight:function(){this._affectScroll(this._step)},_tabChanged:function(tab,old){if(!tab){this.$.selectionBar.classList.remove("expand");this.$.selectionBar.classList.remove("contract");this._positionBar(0,0);return}var r=this.$.tabsContent.getBoundingClientRect();var w=r.width;var tabRect=tab.getBoundingClientRect();var tabOffsetLeft=tabRect.left-r.left;this._pos={width:this._calcPercent(tabRect.width,w),left:this._calcPercent(tabOffsetLeft,w)};if(this.noSlide||old==null){this.$.selectionBar.classList.remove("expand");this.$.selectionBar.classList.remove("contract");this._positionBar(this._pos.width,this._pos.left);return}var oldRect=old.getBoundingClientRect();var oldIndex=this.items.indexOf(old);var index=this.items.indexOf(tab);var m=5;this.$.selectionBar.classList.add("expand");var moveRight=oldIndex<index;var isRTL=this._isRTL;if(isRTL){moveRight=!moveRight}if(moveRight){this._positionBar(this._calcPercent(tabRect.left+tabRect.width-oldRect.left,w)-m,this._left)}else{this._positionBar(this._calcPercent(oldRect.left+oldRect.width-tabRect.left,w)-m,this._calcPercent(tabOffsetLeft,w)+m)}if(this.scrollable){this._scrollToSelectedIfNeeded(tabRect.width,tabOffsetLeft)}},_scrollToSelectedIfNeeded:function(tabWidth,tabOffsetLeft){var l=tabOffsetLeft-this.$.tabsContainer.scrollLeft;if(l<0){this.$.tabsContainer.scrollLeft+=l}else{l+=tabWidth-this.$.tabsContainer.offsetWidth;if(l>0){this.$.tabsContainer.scrollLeft+=l}}},_calcPercent:function(w,w0){return 100*w/w0},_positionBar:function(width,left){width=width||0;left=left||0;this._width=width;this._left=left;this.transform("translateX("+left+"%) scaleX("+width/100+")",this.$.selectionBar)},_onBarTransitionEnd:function(e){var cl=this.$.selectionBar.classList;if(cl.contains("expand")){cl.remove("expand");cl.add("contract");this._positionBar(this._pos.width,this._pos.left)}else if(cl.contains("contract")){cl.remove("contract")}}}); \ No newline at end of file +Polymer({is:"cr-dialog","extends":"dialog",properties:{closeText:String,ignorePopstate:{type:Boolean,value:false}},ready:function(){window.addEventListener("popstate",function(){if(!this.ignorePopstate&&this.open)this.cancel()}.bind(this))},cancel:function(){this.fire("cancel");HTMLDialogElement.prototype.close.call(this,"")},close:function(opt_returnValue){HTMLDialogElement.prototype.close.call(this,"success")},getCloseButton:function(){return this.$.close}});Polymer({is:"app-drawer",properties:{opened:{type:Boolean,value:false,notify:true,reflectToAttribute:true},persistent:{type:Boolean,value:false,reflectToAttribute:true},align:{type:String,value:"left"},position:{type:String,readOnly:true,value:"left",reflectToAttribute:true},swipeOpen:{type:Boolean,value:false,reflectToAttribute:true},noFocusTrap:{type:Boolean,value:false}},observers:["resetLayout(position)","_resetPosition(align, isAttached)"],_translateOffset:0,_trackDetails:null,_drawerState:0,_boundEscKeydownHandler:null,_firstTabStop:null,_lastTabStop:null,ready:function(){this.setScrollDirection("y");this._setTransitionDuration("0s")},attached:function(){Polymer.RenderStatus.afterNextRender(this,function(){this._setTransitionDuration("");this._boundEscKeydownHandler=this._escKeydownHandler.bind(this);this._resetDrawerState();this.listen(this,"track","_track");this.addEventListener("transitionend",this._transitionend.bind(this));this.addEventListener("keydown",this._tabKeydownHandler.bind(this))})},detached:function(){document.removeEventListener("keydown",this._boundEscKeydownHandler)},open:function(){this.opened=true},close:function(){this.opened=false},toggle:function(){this.opened=!this.opened},getWidth:function(){return this.$.contentContainer.offsetWidth},resetLayout:function(){this.debounce("_resetLayout",function(){this.fire("app-drawer-reset-layout")},1)},_isRTL:function(){return window.getComputedStyle(this).direction==="rtl"},_resetPosition:function(){switch(this.align){case"start":this._setPosition(this._isRTL()?"right":"left");return;case"end":this._setPosition(this._isRTL()?"left":"right");return}this._setPosition(this.align)},_escKeydownHandler:function(event){var ESC_KEYCODE=27;if(event.keyCode===ESC_KEYCODE){event.preventDefault();this.close()}},_track:function(event){if(this.persistent){return}event.preventDefault();switch(event.detail.state){case"start":this._trackStart(event);break;case"track":this._trackMove(event);break;case"end":this._trackEnd(event);break}},_trackStart:function(event){this._drawerState=this._DRAWER_STATE.TRACKING;this._setTransitionDuration("0s");this.style.visibility="visible";var rect=this.$.contentContainer.getBoundingClientRect();if(this.position==="left"){this._translateOffset=rect.left}else{this._translateOffset=rect.right-window.innerWidth}this._trackDetails=[]},_trackMove:function(event){this._translateDrawer(event.detail.dx+this._translateOffset);this._trackDetails.push({dx:event.detail.dx,timeStamp:Date.now()})},_trackEnd:function(event){var x=event.detail.dx+this._translateOffset;var drawerWidth=this.getWidth();var isPositionLeft=this.position==="left";var isInEndState=isPositionLeft?x>=0||x<=-drawerWidth:x<=0||x>=drawerWidth;if(!isInEndState){var trackDetails=this._trackDetails;this._trackDetails=null;this._flingDrawer(event,trackDetails);if(this._drawerState===this._DRAWER_STATE.FLINGING){return}}var halfWidth=drawerWidth/2;if(event.detail.dx<-halfWidth){this.opened=this.position==="right"}else if(event.detail.dx>halfWidth){this.opened=this.position==="left"}if(isInEndState){this._resetDrawerState()}this._setTransitionDuration("");this._resetDrawerTranslate();this.style.visibility=""},_calculateVelocity:function(event,trackDetails){var now=Date.now();var timeLowerBound=now-100;var trackDetail;var min=0;var max=trackDetails.length-1;while(min<=max){var mid=min+max>>1;var d=trackDetails[mid];if(d.timeStamp>=timeLowerBound){trackDetail=d;max=mid-1}else{min=mid+1}}if(trackDetail){var dx=event.detail.dx-trackDetail.dx;var dt=now-trackDetail.timeStamp||1;return dx/dt}return 0},_flingDrawer:function(event,trackDetails){var velocity=this._calculateVelocity(event,trackDetails);if(Math.abs(velocity)<this._MIN_FLING_THRESHOLD){return}this._drawerState=this._DRAWER_STATE.FLINGING;var x=event.detail.dx+this._translateOffset;var drawerWidth=this.getWidth();var isPositionLeft=this.position==="left";var isVelocityPositive=velocity>0;var isClosingLeft=!isVelocityPositive&&isPositionLeft;var isClosingRight=isVelocityPositive&&!isPositionLeft;var dx;if(isClosingLeft){dx=-(x+drawerWidth)}else if(isClosingRight){dx=drawerWidth-x}else{dx=-x}if(isVelocityPositive){velocity=Math.max(velocity,this._MIN_TRANSITION_VELOCITY);this.opened=this.position==="left"}else{velocity=Math.min(velocity,-this._MIN_TRANSITION_VELOCITY);this.opened=this.position==="right"}this._setTransitionDuration(this._FLING_INITIAL_SLOPE*dx/velocity+"ms");this._setTransitionTimingFunction(this._FLING_TIMING_FUNCTION);this._resetDrawerTranslate()},_transitionend:function(event){var target=Polymer.dom(event).rootTarget;if(target===this.$.contentContainer||target===this.$.scrim){if(this._drawerState===this._DRAWER_STATE.FLINGING){this._setTransitionDuration("");this._setTransitionTimingFunction("");this.style.visibility=""}this._resetDrawerState()}},_setTransitionDuration:function(duration){this.$.contentContainer.style.transitionDuration=duration;this.$.scrim.style.transitionDuration=duration},_setTransitionTimingFunction:function(timingFunction){this.$.contentContainer.style.transitionTimingFunction=timingFunction;this.$.scrim.style.transitionTimingFunction=timingFunction},_translateDrawer:function(x){var drawerWidth=this.getWidth();if(this.position==="left"){x=Math.max(-drawerWidth,Math.min(x,0));this.$.scrim.style.opacity=1+x/drawerWidth}else{x=Math.max(0,Math.min(x,drawerWidth));this.$.scrim.style.opacity=1-x/drawerWidth}this.translate3d(x+"px","0","0",this.$.contentContainer)},_resetDrawerTranslate:function(){this.$.scrim.style.opacity="";this.transform("",this.$.contentContainer)},_resetDrawerState:function(){var oldState=this._drawerState;if(this.opened){this._drawerState=this.persistent?this._DRAWER_STATE.OPENED_PERSISTENT:this._DRAWER_STATE.OPENED}else{this._drawerState=this._DRAWER_STATE.CLOSED}if(oldState!==this._drawerState){if(this._drawerState===this._DRAWER_STATE.OPENED){this._setKeyboardFocusTrap();document.addEventListener("keydown",this._boundEscKeydownHandler);document.body.style.overflow="hidden"}else{document.removeEventListener("keydown",this._boundEscKeydownHandler);document.body.style.overflow=""}if(oldState!==this._DRAWER_STATE.INIT){this.fire("app-drawer-transitioned")}}},_setKeyboardFocusTrap:function(){if(this.noFocusTrap){return}var focusableElementsSelector=['a[href]:not([tabindex="-1"])','area[href]:not([tabindex="-1"])','input:not([disabled]):not([tabindex="-1"])','select:not([disabled]):not([tabindex="-1"])','textarea:not([disabled]):not([tabindex="-1"])','button:not([disabled]):not([tabindex="-1"])','iframe:not([tabindex="-1"])','[tabindex]:not([tabindex="-1"])','[contentEditable=true]:not([tabindex="-1"])'].join(",");var focusableElements=Polymer.dom(this).querySelectorAll(focusableElementsSelector);if(focusableElements.length>0){this._firstTabStop=focusableElements[0];this._lastTabStop=focusableElements[focusableElements.length-1]}else{this._firstTabStop=null;this._lastTabStop=null}var tabindex=this.getAttribute("tabindex");if(tabindex&&parseInt(tabindex,10)>-1){this.focus()}else if(this._firstTabStop){this._firstTabStop.focus()}},_tabKeydownHandler:function(event){if(this.noFocusTrap){return}var TAB_KEYCODE=9;if(this._drawerState===this._DRAWER_STATE.OPENED&&event.keyCode===TAB_KEYCODE){if(event.shiftKey){if(this._firstTabStop&&Polymer.dom(event).localTarget===this._firstTabStop){event.preventDefault();this._lastTabStop.focus()}}else{if(this._lastTabStop&&Polymer.dom(event).localTarget===this._lastTabStop){event.preventDefault();this._firstTabStop.focus()}}}},_MIN_FLING_THRESHOLD:.2,_MIN_TRANSITION_VELOCITY:1.2,_FLING_TIMING_FUNCTION:"cubic-bezier(0.667, 1, 0.667, 1)",_FLING_INITIAL_SLOPE:1.5,_DRAWER_STATE:{INIT:0,OPENED:1,OPENED_PERSISTENT:2,CLOSED:3,TRACKING:4,FLINGING:5}});Polymer({is:"paper-tab",behaviors:[Polymer.IronControlState,Polymer.IronButtonState,Polymer.PaperRippleBehavior],properties:{link:{type:Boolean,value:false,reflectToAttribute:true}},hostAttributes:{role:"tab"},listeners:{down:"_updateNoink",tap:"_onTap"},attached:function(){this._updateNoink()},get _parentNoink(){var parent=Polymer.dom(this).parentNode;return!!parent&&!!parent.noink},_updateNoink:function(){this.noink=!!this.noink||!!this._parentNoink},_onTap:function(event){if(this.link){var anchor=this.queryEffectiveChildren("a");if(!anchor){return}if(event.target===anchor){return}anchor.click()}}});Polymer.IronMenuBehaviorImpl={properties:{focusedItem:{observer:"_focusedItemChanged",readOnly:true,type:Object},attrForItemTitle:{type:String}},hostAttributes:{role:"menu",tabindex:"0"},observers:["_updateMultiselectable(multi)"],listeners:{focus:"_onFocus",keydown:"_onKeydown","iron-items-changed":"_onIronItemsChanged"},keyBindings:{up:"_onUpKey",down:"_onDownKey",esc:"_onEscKey","shift+tab:keydown":"_onShiftTabDown"},attached:function(){this._resetTabindices()},select:function(value){if(this._defaultFocusAsync){this.cancelAsync(this._defaultFocusAsync);this._defaultFocusAsync=null}var item=this._valueToItem(value);if(item&&item.hasAttribute("disabled"))return;this._setFocusedItem(item);Polymer.IronMultiSelectableBehaviorImpl.select.apply(this,arguments)},_resetTabindices:function(){var selectedItem=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this.items.forEach(function(item){item.setAttribute("tabindex",item===selectedItem?"0":"-1")},this)},_updateMultiselectable:function(multi){if(multi){this.setAttribute("aria-multiselectable","true")}else{this.removeAttribute("aria-multiselectable")}},_focusWithKeyboardEvent:function(event){for(var i=0,item;item=this.items[i];i++){var attr=this.attrForItemTitle||"textContent";var title=item[attr]||item.getAttribute(attr);if(!item.hasAttribute("disabled")&&title&&title.trim().charAt(0).toLowerCase()===String.fromCharCode(event.keyCode).toLowerCase()){this._setFocusedItem(item);break}}},_focusPrevious:function(){var length=this.items.length;var curFocusIndex=Number(this.indexOf(this.focusedItem));for(var i=1;i<length+1;i++){var item=this.items[(curFocusIndex-i+length)%length];if(!item.hasAttribute("disabled")){var owner=Polymer.dom(item).getOwnerRoot()||document;this._setFocusedItem(item);if(Polymer.dom(owner).activeElement==item){return}}}},_focusNext:function(){var length=this.items.length;var curFocusIndex=Number(this.indexOf(this.focusedItem));for(var i=1;i<length+1;i++){var item=this.items[(curFocusIndex+i)%length];if(!item.hasAttribute("disabled")){var owner=Polymer.dom(item).getOwnerRoot()||document;this._setFocusedItem(item);if(Polymer.dom(owner).activeElement==item){return}}}},_applySelection:function(item,isSelected){if(isSelected){item.setAttribute("aria-selected","true")}else{item.removeAttribute("aria-selected")}Polymer.IronSelectableBehavior._applySelection.apply(this,arguments)},_focusedItemChanged:function(focusedItem,old){old&&old.setAttribute("tabindex","-1");if(focusedItem){focusedItem.setAttribute("tabindex","0");focusedItem.focus()}},_onIronItemsChanged:function(event){if(event.detail.addedNodes.length){this._resetTabindices()}},_onShiftTabDown:function(event){var oldTabIndex=this.getAttribute("tabindex");Polymer.IronMenuBehaviorImpl._shiftTabPressed=true;this._setFocusedItem(null);this.setAttribute("tabindex","-1");this.async(function(){this.setAttribute("tabindex",oldTabIndex);Polymer.IronMenuBehaviorImpl._shiftTabPressed=false},1)},_onFocus:function(event){if(Polymer.IronMenuBehaviorImpl._shiftTabPressed){return}var rootTarget=Polymer.dom(event).rootTarget;if(rootTarget!==this&&typeof rootTarget.tabIndex!=="undefined"&&!this.isLightDescendant(rootTarget)){return}this._defaultFocusAsync=this.async(function(){var selectedItem=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this._setFocusedItem(null);if(selectedItem){this._setFocusedItem(selectedItem)}else if(this.items[0]){this._focusNext()}})},_onUpKey:function(event){this._focusPrevious();event.detail.keyboardEvent.preventDefault()},_onDownKey:function(event){this._focusNext();event.detail.keyboardEvent.preventDefault()},_onEscKey:function(event){this.focusedItem.blur()},_onKeydown:function(event){if(!this.keyboardEventMatchesKeys(event,"up down esc")){this._focusWithKeyboardEvent(event)}event.stopPropagation()},_activateHandler:function(event){Polymer.IronSelectableBehavior._activateHandler.call(this,event);event.stopPropagation()}};Polymer.IronMenuBehaviorImpl._shiftTabPressed=false;Polymer.IronMenuBehavior=[Polymer.IronMultiSelectableBehavior,Polymer.IronA11yKeysBehavior,Polymer.IronMenuBehaviorImpl];Polymer.IronMenubarBehaviorImpl={hostAttributes:{role:"menubar"},keyBindings:{left:"_onLeftKey",right:"_onRightKey"},_onUpKey:function(event){this.focusedItem.click();event.detail.keyboardEvent.preventDefault()},_onDownKey:function(event){this.focusedItem.click();event.detail.keyboardEvent.preventDefault()},get _isRTL(){return window.getComputedStyle(this)["direction"]==="rtl"},_onLeftKey:function(event){if(this._isRTL){this._focusNext()}else{this._focusPrevious()}event.detail.keyboardEvent.preventDefault()},_onRightKey:function(event){if(this._isRTL){this._focusPrevious()}else{this._focusNext()}event.detail.keyboardEvent.preventDefault()},_onKeydown:function(event){if(this.keyboardEventMatchesKeys(event,"up down left right esc")){return}this._focusWithKeyboardEvent(event)}};Polymer.IronMenubarBehavior=[Polymer.IronMenuBehavior,Polymer.IronMenubarBehaviorImpl];Polymer({is:"paper-tabs",behaviors:[Polymer.IronResizableBehavior,Polymer.IronMenubarBehavior],properties:{noink:{type:Boolean,value:false,observer:"_noinkChanged"},noBar:{type:Boolean,value:false},noSlide:{type:Boolean,value:false},scrollable:{type:Boolean,value:false},fitContainer:{type:Boolean,value:false},disableDrag:{type:Boolean,value:false},hideScrollButtons:{type:Boolean,value:false},alignBottom:{type:Boolean,value:false},selectable:{type:String,value:"paper-tab"},autoselect:{type:Boolean,value:false},autoselectDelay:{type:Number,value:0},_step:{type:Number,value:10},_holdDelay:{type:Number,value:1},_leftHidden:{type:Boolean,value:false},_rightHidden:{type:Boolean,value:false},_previousTab:{type:Object}},hostAttributes:{role:"tablist"},listeners:{"iron-resize":"_onTabSizingChanged","iron-items-changed":"_onTabSizingChanged","iron-select":"_onIronSelect","iron-deselect":"_onIronDeselect"},keyBindings:{"left:keyup right:keyup":"_onArrowKeyup"},created:function(){this._holdJob=null;this._pendingActivationItem=undefined;this._pendingActivationTimeout=undefined;this._bindDelayedActivationHandler=this._delayedActivationHandler.bind(this);this.addEventListener("blur",this._onBlurCapture.bind(this),true)},ready:function(){this.setScrollDirection("y",this.$.tabsContainer)},detached:function(){this._cancelPendingActivation()},_noinkChanged:function(noink){var childTabs=Polymer.dom(this).querySelectorAll("paper-tab");childTabs.forEach(noink?this._setNoinkAttribute:this._removeNoinkAttribute)},_setNoinkAttribute:function(element){element.setAttribute("noink","")},_removeNoinkAttribute:function(element){element.removeAttribute("noink")},_computeScrollButtonClass:function(hideThisButton,scrollable,hideScrollButtons){if(!scrollable||hideScrollButtons){return"hidden"}if(hideThisButton){return"not-visible"}return""},_computeTabsContentClass:function(scrollable,fitContainer){return scrollable?"scrollable"+(fitContainer?" fit-container":""):" fit-container"},_computeSelectionBarClass:function(noBar,alignBottom){if(noBar){return"hidden"}else if(alignBottom){return"align-bottom"}return""},_onTabSizingChanged:function(){this.debounce("_onTabSizingChanged",function(){this._scroll();this._tabChanged(this.selectedItem)},10)},_onIronSelect:function(event){this._tabChanged(event.detail.item,this._previousTab);this._previousTab=event.detail.item;this.cancelDebouncer("tab-changed")},_onIronDeselect:function(event){this.debounce("tab-changed",function(){this._tabChanged(null,this._previousTab);this._previousTab=null},1)},_activateHandler:function(){this._cancelPendingActivation();Polymer.IronMenuBehaviorImpl._activateHandler.apply(this,arguments)},_scheduleActivation:function(item,delay){this._pendingActivationItem=item;this._pendingActivationTimeout=this.async(this._bindDelayedActivationHandler,delay)},_delayedActivationHandler:function(){var item=this._pendingActivationItem;this._pendingActivationItem=undefined;this._pendingActivationTimeout=undefined;item.fire(this.activateEvent,null,{bubbles:true,cancelable:true})},_cancelPendingActivation:function(){if(this._pendingActivationTimeout!==undefined){this.cancelAsync(this._pendingActivationTimeout);this._pendingActivationItem=undefined;this._pendingActivationTimeout=undefined}},_onArrowKeyup:function(event){if(this.autoselect){this._scheduleActivation(this.focusedItem,this.autoselectDelay)}},_onBlurCapture:function(event){if(event.target===this._pendingActivationItem){this._cancelPendingActivation()}},get _tabContainerScrollSize(){return Math.max(0,this.$.tabsContainer.scrollWidth-this.$.tabsContainer.offsetWidth)},_scroll:function(e,detail){if(!this.scrollable){return}var ddx=detail&&-detail.ddx||0;this._affectScroll(ddx)},_down:function(e){this.async(function(){if(this._defaultFocusAsync){this.cancelAsync(this._defaultFocusAsync);this._defaultFocusAsync=null}},1)},_affectScroll:function(dx){this.$.tabsContainer.scrollLeft+=dx;var scrollLeft=this.$.tabsContainer.scrollLeft;this._leftHidden=scrollLeft===0;this._rightHidden=scrollLeft===this._tabContainerScrollSize},_onLeftScrollButtonDown:function(){this._scrollToLeft();this._holdJob=setInterval(this._scrollToLeft.bind(this),this._holdDelay)},_onRightScrollButtonDown:function(){this._scrollToRight();this._holdJob=setInterval(this._scrollToRight.bind(this),this._holdDelay)},_onScrollButtonUp:function(){clearInterval(this._holdJob);this._holdJob=null},_scrollToLeft:function(){this._affectScroll(-this._step)},_scrollToRight:function(){this._affectScroll(this._step)},_tabChanged:function(tab,old){if(!tab){this.$.selectionBar.classList.remove("expand");this.$.selectionBar.classList.remove("contract");this._positionBar(0,0);return}var r=this.$.tabsContent.getBoundingClientRect();var w=r.width;var tabRect=tab.getBoundingClientRect();var tabOffsetLeft=tabRect.left-r.left;this._pos={width:this._calcPercent(tabRect.width,w),left:this._calcPercent(tabOffsetLeft,w)};if(this.noSlide||old==null){this.$.selectionBar.classList.remove("expand");this.$.selectionBar.classList.remove("contract");this._positionBar(this._pos.width,this._pos.left);return}var oldRect=old.getBoundingClientRect();var oldIndex=this.items.indexOf(old);var index=this.items.indexOf(tab);var m=5;this.$.selectionBar.classList.add("expand");var moveRight=oldIndex<index;var isRTL=this._isRTL;if(isRTL){moveRight=!moveRight}if(moveRight){this._positionBar(this._calcPercent(tabRect.left+tabRect.width-oldRect.left,w)-m,this._left)}else{this._positionBar(this._calcPercent(oldRect.left+oldRect.width-tabRect.left,w)-m,this._calcPercent(tabOffsetLeft,w)+m)}if(this.scrollable){this._scrollToSelectedIfNeeded(tabRect.width,tabOffsetLeft)}},_scrollToSelectedIfNeeded:function(tabWidth,tabOffsetLeft){var l=tabOffsetLeft-this.$.tabsContainer.scrollLeft;if(l<0){this.$.tabsContainer.scrollLeft+=l}else{l+=tabWidth-this.$.tabsContainer.offsetWidth;if(l>0){this.$.tabsContainer.scrollLeft+=l}}},_calcPercent:function(w,w0){return 100*w/w0},_positionBar:function(width,left){width=width||0;left=left||0;this._width=width;this._left=left;this.transform("translateX("+left+"%) scaleX("+width/100+")",this.$.selectionBar)},_onBarTransitionEnd:function(e){var cl=this.$.selectionBar.classList;if(cl.contains("expand")){cl.remove("expand");cl.add("contract");this._positionBar(this._pos.width,this._pos.left)}else if(cl.contains("contract")){cl.remove("contract")}}}); \ No newline at end of file
diff --git a/chrome/browser/resources/md_history/lazy_load.html b/chrome/browser/resources/md_history/lazy_load.html index 0b489d25..b7f70eb2 100644 --- a/chrome/browser/resources/md_history/lazy_load.html +++ b/chrome/browser/resources/md_history/lazy_load.html
@@ -1,7 +1,7 @@ <link rel="import" href="chrome://history/grouped_list.html"> <link rel="import" href="chrome://history/synced_device_manager.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_shared_menu/cr_shared_menu.html"> <link rel="import" href="chrome://resources/polymer/v1_0/app-layout/app-drawer/app-drawer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
diff --git a/chrome/browser/resources/md_history/lazy_load.vulcanized.html b/chrome/browser/resources/md_history/lazy_load.vulcanized.html index d305c9e2..3c1dfb8 100644 --- a/chrome/browser/resources/md_history/lazy_load.vulcanized.html +++ b/chrome/browser/resources/md_history/lazy_load.vulcanized.html
@@ -78,13 +78,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat; @@ -252,8 +245,6 @@ </style> </template> </dom-module> - - <dom-module id="paper-button" assetpath="chrome://resources/polymer/v1_0/paper-button/" css-build="shadow"> <template strip-whitespace=""> <style scope="paper-button">:host { @@ -373,7 +364,7 @@ } :host([disabled]), .paper-item[disabled] { - color: var(--paper-item-disabled-color,var(--disabled-text-color));; + color: var(--paper-item-disabled-color,var(--disabled-text-color)); ; } @@ -399,8 +390,6 @@ </style> </template> </dom-module> - - <dom-module id="paper-item" assetpath="chrome://resources/polymer/v1_0/paper-item/" css-build="shadow"> <template> @@ -431,7 +420,7 @@ } :host([disabled]), .paper-item[disabled] { - color: var(--paper-item-disabled-color,var(--disabled-text-color));; + color: var(--paper-item-disabled-color,var(--disabled-text-color)); ; } @@ -468,93 +457,49 @@ </template> </dom-module> -<dom-module id="iron-overlay-backdrop" assetpath="chrome://resources/polymer/v1_0/iron-overlay-behavior/" css-build="shadow"> - +<dom-module id="cr-action-menu" assetpath="chrome://resources/cr_elements/cr_action_menu/" css-build="shadow"> <template> - <style scope="iron-overlay-backdrop">:host { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: var(--iron-overlay-backdrop-background-color, #000); - opacity: 0; - transition: opacity 0.2s; - pointer-events: none; - ; -} - -:host(.opened) { - opacity: var(--iron-overlay-backdrop-opacity, 0.6); - pointer-events: auto; - ; -} - -</style> - - <content></content> - </template> - -</dom-module> - -<script src="chrome://resources/polymer/v1_0/web-animations-js/web-animations-next-lite.min.js"></script> - - -<dom-module id="iron-dropdown" assetpath="chrome://resources/polymer/v1_0/iron-dropdown/" css-build="shadow"> - <template> - <style scope="iron-dropdown">:host { - position: fixed; -} - -#contentWrapper ::content > * { - overflow: auto; -} - -#contentWrapper.animating ::content > * { - overflow: hidden; -} - -</style> - - <div id="contentWrapper"> - <content id="content" select=".dropdown-content"></content> - </div> - </template> - - </dom-module> -<dom-module id="paper-listbox" assetpath="chrome://resources/polymer/v1_0/paper-listbox/" css-build="shadow"> - <template> - <style scope="paper-listbox">:host { - display: block; + <style scope="cr-action-menu">:host { + background-color: white; + border: none; + box-shadow: 0 2px 6px var(--paper-grey-500); + margin: 0; + outline: none; padding: 8px 0; +} - background: var(--paper-listbox-background-color,var(--primary-background-color));; - color: var(--paper-listbox-color,var(--primary-text-color));; +:host::backdrop { + background-color: transparent; +} - ; +:host ::content .dropdown-item { + background: none; + border: none; + box-sizing: border-box; + color: var(--paper-grey-800); + font: inherit; + min-height: 32px; + padding: 0 24px; + text-align: start; + width: 100%; +} + +:host ::content .dropdown-item:not([hidden]) { + align-items: center; + display: flex; +} + +:host ::content .dropdown-item:not([disabled]) { + cursor: var(--cr-actionable_-_cursor); +} + +:host ::content .dropdown-item:focus { + background-color: var(--paper-grey-300); + outline: none; } </style> - - <content></content> - </template> - - </dom-module> -<dom-module id="cr-shared-menu" assetpath="chrome://resources/cr_elements/cr_shared_menu/" css-build="shadow"> - <template> - <style scope="cr-shared-menu">paper-listbox { - box-shadow: var(--shadow-elevation-2dp_-_box-shadow); - overflow: hidden; - position: relative; - width: var(--cr-shared-menu-width); -} - -</style> - <iron-dropdown id="dropdown" allow-outside-scroll="" restore-focus-on-close="" vertical-align="auto" horizontal-align="right" opened="{{menuOpen}}" open-animation-config="[[openAnimationConfig]]" close-animation-config="[[closeAnimationConfig]]"> - <paper-listbox id="menu" class="dropdown-content"> - <content></content> - </paper-listbox> - </iron-dropdown> + <content select=".dropdown-item,hr"></content> </template> </dom-module> @@ -631,13 +576,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat; @@ -821,13 +759,6 @@ justify-content: center; } -.menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; -} - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat; @@ -1038,14 +969,14 @@ </div> <template is="cr-lazy-render" id="menu"> - <cr-shared-menu> - <paper-item id="menuOpenButton" class="menu-item" on-tap="onOpenAllTap_"> + <dialog is="cr-action-menu"> + <button id="menuOpenButton" class="dropdown-item" on-tap="onOpenAllTap_"> $i18n{openAll} - </paper-item> - <paper-item id="menuDeleteButton" class="menu-item" on-tap="onDeleteSessionTap_"> + </button> + <button id="menuDeleteButton" class="dropdown-item" on-tap="onDeleteSessionTap_"> $i18n{deleteSession} - </paper-item> - </cr-shared-menu> + </button> + </dialog> </template> </template> </dom-module> @@ -1311,7 +1242,7 @@ } paper-ripple { - color: var(--paper-tab-ink,var(--paper-yellow-a100));; + color: var(--paper-tab-ink,var(--paper-yellow-a100)); } .tab-content > ::content > a { @@ -1334,8 +1265,6 @@ <g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></g> </defs></svg> </iron-iconset-svg> - - <dom-module id="paper-tabs" assetpath="chrome://resources/polymer/v1_0/paper-tabs/" css-build="shadow"> <template> <style scope="paper-tabs">:host { @@ -1418,7 +1347,7 @@ bottom: 0; left: 0; right: 0; - background-color: var(--paper-tabs-selection-bar-color,var(--paper-yellow-a100));; + background-color: var(--paper-tabs-selection-bar-color,var(--paper-yellow-a100)); -webkit-transform: scale(0); transform: scale(0); -webkit-transform-origin: left center;
diff --git a/chrome/browser/resources/md_history/list_container.html b/chrome/browser/resources/md_history/list_container.html index b6a3b8b..409a92ef 100644 --- a/chrome/browser/resources/md_history/list_container.html +++ b/chrome/browser/resources/md_history/list_container.html
@@ -7,7 +7,7 @@ <link rel="import" href="chrome://history/history_list.html"> <link rel="import" href="chrome://history/shared_style.html"> -<!-- Lazy loaded: cr-dialog, cr-shared-menu, history-grouped-list, paper-button, +<!-- Lazy loaded: cr-dialog, cr-action-menu, history-grouped-list, paper-button, paper-item. --> <dom-module id="history-list-container"> @@ -62,17 +62,17 @@ </template> <template is="cr-lazy-render" id="sharedMenu"> - <cr-shared-menu> - <paper-item id="menuMoreButton" class="menu-item" + <dialog is="cr-action-menu"> + <button id="menuMoreButton" class="dropdown-item" on-tap="onMoreFromSiteTap_"> $i18n{moreFromSite} - </paper-item> - <paper-item id="menuRemoveButton" class="menu-item" + </button> + <button id="menuRemoveButton" class="dropdown-item" disabled="[[!canDeleteHistory_()]]" on-tap="onRemoveFromHistoryTap_"> $i18n{removeFromHistory} - </paper-item> - </cr-shared-menu> + </button> + </dialog> </template> </template> <script src="chrome://history/list_container.js"></script>
diff --git a/chrome/browser/resources/md_history/list_container.js b/chrome/browser/resources/md_history/list_container.js index 51120d53..d808ab58 100644 --- a/chrome/browser/resources/md_history/list_container.js +++ b/chrome/browser/resources/md_history/list_container.js
@@ -23,6 +23,16 @@ /** @type {!QueryResult} */ queryResult: Object, + + /** + * @private {?{ + * index: number, + * item: !HistoryEntry, + * path: string, + * target: !HTMLElement + * }} + */ + actionMenuModel_: Object, }, observers: [ @@ -31,9 +41,8 @@ ], listeners: { - 'history-list-scrolled': 'closeMenu_', 'load-more-history': 'loadMoreHistory_', - 'toggle-menu': 'toggleMenu_', + 'open-menu': 'openMenu_', }, /** @@ -222,20 +231,25 @@ */ closeMenu_: function() { var menu = this.$.sharedMenu.getIfExists(); - if (menu) - menu.closeMenu(); + if (menu && menu.open) { + this.actionMenuModel_ = null; + menu.close(); + } }, /** - * Opens the overflow menu unless the menu is already open and the same button - * is pressed. - * @param {{detail: {item: !HistoryEntry, target: !HTMLElement}}} e + * Opens the overflow menu. + * @param {{detail: { + * index: number, item: !HistoryEntry, + * path: string, target: !HTMLElement + * }}} e * @private */ - toggleMenu_: function(e) { + openMenu_: function(e) { var target = e.detail.target; + this.actionMenuModel_ = e.detail; var menu = /** @type {CrSharedMenuElement} */ this.$.sharedMenu.get(); - menu.toggleMenu(target, e.detail); + menu.showAt(target); }, /** @private */ @@ -244,8 +258,9 @@ 'EntryMenuShowMoreFromSite'); var menu = assert(this.$.sharedMenu.getIfExists()); - this.set('queryState.searchTerm', menu.itemData.item.domain); - menu.closeMenu(); + this.set('queryState.searchTerm', this.actionMenuModel_.item.domain); + this.actionMenuModel_ = null; + this.closeMenu_(); }, /** @private */ @@ -253,7 +268,7 @@ var browserService = md_history.BrowserService.getInstance(); browserService.recordAction('EntryMenuRemoveFromHistory'); var menu = assert(this.$.sharedMenu.getIfExists()); - var itemData = menu.itemData; + var itemData = this.actionMenuModel_; browserService.deleteItems([itemData.item]).then(function(items) { // This unselect-all resets the toolbar when deleting a selected item // and clears selection state which can be invalid if items move @@ -277,7 +292,7 @@ UMA_MAX_SUBSET_BUCKET_VALUE); } }.bind(this)); - menu.closeMenu(); + this.closeMenu_(); }, /**
diff --git a/chrome/browser/resources/md_history/shared_style.html b/chrome/browser/resources/md_history/shared_style.html index 5d58cc00b..809f82c 100644 --- a/chrome/browser/resources/md_history/shared_style.html +++ b/chrome/browser/resources/md_history/shared_style.html
@@ -37,13 +37,6 @@ justify-content: center; } - .menu-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - white-space: nowrap; - } - .website-icon { -webkit-margin-end: 16px; background-repeat: no-repeat;
diff --git a/chrome/browser/resources/md_history/synced_device_card.js b/chrome/browser/resources/md_history/synced_device_card.js index 1c2e9f6..244cc82f7 100644 --- a/chrome/browser/resources/md_history/synced_device_card.js +++ b/chrome/browser/resources/md_history/synced_device_card.js
@@ -150,7 +150,7 @@ * @private */ onMenuButtonTap_: function(e) { - this.fire('toggle-menu', { + this.fire('open-menu', { target: Polymer.dom(e).localTarget, tag: this.sessionTag, });
diff --git a/chrome/browser/resources/md_history/synced_device_manager.html b/chrome/browser/resources/md_history/synced_device_manager.html index d0a7a1d..78428c3 100644 --- a/chrome/browser/resources/md_history/synced_device_manager.html +++ b/chrome/browser/resources/md_history/synced_device_manager.html
@@ -3,8 +3,8 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_shared_menu/cr_shared_menu.html"> <link rel="import" href="chrome://resources/cr_elements/shared_style_css.html"> <link rel="import" href="chrome://history/shared_style.html"> <link rel="import" href="chrome://history/synced_device_card.html"> @@ -90,16 +90,16 @@ </div> <template is="cr-lazy-render" id="menu"> - <cr-shared-menu> - <paper-item id="menuOpenButton" class="menu-item" + <dialog is="cr-action-menu"> + <button id="menuOpenButton" class="dropdown-item" on-tap="onOpenAllTap_"> $i18n{openAll} - </paper-item> - <paper-item id="menuDeleteButton" class="menu-item" + </button> + <button id="menuDeleteButton" class="dropdown-item" on-tap="onDeleteSessionTap_"> $i18n{deleteSession} - </paper-item> - </cr-shared-menu> + </button> + </dialog> </template> </template> <script src="chrome://history/synced_device_manager.js"></script>
diff --git a/chrome/browser/resources/md_history/synced_device_manager.js b/chrome/browser/resources/md_history/synced_device_manager.js index a2a400e2..e23f571 100644 --- a/chrome/browser/resources/md_history/synced_device_manager.js +++ b/chrome/browser/resources/md_history/synced_device_manager.js
@@ -57,12 +57,18 @@ value: false, }, + /** @private */ hasSeenForeignData_: Boolean, + + /** + * The session ID referring to the currently active action menu. + * @private {?string} + */ + actionMenuModel_: String, }, listeners: { - 'toggle-menu': 'onToggleMenu_', - 'scroll': 'onListScroll_', + 'open-menu': 'onOpenMenu_', 'update-focus-grid': 'updateFocusGrid_', }, @@ -135,21 +141,13 @@ onSignInTap_: function() { chrome.send('startSignInFlow'); }, /** @private */ - onListScroll_: function() { - var menu = this.$.menu.getIfExists(); - if (menu) - menu.closeMenu(); - }, - - /** @private */ - onToggleMenu_: function(e) { - var menu = /** @type {CrSharedMenuElement} */ this.$.menu.get(); - menu.toggleMenu(e.detail.target, e.detail.tag); - if (menu.menuOpen) { - md_history.BrowserService.getInstance().recordHistogram( - SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.SHOW_SESSION_MENU, - SyncedTabsHistogram.LIMIT); - } + onOpenMenu_: function(e) { + var menu = /** @type {CrActionMenuElement} */ this.$.menu.get(); + this.actionMenuModel_ = e.detail.tag; + menu.showAt(e.detail.target); + md_history.BrowserService.getInstance().recordHistogram( + SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.SHOW_SESSION_MENU, + SyncedTabsHistogram.LIMIT); }, /** @private */ @@ -159,8 +157,9 @@ browserService.recordHistogram( SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.OPEN_ALL, SyncedTabsHistogram.LIMIT); - browserService.openForeignSessionAllTabs(menu.itemData); - menu.closeMenu(); + browserService.openForeignSessionAllTabs(assert(this.actionMenuModel_)); + this.actionMenuModel_ = null; + menu.close(); }, /** @private */ @@ -190,8 +189,9 @@ browserService.recordHistogram( SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.HIDE_FOR_NOW, SyncedTabsHistogram.LIMIT); - browserService.deleteForeignSession(menu.itemData); - menu.closeMenu(); + browserService.deleteForeignSession(assert(this.actionMenuModel_)); + this.actionMenuModel_ = null; + menu.close(); }, /** @private */
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html index a6dc4d5..78fbc14d 100644 --- a/chrome/browser/resources/settings/settings_shared_css.html +++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -57,20 +57,6 @@ padding: 8px 0; } - .dropdown-item { - align-items: center; - background: none; - border: none; - box-sizing: border-box; - color: var(--paper-grey-800); - display: flex; - font: inherit; - min-height: 32px; - padding: 0 24px; - text-align: start; - width: 100%; - } - iron-dropdown .dropdown-item:focus { @apply(--cr-selectable-focus); } @@ -80,13 +66,11 @@ box-shadow: 0 2px 6px var(--paper-grey-500); } - .dropdown-item:not([disabled]), iron-dropdown .dropdown-content paper-item { @apply(--settings-actionable); } - iron-dropdown .dropdown-content .dropdown-item[disabled], - cr-shared-menu .dropdown-item[disabled] { + iron-dropdown .dropdown-content .dropdown-item[disabled] { opacity: var(--settings-disabled-opacity); }
diff --git a/chrome/browser/safe_browsing/ui_manager.cc b/chrome/browser/safe_browsing/ui_manager.cc index 5aedb64..877b23f5 100644 --- a/chrome/browser/safe_browsing/ui_manager.cc +++ b/chrome/browser/safe_browsing/ui_manager.cc
@@ -5,13 +5,9 @@ #include "chrome/browser/safe_browsing/ui_manager.h" #include "base/bind.h" -#include "base/bind_helpers.h" #include "base/callback.h" -#include "base/debug/leak_tracker.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" -#include "base/stl_util.h" -#include "base/strings/string_util.h" #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" @@ -34,6 +30,7 @@ #include "net/ssl/ssl_info.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" +#include "url/gurl.h" using content::BrowserThread; using content::NavigationEntry; @@ -43,57 +40,6 @@ namespace { -const void* const kWhitelistKey = &kWhitelistKey; - -// A WhitelistUrlSet holds the set of URLs that have been whitelisted -// for a specific WebContents, along with pending entries that are still -// undecided. Each URL is associated with the first SBThreatType that -// was seen for that URL. The URLs in this set should come from -// GetWhitelistUrl() or GetMainFrameWhitelistUrlForResource(). -class WhitelistUrlSet : public base::SupportsUserData::Data { - public: - WhitelistUrlSet() {} - - bool Contains(const GURL url, SBThreatType* threat_type) { - auto found = map_.find(url); - if (found == map_.end()) - return false; - if (threat_type) - *threat_type = found->second; - return true; - } - - void RemovePending(const GURL& url) { pending_.erase(url); } - - void Insert(const GURL url, SBThreatType threat_type) { - if (Contains(url, nullptr)) - return; - map_[url] = threat_type; - RemovePending(url); - } - - bool ContainsPending(const GURL& url, SBThreatType* threat_type) { - auto found = pending_.find(url); - if (found == pending_.end()) - return false; - if (threat_type) - *threat_type = found->second; - return true; - } - - void InsertPending(const GURL url, SBThreatType threat_type) { - if (ContainsPending(url, nullptr)) - return; - pending_[url] = threat_type; - } - - private: - std::map<GURL, SBThreatType> map_; - std::map<GURL, SBThreatType> pending_; - - DISALLOW_COPY_AND_ASSIGN(WhitelistUrlSet); -}; - // Returns the URL that should be used in a WhitelistUrlSet for the given // |resource|. GURL GetMainFrameWhitelistUrlForResource( @@ -107,29 +53,6 @@ return resource.url.GetWithEmptyPath(); } -// Returns the URL that should be used in a WhitelistUrlSet for the -// resource loaded from |url| on a navigation |entry|. -GURL GetWhitelistUrl(const GURL& url, - bool is_subresource, - NavigationEntry* entry) { - if (is_subresource) { - if (!entry) - return GURL(); - return entry->GetURL().GetWithEmptyPath(); - } - return url.GetWithEmptyPath(); -} - -WhitelistUrlSet* GetOrCreateWhitelist(content::WebContents* web_contents) { - WhitelistUrlSet* site_list = - static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); - if (!site_list) { - site_list = new WhitelistUrlSet; - web_contents->SetUserData(kWhitelistKey, site_list); - } - return site_list; -} - } // namespace namespace safe_browsing { @@ -151,33 +74,6 @@ UMA_HISTOGRAM_LONG_TIMES("SB2.Delay", time); } -void SafeBrowsingUIManager::OnBlockingPageDone( - const std::vector<UnsafeResource>& resources, - bool proceed, - content::WebContents* web_contents, - const GURL& main_frame_url) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - for (const auto& resource : resources) { - if (!resource.callback.is_null()) { - DCHECK(resource.callback_thread); - resource.callback_thread->PostTask( - FROM_HERE, base::Bind(resource.callback, proceed)); - } - - GURL whitelist_url = GetWhitelistUrl( - main_frame_url, false /* is subresource */, - nullptr /* no navigation entry needed for main resource */); - if (proceed) { - AddToWhitelistUrlSet(whitelist_url, web_contents, - false /* Pending -> permanent */, - resource.threat_type); - } else if (web_contents) { - // |web_contents| doesn't exist if the tab has been closed. - RemoveFromPendingWhitelistUrlSet(whitelist_url, web_contents); - } - } -} - void SafeBrowsingUIManager::DisplayBlockingPage( const UnsafeResource& resource) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -325,20 +221,10 @@ report_info)); } -void SafeBrowsingUIManager::AddObserver(Observer* observer) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - observer_list_.AddObserver(observer); -} - -void SafeBrowsingUIManager::RemoveObserver(Observer* observer) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - observer_list_.RemoveObserver(observer); -} - // Static. void SafeBrowsingUIManager::CreateWhitelistForTesting( content::WebContents* web_contents) { - GetOrCreateWhitelist(web_contents); + EnsureWhitelistCreated(web_contents); } void SafeBrowsingUIManager::ReportInvalidCertificateChainOnIOThread( @@ -382,111 +268,6 @@ } } -// Record this domain in the given WebContents as either whitelisted or -// pending whitelisting (if an interstitial is currently displayed). If an -// existing WhitelistUrlSet does not yet exist, create a new WhitelistUrlSet. -void SafeBrowsingUIManager::AddToWhitelistUrlSet( - const GURL& whitelist_url, - content::WebContents* web_contents, - bool pending, - SBThreatType threat_type) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - // A WebContents might not exist if the tab has been closed. - if (!web_contents) - return; - - WhitelistUrlSet* site_list = GetOrCreateWhitelist(web_contents); - - if (whitelist_url.is_empty()) - return; - - if (pending) { - site_list->InsertPending(whitelist_url, threat_type); - } else { - site_list->Insert(whitelist_url, threat_type); - } - - // Notify security UI that security state has changed. - web_contents->DidChangeVisibleSecurityState(); -} - -void SafeBrowsingUIManager::RemoveFromPendingWhitelistUrlSet( - const GURL& whitelist_url, - content::WebContents* web_contents) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - // A WebContents might not exist if the tab has been closed. - if (!web_contents) - return; - - // Use |web_contents| rather than |resource.web_contents_getter| - // here. By this point, a "Back" navigation could have already been - // committed, so the page loading |resource| might be gone and - // |web_contents_getter| may no longer be valid. - WhitelistUrlSet* site_list = - static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); - - if (whitelist_url.is_empty()) - return; - - // Note that this function does not DCHECK that |whitelist_url| - // appears in the pending whitelist. In the common case, it's expected - // that a URL is in the pending whitelist when it is removed, but it's - // not always the case. For example, if there are several blocking - // pages queued up for different resources on the same page, and the - // user goes back to dimiss the first one, the subsequent blocking - // pages get dismissed as well (as if the user had clicked "Back to - // safety" on each of them). In this case, the first dismissal will - // remove the main-frame URL from the pending whitelist, so the - // main-frame URL will have already been removed when the subsequent - // blocking pages are dismissed. - if (site_list->ContainsPending(whitelist_url, nullptr)) - site_list->RemovePending(whitelist_url); - - // Notify security UI that security state has changed. - web_contents->DidChangeVisibleSecurityState(); -} - -bool SafeBrowsingUIManager::IsWhitelisted(const UnsafeResource& resource) { - NavigationEntry* entry = nullptr; - if (resource.is_subresource) { - entry = resource.GetNavigationEntryForResource(); - } - SBThreatType unused_threat_type; - return IsUrlWhitelistedOrPendingForWebContents( - resource.url, resource.is_subresource, entry, - resource.web_contents_getter.Run(), true, &unused_threat_type); -} - -// Check if the user has already seen and/or ignored a SB warning for this -// WebContents and top-level domain. -bool SafeBrowsingUIManager::IsUrlWhitelistedOrPendingForWebContents( - const GURL& url, - bool is_subresource, - NavigationEntry* entry, - content::WebContents* web_contents, - bool whitelist_only, - SBThreatType* threat_type) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - - GURL lookup_url = GetWhitelistUrl(url, is_subresource, entry); - if (lookup_url.is_empty()) - return false; - - WhitelistUrlSet* site_list = - static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); - if (!site_list) - return false; - - bool whitelisted = site_list->Contains(lookup_url, threat_type); - if (whitelist_only) { - return whitelisted; - } else { - return whitelisted || site_list->ContainsPending(lookup_url, threat_type); - } -} - // Static. GURL SafeBrowsingUIManager::GetMainFrameWhitelistUrlForResourceForTesting( const security_interstitials::UnsafeResource& resource) {
diff --git a/chrome/browser/safe_browsing/ui_manager.h b/chrome/browser/safe_browsing/ui_manager.h index 8c34379..d057dfe 100644 --- a/chrome/browser/safe_browsing/ui_manager.h +++ b/chrome/browser/safe_browsing/ui_manager.h
@@ -13,115 +13,56 @@ #include "base/callback.h" #include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/observer_list.h" #include "base/time/time.h" #include "chrome/browser/permissions/permission_uma_util.h" -#include "components/safe_browsing_db/hit_report.h" -#include "components/safe_browsing_db/util.h" -#include "components/security_interstitials/content/unsafe_resource.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/permission_type.h" -#include "url/gurl.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "components/safe_browsing/base_ui_manager.h" + +class GURL; namespace content { -class NavigationEntry; class WebContents; +struct PermissionReportInfo; } // namespace content namespace safe_browsing { -class SafeBrowsingService; +struct HitReport; // Construction needs to happen on the main thread. -class SafeBrowsingUIManager - : public base::RefCountedThreadSafe<SafeBrowsingUIManager> { +class SafeBrowsingUIManager : public BaseSafeBrowsingUIManager { public: - typedef security_interstitials::UnsafeResource UnsafeResource; - // Observer class can be used to get notified when a SafeBrowsing hit - // was found. - class Observer { - public: - // The |resource| was classified as unsafe by SafeBrowsing, and is - // not whitelisted. - // The |resource| must not be accessed after OnSafeBrowsingHit returns. - // This method will be called on the UI thread. - virtual void OnSafeBrowsingHit(const UnsafeResource& resource) = 0; - - protected: - Observer() {} - virtual ~Observer() {} - - private: - DISALLOW_COPY_AND_ASSIGN(Observer); - }; - explicit SafeBrowsingUIManager( const scoped_refptr<SafeBrowsingService>& service); // Called to stop or shutdown operations on the io_thread. This may be called // multiple times during the life of the UIManager. Should be called // on IO thread. If shutdown is true, the manager is disabled permanently. - void StopOnIOThread(bool shutdown); + void StopOnIOThread(bool shutdown) override; // Called on the UI thread to display an interstitial page. // |url| is the url of the resource that matches a safe browsing list. // If the request contained a chain of redirects, |url| is the last url // in the chain, and |original_url| is the first one (the root of the // chain). Otherwise, |original_url| = |url|. - virtual void DisplayBlockingPage(const UnsafeResource& resource); - - // A convenience wrapper method for IsUrlWhitelistedOrPendingForWebContents. - bool IsWhitelisted(const UnsafeResource& resource); - - // Checks if we already displayed or are displaying an interstitial - // for the top-level site |url| in a given WebContents. If - // |whitelist_only|, it returns true only if the user chose to ignore - // the interstitial. Otherwise, it returns true if an interstitial for - // |url| is already displaying *or* if the user has seen an - // interstitial for |url| before in this WebContents and proceeded - // through it. Called on the UI thread. - // - // If the resource was found in the whitelist or pending for the - // whitelist, |threat_type| will be set to the SBThreatType for which - // the URL was first whitelisted. - bool IsUrlWhitelistedOrPendingForWebContents( - const GURL& url, - bool is_subresource, - content::NavigationEntry* entry, - content::WebContents* web_contents, - bool whitelist_only, - SBThreatType* threat_type); - - // The blocking page for |web_contents| on the UI thread has - // completed, with |proceed| set to true if the user has chosen to - // proceed through the blocking page and false - // otherwise. |web_contents| is the WebContents that was displaying - // the blocking page. |main_frame_url| is the top-level URL on which - // the blocking page was displayed. If |proceed| is true, - // |main_frame_url| is whitelisted so that the user will not see - // another warning for that URL in this WebContents. - void OnBlockingPageDone(const std::vector<UnsafeResource>& resources, - bool proceed, - content::WebContents* web_contents, - const GURL& main_frame_url); + void DisplayBlockingPage(const UnsafeResource& resource) override; // Log the user perceived delay caused by SafeBrowsing. This delay is the time // delta starting from when we would have started reading data from the // network, and ending when the SafeBrowsing check completes indicating that // the current page is 'safe'. - void LogPauseDelay(base::TimeDelta time); + void LogPauseDelay(base::TimeDelta time) override; // Called on the IO thread by the ThreatDetails with the serialized // protocol buffer, so the service can send it over. - virtual void SendSerializedThreatDetails(const std::string& serialized); + void SendSerializedThreatDetails(const std::string& serialized) override; // Report hits to the unsafe contents (malware, phishing, unsafe download URL) // to the server. Can only be called on UI thread. If |post_data| is // non-empty, the request will be sent as a POST instead of a GET. // Will report only for UMA || is_extended_reporting. - virtual void MaybeReportSafeBrowsingHit( - const safe_browsing::HitReport& hit_report); + void MaybeReportSafeBrowsingHit( + const safe_browsing::HitReport& hit_report) override; // Report an invalid TLS/SSL certificate chain to the server. Can only // be called on UI thread. @@ -132,10 +73,6 @@ // thread. void ReportPermissionAction(const PermissionReportInfo& report_info); - // Add and remove observers. These methods must be invoked on the UI thread. - void AddObserver(Observer* observer); - void RemoveObserver(Observer* remove); - // Creates the whitelist URL set for tests that create a blocking page // themselves and then simulate OnBlockingPageDone(). OnBlockingPageDone() // expects the whitelist to exist, but the tests don't necessarily call @@ -143,16 +80,15 @@ static void CreateWhitelistForTesting(content::WebContents* web_contents); protected: - virtual ~SafeBrowsingUIManager(); - - private: - friend class base::RefCountedThreadSafe<SafeBrowsingUIManager>; - friend class SafeBrowsingUIManagerTest; - friend class TestSafeBrowsingUIManager; + ~SafeBrowsingUIManager() override; // Call protocol manager on IO thread to report hits of unsafe contents. void ReportSafeBrowsingHitOnIOThread( - const safe_browsing::HitReport& hit_report); + const safe_browsing::HitReport& hit_report) override; + + private: + friend class SafeBrowsingUIManagerTest; + friend class TestSafeBrowsingUIManager; // Sends an invalid certificate chain report over the network. void ReportInvalidCertificateChainOnIOThread( @@ -162,25 +98,12 @@ void ReportPermissionActionOnIOThread( const PermissionReportInfo& report_info); - // Updates the whitelist URL set for |web_contents|. Called on the UI thread. - void AddToWhitelistUrlSet(const GURL& whitelist_url, - content::WebContents* web_contents, - bool is_pending, - SBThreatType threat_type); - - // Removes |whitelist_url| from the pending whitelist for - // |web_contents|. Called on the UI thread. - void RemoveFromPendingWhitelistUrlSet(const GURL& whitelist_url, - content::WebContents* web_contents); - static GURL GetMainFrameWhitelistUrlForResourceForTesting( const safe_browsing::SafeBrowsingUIManager::UnsafeResource& resource); // Safebrowsing service. scoped_refptr<SafeBrowsingService> sb_service_; - base::ObserverList<Observer> observer_list_; - DISALLOW_COPY_AND_ASSIGN(SafeBrowsingUIManager); };
diff --git a/chrome/browser/search_engines/template_url_service_android.cc b/chrome/browser/search_engines/template_url_service_android.cc index c3c9add..d795ba5 100644 --- a/chrome/browser/search_engines/template_url_service_android.cc +++ b/chrome/browser/search_engines/template_url_service_android.cc
@@ -125,7 +125,6 @@ return Java_TemplateUrl_create( env, index, base::android::ConvertUTF16ToJavaString(env, template_url->short_name()), - base::android::ConvertUTF8ToJavaString(env, template_url->url()), template_url_service_->IsPrepopulatedOrCreatedByPolicy(template_url), base::android::ConvertUTF16ToJavaString(env, template_url->keyword())); }
diff --git a/chrome/browser/test_presubmit.py b/chrome/browser/test_presubmit.py index 4509bacd..796a90ad 100755 --- a/chrome/browser/test_presubmit.py +++ b/chrome/browser/test_presubmit.py
@@ -5,14 +5,12 @@ """Unit test runner for Web Development Style Guide checks.""" -from web_dev_style import closure_lint_test, \ - css_checker_test, \ +from web_dev_style import css_checker_test, \ html_checker_test, \ js_checker_test, \ resource_checker_test _TEST_MODULES = [ - closure_lint_test, css_checker_test, html_checker_test, js_checker_test,
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h index 1d3a1030..98205d5 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h
@@ -177,6 +177,8 @@ bool ShouldShowEVBubble() const; + bool ShouldShowExtensionBubble() const; + // Returns true if the security state decoration should be displayed. The // security state should only be shown for valid and invalid HTTPS states. bool ShouldShowSecurityState() const;
diff --git a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm index 7e0308f..08f552b 100644 --- a/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm +++ b/chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.mm
@@ -458,8 +458,9 @@ // displayed, even if the width is narrow. CGFloat available_width = [cell availableWidthInFrame:[[cell controlView] frame]]; - is_width_available_for_security_verbose_ = - available_width >= kMinURLWidth || ShouldShowEVBubble(); + is_width_available_for_security_verbose_ = available_width >= kMinURLWidth || + ShouldShowEVBubble() || + ShouldShowExtensionBubble(); if (!keyword.empty() && !is_keyword_hint) { // Switch from location icon to keyword mode. @@ -482,6 +483,15 @@ base::string16 label(GetToolbarModel()->GetEVCertName()); security_state_bubble_decoration_->SetFullLabel( base::SysUTF16ToNSString(label)); + } else if (ShouldShowExtensionBubble()) { + // Switch from location icon to show the extension bubble instead. + location_icon_decoration_->SetVisible(false); + security_state_bubble_decoration_->SetVisible(true); + + base::string16 label( + GetExtensionName(GetToolbarModel()->GetURL(), GetWebContents())); + security_state_bubble_decoration_->SetFullLabel( + base::SysUTF16ToNSString(label)); } else if (ShouldShowSecurityState() || security_state_bubble_decoration_->AnimatingOut()) { bool is_security_state_visible = @@ -652,6 +662,11 @@ security_state::EV_SECURE; } +bool LocationBarViewMac::ShouldShowExtensionBubble() const { + return !GetOmniboxView()->IsEditingOrEmpty() && + GetToolbarModel()->GetURL().SchemeIs(extensions::kExtensionScheme); +} + bool LocationBarViewMac::ShouldShowSecurityState() const { if (omnibox_view_->IsEditingOrEmpty() || omnibox_view_->model()->is_keyword_hint()) { @@ -860,7 +875,8 @@ // out, animate it back in. Otherwise, if the security state has changed, // animate the decoration if animation is enabled and the state changed is // not from a tab switch. - if (ShouldShowSecurityState() && is_width_available_for_security_verbose_) { + if ((ShouldShowSecurityState() || ShouldShowExtensionBubble()) && + is_width_available_for_security_verbose_) { bool is_secure_to_secure = IsSecureConnection(new_security_level) && IsSecureConnection(security_level_); bool is_new_security_level =
diff --git a/chrome/browser/ui/location_bar/location_bar.cc b/chrome/browser/ui/location_bar/location_bar.cc index 81b37242..f01caef 100644 --- a/chrome/browser/ui/location_bar/location_bar.cc +++ b/chrome/browser/ui/location_bar/location_bar.cc
@@ -4,9 +4,13 @@ #include "chrome/browser/ui/location_bar/location_bar.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/manifest_handlers/ui_overrides_handler.h" +#include "content/public/browser/web_contents.h" #include "extensions/browser/extension_registry.h" +#include "extensions/common/constants.h" #include "extensions/common/extension_set.h" #include "extensions/common/feature_switch.h" #include "extensions/common/permissions/permissions_data.h" @@ -32,3 +36,21 @@ return false; } + +// static +base::string16 LocationBar::GetExtensionName( + const GURL& url, + content::WebContents* web_contents) { + CHECK(web_contents); + if (!url.SchemeIs(extensions::kExtensionScheme)) + return base::string16(); + + content::BrowserContext* browser_context = web_contents->GetBrowserContext(); + extensions::ExtensionRegistry* extension_registry = + extensions::ExtensionRegistry::Get(browser_context); + const extensions::Extension* extension = + extension_registry->enabled_extensions().GetByID(url.host()); + return extension ? base::CollapseWhitespace( + base::UTF8ToUTF16(extension->name()), false) + : base::string16(); +}
diff --git a/chrome/browser/ui/location_bar/location_bar.h b/chrome/browser/ui/location_bar/location_bar.h index 2cdd713..ad2b220 100644 --- a/chrome/browser/ui/location_bar/location_bar.h +++ b/chrome/browser/ui/location_bar/location_bar.h
@@ -100,6 +100,12 @@ // Checks if any extension has requested that the bookmark star be hidden. bool IsBookmarkStarHiddenByExtension() const; + // If |url| is an extension URL, returns the name of the associated extension, + // with whitespace collapsed. Otherwise, returns empty string. |web_contents| + // is used to get at the extension registry. + static base::string16 GetExtensionName(const GURL& url, + content::WebContents* web_contents); + private: Profile* profile_;
diff --git a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc index 85348ed..538bc43b 100644 --- a/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc +++ b/chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.cc
@@ -66,9 +66,7 @@ ChromeBrowserMainExtraPartsViewsLinux:: ~ChromeBrowserMainExtraPartsViewsLinux() { - // X11DesktopHandler is destructed at this point, so we don't need to remove - // ourselves as an X11DesktopHandlerObserver - DCHECK(!aura::Env::GetInstanceDontCreate()); + views::X11DesktopHandler::get()->RemoveObserver(this); } void ChromeBrowserMainExtraPartsViewsLinux::PreEarlyInitialization() {
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index fea3325..463bb66 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -456,10 +456,10 @@ int leading_width = edge_thickness; if (ShouldShowKeywordBubble()) { // The selected keyword view can collapse completely. - } else if (ShouldShowSecurityChip()) { - base::string16 security_text = GetSecurityText(); + } else if (ShouldShowLocationIconText()) { leading_width += - location_icon_view_->GetMinimumSizeForLabelText(security_text).width(); + location_icon_view_->GetMinimumSizeForLabelText(GetLocationIconText()) + .width(); } else { leading_width += kHorizontalPadding + location_icon_view_->GetMinimumSize().width(); @@ -530,8 +530,8 @@ selected_keyword_view_->ResetImage(); } } - } else if (ShouldShowSecurityChip()) { - location_icon_view_->SetLabel(GetSecurityText()); + } else if (ShouldShowLocationIconText()) { + location_icon_view_->SetLabel(GetLocationIconText()); // The largest fraction of the omnibox that can be taken by the EV bubble. const double kMaxBubbleFraction = 0.5; leading_decorations.AddDecoration(vertical_padding, location_height, false, @@ -660,9 +660,9 @@ else omnibox_view_->Update(); - location_icon_view_->SetSecurityState( - ShouldShowSecurityChip(), !contents && ShouldAnimateSecurityChip()); - + location_icon_view_->SetTextVisibility( + ShouldShowLocationIconText(), + !contents && ShouldAnimateLocationIconTextVisibilityChange()); OnChanged(); // NOTE: Calls Layout(). } @@ -879,7 +879,12 @@ #endif } -base::string16 LocationBarView::GetSecurityText() const { +base::string16 LocationBarView::GetLocationIconText() const { + const base::string16 extension_name = GetExtensionName( + GetToolbarModel()->GetURL(), delegate_->GetWebContents()); + if (!extension_name.empty()) + return extension_name; + bool has_ev_cert = (GetToolbarModel()->GetSecurityLevel(false) == security_state::EV_SECURE); return has_ev_cert ? GetToolbarModel()->GetEVCertName() @@ -891,7 +896,11 @@ !omnibox_view_->model()->is_keyword_hint(); } -bool LocationBarView::ShouldShowSecurityChip() const { +bool LocationBarView::ShouldShowLocationIconText() const { + if (!GetOmniboxView()->IsEditingOrEmpty() && + GetToolbarModel()->GetURL().SchemeIs(extensions::kExtensionScheme)) + return true; + using SecurityLevel = security_state::SecurityLevel; const SecurityLevel level = GetToolbarModel()->GetSecurityLevel(false); return level == SecurityLevel::EV_SECURE || level == SecurityLevel::SECURE || @@ -899,7 +908,9 @@ level == SecurityLevel::HTTP_SHOW_WARNING; } -bool LocationBarView::ShouldAnimateSecurityChip() const { +bool LocationBarView::ShouldAnimateLocationIconTextVisibilityChange() const { + // Text for extension URLs should not be animated (their security level is + // SecurityLevel::NONE). using SecurityLevel = security_state::SecurityLevel; SecurityLevel level = GetToolbarModel()->GetSecurityLevel(false); return level == SecurityLevel::DANGEROUS ||
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index 44248e05..599d2c3 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -311,18 +311,21 @@ // Helper to show the first run info bubble. void ShowFirstRunBubbleInternal(); - // Returns text describing the URL's security level, to be placed in the - // security chip. - base::string16 GetSecurityText() const; + // Returns text to be placed in the location icon view. + // - For secure/insecure pages, returns text describing the URL's security + // level. + // - For extension URLs, returns the extension name. + base::string16 GetLocationIconText() const; bool ShouldShowKeywordBubble() const; - // Returns true when the current page is explicitly secure or insecure. - // In these cases, we should show the state of the security chip. - bool ShouldShowSecurityChip() const; + // Returns true if any of the following is true: + // - the current page is explicitly secure or insecure. + // - the current page URL is a chrome-extension:// URL. + bool ShouldShowLocationIconText() const; - // Returns true if the chip should be animated - bool ShouldAnimateSecurityChip() const; + // Returns true if the location icon text should be animated. + bool ShouldAnimateLocationIconTextVisibilityChange() const; // Used to "reverse" the URL showing/hiding animations, since we use separate // animations whose curves are not true inverses of each other. Based on the
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view.cc b/chrome/browser/ui/views/location_bar/location_icon_view.cc index f3dfc1a..92e6e2d 100644 --- a/chrome/browser/ui/views/location_bar/location_icon_view.cc +++ b/chrome/browser/ui/views/location_bar/location_icon_view.cc
@@ -136,7 +136,8 @@ GetSizeForLabelWidth(label.GetPreferredSize().width())); } -void LocationIconView::SetSecurityState(bool should_show, bool should_animate) { +void LocationIconView::SetTextVisibility(bool should_show, + bool should_animate) { if (!should_animate) { animation_.Reset(should_show); } else if (should_show) {
diff --git a/chrome/browser/ui/views/location_bar/location_icon_view.h b/chrome/browser/ui/views/location_bar/location_icon_view.h index a16501df..ac08368 100644 --- a/chrome/browser/ui/views/location_bar/location_icon_view.h +++ b/chrome/browser/ui/views/location_bar/location_icon_view.h
@@ -18,7 +18,8 @@ // Use a LocationIconView to display an icon on the leading side of the edit // field. It shows the user's current action (while the user is editing), or the -// page security status (after navigation has completed). +// page security status (after navigation has completed), or extension name (if +// the URL is a chrome-extension:// URL). class LocationIconView : public IconLabelBubbleView, public gfx::AnimationDelegate { public: @@ -46,10 +47,9 @@ const gfx::FontList& GetFontList() const { return font_list(); } - // Sets whether the verbose security state text should be visible. - // |should_animate| controls whether any necessary transition to this state - // should be animated. - void SetSecurityState(bool should_show, bool should_animate); + // Sets whether the text should be visible. |should_animate| controls whether + // any necessary transition to this state should be animated. + void SetTextVisibility(bool should_show, bool should_animate); private: // IconLabelBubbleView:
diff --git a/chrome/browser/web_dev_style/closure_lint_test.py b/chrome/browser/web_dev_style/closure_lint_test.py deleted file mode 100755 index d509d57..0000000 --- a/chrome/browser/web_dev_style/closure_lint_test.py +++ /dev/null
@@ -1,90 +0,0 @@ -#!/usr/bin/env python -# Copyright 2015 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 js_checker -from os import path as os_path -import re -from sys import path as sys_path -import unittest - -_HERE = os_path.dirname(os_path.abspath(__file__)) -sys_path.append(os_path.join(_HERE, '..', '..', '..', 'build')) - -import find_depot_tools # pylint: disable=W0611 -from testing_support.super_mox import SuperMoxTestBase - - -class ClosureLintTest(SuperMoxTestBase): - def setUp(self): - SuperMoxTestBase.setUp(self) - - input_api = self.mox.CreateMockAnything() - input_api.os_path = os_path - input_api.re = re - - input_api.change = self.mox.CreateMockAnything() - self.mox.StubOutWithMock(input_api.change, 'RepositoryRoot') - src_root = os_path.join(os_path.dirname(__file__), '..', '..', '..') - input_api.change.RepositoryRoot().MultipleTimes().AndReturn(src_root) - - output_api = self.mox.CreateMockAnything() - - self.mox.ReplayAll() - - self.checker = js_checker.JSChecker(input_api, output_api) - - def ShouldPassClosureLint(self, source): - errors = self.checker.ClosureLint('', source=source) - - for error in errors: - print 'Error: ' + error.message - - self.assertListEqual([], errors) - - def testBindFalsePositives(self): - sources = [ - [ - 'var addOne = function(prop) {\n', - ' this[prop] += 1;\n', - '}.bind(counter, timer);\n', - '\n', - 'setInterval(addOne, 1000);\n', - '\n', - ], - [ - '/** Da clickz. */\n', - 'button.onclick = function() { this.add_(this.total_); }.bind(this);\n', - ], - ] - for source in sources: - self.ShouldPassClosureLint(source) - - def testPromiseFalsePositives(self): - sources = [ - [ - 'Promise.reject(1).catch(function(error) {\n', - ' alert(error);\n', - '});\n', - ], - [ - 'var loaded = new Promise();\n', - 'loaded.then(runAwesomeApp);\n', - 'loaded.catch(showSadFace);\n', - '\n', - '/** Da loadz. */\n', - 'document.onload = function() { loaded.resolve(); };\n', - '\n', - '/** Da errorz. */\n', - 'document.onerror = function() { loaded.reject(); };\n', - '\n', - "if (document.readystate == 'complete') loaded.resolve();\n", - ], - ] - for source in sources: - self.ShouldPassClosureLint(source) - - -if __name__ == '__main__': - unittest.main()
diff --git a/chrome/browser/web_dev_style/js_checker.py b/chrome/browser/web_dev_style/js_checker.py index d3306a94..d9c8888 100644 --- a/chrome/browser/web_dev_style/js_checker.py +++ b/chrome/browser/web_dev_style/js_checker.py
@@ -112,101 +112,6 @@ else: return self.output_api.PresubmitPromptWarning(error_text) - def ClosureLint(self, file_to_lint, source=None): - """Lints |file_to_lint| and returns the errors.""" - - import sys - import warnings - old_path = sys.path - old_filters = warnings.filters - - try: - closure_linter_path = self.input_api.os_path.join( - self.input_api.change.RepositoryRoot(), - "third_party", - "closure_linter") - gflags_path = self.input_api.os_path.join( - self.input_api.change.RepositoryRoot(), - "third_party", - "python_gflags") - - sys.path.insert(0, closure_linter_path) - sys.path.insert(0, gflags_path) - - warnings.filterwarnings('ignore', category=DeprecationWarning) - - from closure_linter import errors, runner - from closure_linter.common import errorhandler - import gflags - - finally: - sys.path = old_path - warnings.filters = old_filters - - class ErrorHandlerImpl(errorhandler.ErrorHandler): - """Filters out errors that don't apply to Chromium JavaScript code.""" - - def __init__(self, re): - self._errors = [] - self.re = re - - def HandleFile(self, filename, first_token): - self._filename = filename - - def HandleError(self, error): - if (self._valid(error)): - error.filename = self._filename - self._errors.append(error) - - def GetErrors(self): - return self._errors - - def HasErrors(self): - return bool(self._errors) - - def _valid(self, error): - """Check whether an error is valid. Most errors are valid, with a few - exceptions which are listed here. - """ - - is_grit_statement = bool( - self.re.search("</?(include|if)", error.token.line)) - - # Ignore missing spaces before "(" until Promise#catch issue is solved. - # http://crbug.com/338301 - if (error.code == errors.MISSING_SPACE and error.token.string == '(' and - 'catch(' in error.token.line): - return False - - # Ignore "}.bind(" errors. http://crbug.com/397697 - if (error.code == errors.MISSING_SEMICOLON_AFTER_FUNCTION and - '}.bind(' in error.token.line): - return False - - return not is_grit_statement and error.code not in [ - errors.COMMA_AT_END_OF_LITERAL, - errors.JSDOC_ILLEGAL_QUESTION_WITH_PIPE, - errors.LINE_TOO_LONG, - errors.MISSING_JSDOC_TAG_THIS, - ] - - # Keep this in sync with third_party/closure_compiler/closure_args.gypi - gflags.FLAGS.custom_jsdoc_tags = ( - 'abstract', - 'attribute', - 'default', - 'demo', - 'element', - 'group', - 'hero', - 'polymerBehavior', - 'status', - 'submodule', - ) - error_handler = ErrorHandlerImpl(self.input_api.re) - runner.Run(file_to_lint, error_handler, source=source) - return error_handler.GetErrors() - def RunChecks(self): """Check for violations of the Chromium JavaScript style guide. See http://chromium.org/developers/web-development-style-guide#TOC-JavaScript @@ -238,21 +143,6 @@ self.VarNameCheck(i, line), ]) - # Use closure linter to check for several different errors. - lint_errors = self.ClosureLint(self.input_api.os_path.join( - self.input_api.change.RepositoryRoot(), f.LocalPath())) - - for error in lint_errors: - highlight = self._GetErrorHighlight( - error.token.start_index, error.token.length) - error_msg = ' line %d: E%04d: %s\n%s\n%s' % ( - error.token.line_number, - error.code, - error.message, - error.token.line.rstrip(), - highlight) - error_lines.append(error_msg) - if error_lines: error_lines = [ 'Found JavaScript style violations in %s:' %
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 8bd7fc3e..f07bb46e 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1521,6 +1521,7 @@ "../browser/extensions/lazy_background_page_apitest.cc", "../browser/extensions/lazy_background_page_test_util.h", "../browser/extensions/mutation_observers_apitest.cc", + "../browser/extensions/native_bindings_apitest.cc", "../browser/extensions/options_page_apitest.cc", "../browser/extensions/page_action_browsertest.cc", "../browser/extensions/process_management_browsertest.cc",
diff --git a/chrome/test/data/extensions/api_test/native_bindings/background.html b/chrome/test/data/extensions/api_test/native_bindings/background.html new file mode 100644 index 0000000..7315f00 --- /dev/null +++ b/chrome/test/data/extensions/api_test/native_bindings/background.html
@@ -0,0 +1,2 @@ +<!doctype html> +<script src="background.js"></script>
diff --git a/chrome/test/data/extensions/api_test/native_bindings/background.js b/chrome/test/data/extensions/api_test/native_bindings/background.js new file mode 100644 index 0000000..9ec8032c --- /dev/null +++ b/chrome/test/data/extensions/api_test/native_bindings/background.js
@@ -0,0 +1,40 @@ +// Copyright 2016 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. + +if (!chrome || !chrome.test) + throw new Error('chrome.test is undefined'); + +// This is a good end-to-end test for two reasons. The first is obvious - it +// tests a simple API and makes sure it behaves as expected, as well as testing +// that other APIs are unavailable. +// The second is that chrome.test is itself an extension API, and a rather +// complex one. It requires both traditional bindings (renderer parses args, +// passes info to browser process, browser process does work and responds, re- +// enters JS) and custom JS bindings (in order to have our runTests, assert* +// methods, etc). If any of these stages failed, the test itself would also +// fail. +chrome.test.runTests([ + function idleApi() { + chrome.test.assertTrue(!!chrome.idle); + chrome.test.assertTrue(!!chrome.idle.queryState); + chrome.idle.queryState(1000, function(state) { + // Depending on the machine, this could come back as either idle or + // active. However, all we're curious about is the bindings themselves + // (not the API implementation), so as long as it's a possible response, + // it's a success for our purposes. + // TODO(devlin): Update this to use chrome.idle.IdleState.[ACTIVE|IDLE] + // when we have enums in native bindings. + chrome.test.assertTrue(state == 'idle' || state == 'active', state); + chrome.test.succeed(); + }); + }, + function nonexistentApi() { + chrome.test.assertFalse(!!chrome.nonexistent); + chrome.test.succeed(); + }, + function disallowedApi() { + chrome.test.assertFalse(!!chrome.power); + chrome.test.succeed(); + }, +]);
diff --git a/chrome/test/data/extensions/api_test/native_bindings/manifest.json b/chrome/test/data/extensions/api_test/native_bindings/manifest.json new file mode 100644 index 0000000..ba356ae --- /dev/null +++ b/chrome/test/data/extensions/api_test/native_bindings/manifest.json
@@ -0,0 +1,11 @@ +{ + "name": "Simple e2e", + "description": "A simple e2e test for native bindings", + "manifest_version": 2, + "version": "0.1", + "permissions": ["idle"], + "background": { + "persistent": false, + "page": "background.html" + } +}
diff --git a/chrome/test/data/extensions/api_test/window_update/resize/test.js b/chrome/test/data/extensions/api_test/window_update/resize/test.js index ce2ad93..87647fb 100644 --- a/chrome/test/data/extensions/api_test/window_update/resize/test.js +++ b/chrome/test/data/extensions/api_test/window_update/resize/test.js
@@ -53,7 +53,7 @@ chrome.test.runTests([ // Tests windows.update use of the chrome.windows.WINDOW_ID_CURRENT constant. function testCurrentWindowResize() { - var newWidth = 400; + var newWidth = 500; chrome.windows.create( { 'url': 'blank.html', 'top': 0, 'left': 0, 'width': 500, 'height': 400, 'type': 'normal' },
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js index 2011f39..6a830706 100644 --- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js +++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -116,25 +116,6 @@ mocha.run(); }); -function CrElementsSharedMenuTest() {} - -CrElementsSharedMenuTest.prototype = { - __proto__: CrElementsBrowserTest.prototype, - - /** @override */ - browsePreload: - 'chrome://resources/cr_elements/cr_shared_menu/cr_shared_menu.html', - - /** @override */ - extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - 'cr_shared_menu_tests.js' - ]), -}; - -TEST_F('CrElementsSharedMenuTest', 'All', function() { - mocha.run(); -}); - function CrElementsActionMenuTest() {} CrElementsActionMenuTest.prototype = {
diff --git a/chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js b/chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js deleted file mode 100644 index 7b18a7a..0000000 --- a/chrome/test/data/webui/cr_elements/cr_shared_menu_tests.js +++ /dev/null
@@ -1,240 +0,0 @@ -// Copyright 2016 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. - -/** @fileoverview Suite of tests for cr-shared-menu. */ -suite('cr-shared-menu', function() { - var menu; - - var button; - var button2; - - var items = []; - - function afterOpen(callback) { - listenOnce(menu, 'iron-overlay-opened', function () { - // paper-listbox applies focus after opening with microtask timing. - // Delay until that has happened: - setTimeout(callback, 0); - }); - } - - function afterClose(callback) { - listenOnce(menu, 'iron-overlay-closed', () => callback()); - } - - suiteSetup(function() { - return PolymerTest.importHtml( - 'chrome://resources/polymer/v1_0/paper-item/paper-item.html'); - }); - - setup(function() { - PolymerTest.clearBody(); - // Basic wiring to set up an empty menu that opens when a button is pressed. - menu = document.createElement('cr-shared-menu'); - menu.$$('#dropdown').noAnimations = true; - - button = document.createElement('button'); - button.addEventListener('tap', function(e) { - menu.toggleMenu(button, {}); - e.stopPropagation(); // Prevent 'tap' from closing the dialog. - }); - - button2 = document.createElement('button'); - button2.addEventListener('tap', function(e) { - menu.toggleMenu(button2, {}); - e.stopPropagation(); // Prevent 'tap' from closing the dialog. - }); - - document.body.appendChild(menu); - document.body.appendChild(button); - document.body.appendChild(button2); - }); - - suite('basic', function() { - setup(function() { - // Populate the menu with paper-items. - for (var i = 0; i < 3; i++) { - items[i] = document.createElement('paper-item'); - menu.appendChild(items[i]); - } - }); - - test('opening and closing menu', function(done) { - MockInteractions.tap(button); - assertTrue(menu.menuOpen); - - afterOpen(function() { - // Using tap to close the menu requires that the iron-overlay-behavior - // has finished initializing, which happens asynchronously between - // tapping the button and firing iron-overlay-opened. - MockInteractions.tap(document.body); - assertFalse(menu.menuOpen); - - done(); - }); - }); - - test('open and close menu with escape', function(done) { - MockInteractions.tap(button); - assertTrue(menu.menuOpen); - afterOpen(function() { - // Pressing escape should close the menu. - MockInteractions.pressAndReleaseKeyOn(menu, 27); - assertFalse(menu.menuOpen); - done(); - }); - }); - - test('refocus button on close', function(done) { - button.focus(); - MockInteractions.tap(button); - - afterOpen(function() { - assertTrue(menu.menuOpen); - // Focus is applied asynchronously after the menu is opened. - assertEquals(items[0], menu.shadowRoot.activeElement); - - menu.closeMenu(); - - afterClose(function() { - assertFalse(menu.menuOpen); - // Button should regain focus after closing the menu. - assertEquals(button, document.activeElement); - done(); - }); - - }); - }); - - test('refocus latest button on close', function(done) { - // Regression test for crbug.com/628080. - button.focus(); - MockInteractions.tap(button); - - afterOpen(function() { - button2.focus(); - MockInteractions.tap(button2); - - afterOpen(function() { - menu.closeMenu(); - afterClose(function() { - assertEquals(button2, document.activeElement); - done(); - }); - }); - }); - }); - - test('closeMenu does not refocus button when focus moves', function(done) { - var input = document.createElement('input'); - document.body.appendChild(input); - - button.focus(); - MockInteractions.tap(button); - - afterOpen(function() { - input.focus(); - menu.closeMenu(); - - afterClose(function() { - assertEquals(input, document.activeElement); - done(); - }); - }); - }); - - test('tab closes menu', function(done) { - button.focus(); - MockInteractions.tap(button); - - afterOpen(function() { - MockInteractions.pressAndReleaseKeyOn(items[0], 9); - afterClose(function() { - // Focus should move to a different element, but we can't simulate - // the right events to test this. - done(); - }); - }); - }); - - test('shift-tab closes menu', function(done) { - button.focus(); - MockInteractions.tap(button); - - afterOpen(function() { - MockInteractions.pressAndReleaseKeyOn(items[0], 9, ['shift']); - afterClose(done); - }); - }); - - test('up and down change focus', function(done) { - button.focus(); - MockInteractions.tap(button); - - afterOpen(function() { - // Pressing down on first item goes to second item. - assertEquals(items[0], document.activeElement); - MockInteractions.pressAndReleaseKeyOn(items[0], 40); - assertEquals(items[1], document.activeElement); - - // Pressing down twice more cycles back to first item. - MockInteractions.pressAndReleaseKeyOn(items[1], 40); - MockInteractions.pressAndReleaseKeyOn(items[2], 40); - assertEquals(items[0], document.activeElement); - - // Pressing up cycles to last item. - MockInteractions.pressAndReleaseKeyOn(items[0], 38); - assertEquals(items[2], document.activeElement); - - done(); - }); - }); - }); - - suite('different item types', function() { - setup(function() { - // Populate the menu with tabbable and untabbable items. - items[0] = document.createElement('paper-item'); - items[0].disabled = true; - menu.appendChild(items[0]); - - items[1] = document.createElement('paper-item'); - menu.appendChild(items[1]); - - items[2] = document.createElement('button'); - menu.appendChild(items[2]); - - items[3] = document.createElement('button'); - items[3].disabled = true; - menu.appendChild(items[3]); - - items[4] = document.createElement('paper-item'); - items[4].hidden = true; - menu.appendChild(items[4]); - }); - - test('focus does not start/end with untabbable elements', function(done) { - button.focus(); - MockInteractions.tap(button); - - afterOpen(function() { - // The first item is disabled, so the second item is the first tabbable - // item and should be focusced. - assertEquals(items[1], menu.shadowRoot.activeElement); - - // The last two items are disabled or hidden, so they should be skipped - // when pressing up. - MockInteractions.pressAndReleaseKeyOn(items[1], 38); - assertEquals(items[2], menu.shadowRoot.activeElement); - - // Simulate pressing down on last focusable element to wrap to first - // focusable element. - MockInteractions.pressAndReleaseKeyOn(items[2], 40); - assertEquals(items[1], menu.shadowRoot.activeElement); - - done(); - }); - }); - }); -});
diff --git a/chrome/test/data/webui/md_history/history_list_test.js b/chrome/test/data/webui/md_history/history_list_test.js index 687cd09..c270983 100644 --- a/chrome/test/data/webui/md_history/history_list_test.js +++ b/chrome/test/data/webui/md_history/history_list_test.js
@@ -273,24 +273,6 @@ }); }); - test('scrolling history list closes overflow menu', function() { - var lazyMenu = app.$.history.$.sharedMenu; - for (var i = 0; i < 10; i++) - app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS); - return PolymerTest.flushTasks().then(function() { - items = polymerSelectAll(element, 'history-item'); - - MockInteractions.tap(items[2].$['menu-button']); - return PolymerTest.flushTasks(); - }).then(function() { - assertTrue(lazyMenu.getIfExists().menuOpen); - element.$['infinite-list'].scrollToIndex(20); - return waitForEvent(lazyMenu.getIfExists(), 'menu-open-changed'); - }).then(function() { - assertFalse(lazyMenu.getIfExists().menuOpen); - }); - }); - // TODO(calamity): Reenable this test after fixing flakiness. // See http://crbug.com/640862. test.skip('scrolling history list causes toolbar shadow to appear',
diff --git a/chrome/test/data/webui/md_history/history_metrics_test.js b/chrome/test/data/webui/md_history/history_metrics_test.js index c9c6e80..a708454 100644 --- a/chrome/test/data/webui/md_history/history_metrics_test.js +++ b/chrome/test/data/webui/md_history/history_metrics_test.js
@@ -151,6 +151,7 @@ test('synced-device-manager', function() { app.selectedPage_ = 'syncedTabs'; var histogram; + var menuButton; return PolymerTest.flushTasks().then(() => { histogram = histogramMap[SYNCED_TABS_HISTOGRAM_NAME]; assertEquals(1, histogram[SyncedTabsHistogram.INITIALIZED]); @@ -183,12 +184,16 @@ MockInteractions.tap(polymerSelectAll(cards[0], '.website-title')[0]); assertEquals(1, histogram[SyncedTabsHistogram.LINK_CLICKED]); - MockInteractions.tap(cards[0].$['menu-button']); + menuButton = cards[0].$['menu-button']; + MockInteractions.tap(menuButton); return PolymerTest.flushTasks(); }).then(() => { MockInteractions.tap(app.$$('#synced-devices').$$('#menuOpenButton')); assertEquals(1, histogram[SyncedTabsHistogram.OPEN_ALL]); + MockInteractions.tap(menuButton); + return PolymerTest.flushTasks(); + }).then(() => { MockInteractions.tap(app.$$('#synced-devices').$$('#menuDeleteButton')); assertEquals(1, histogram[SyncedTabsHistogram.HIDE_FOR_NOW]); });
diff --git a/chrome/test/data/webui/md_history/history_overflow_menu_test.js b/chrome/test/data/webui/md_history/history_overflow_menu_test.js index 5f407a07..6dc4a4a 100644 --- a/chrome/test/data/webui/md_history/history_overflow_menu_test.js +++ b/chrome/test/data/webui/md_history/history_overflow_menu_test.js
@@ -2,74 +2,45 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Menu button event. -var MENU_EVENT = { - detail: { - target: null - } -}; - -var ADDITIONAL_MENU_EVENT = { - detail: { - target: null - } -}; - suite('#overflow-menu', function() { - var app; var listContainer; var sharedMenu; + var target1; + var target2; + suiteSetup(function() { - app = $('history-app'); + var app = $('history-app'); listContainer = app.$['history']; var element1 = document.createElement('div'); var element2 = document.createElement('div'); document.body.appendChild(element1); document.body.appendChild(element2); - MENU_EVENT.detail.target = element1; - ADDITIONAL_MENU_EVENT.detail.target = element2; + target1 = element1; + target2 = element2; sharedMenu = listContainer.$.sharedMenu.get(); }); test('opening and closing menu', function() { - listContainer.toggleMenu_(MENU_EVENT); - assertTrue(sharedMenu.menuOpen); - assertEquals(MENU_EVENT.detail.target, sharedMenu.lastAnchor_); + var detail1 = {target: target1}; + listContainer.fire('open-menu', detail1); + assertTrue(sharedMenu.open); + assertEquals(detail1, listContainer.actionMenuModel_); - // Test having the same menu event (pressing the same button) closes - // the overflow menu. - listContainer.toggleMenu_(MENU_EVENT); - assertFalse(sharedMenu.menuOpen); + sharedMenu.close(); + assertFalse(sharedMenu.open); - // Test having consecutive distinct menu events moves the menu to the - // new button. - listContainer.toggleMenu_(MENU_EVENT); - listContainer.toggleMenu_(ADDITIONAL_MENU_EVENT); - assertEquals(ADDITIONAL_MENU_EVENT.detail.target, sharedMenu.lastAnchor_); - assertTrue(sharedMenu.menuOpen); + var detail2 = {target: target2}; + listContainer.fire('open-menu', detail2); + assertEquals(detail2, listContainer.actionMenuModel_); + assertTrue(sharedMenu.open); - listContainer.toggleMenu_(MENU_EVENT); - assertTrue(sharedMenu.menuOpen); - assertEquals(MENU_EVENT.detail.target, sharedMenu.lastAnchor_); - - sharedMenu.closeMenu(); - assertFalse(sharedMenu.menuOpen); - }); - - test('menu closes when search changes', function() { - var entry = - [createHistoryEntry('2016-07-19', 'https://www.nianticlabs.com')]; - - app.historyResult(createHistoryInfo(), entry); - listContainer.toggleMenu_(MENU_EVENT); - // Menu closes when search changes. - app.historyResult(createHistoryInfo('niantic'), entry); - assertFalse(sharedMenu.menuOpen); + sharedMenu.close(); + assertFalse(sharedMenu.open); }); teardown(function() { - sharedMenu.lastAnchor_ = null; + sharedMenu.actionMenuModel_ = null; }); });
diff --git a/chrome/test/data/webui/md_history/history_synced_tabs_test.js b/chrome/test/data/webui/md_history/history_synced_tabs_test.js index 69ecaf5..8336ae0 100644 --- a/chrome/test/data/webui/md_history/history_synced_tabs_test.js +++ b/chrome/test/data/webui/md_history/history_synced_tabs_test.js
@@ -345,7 +345,7 @@ return PolymerTest.flushTasks().then(function() { var cards = getCards(element); MockInteractions.tap(cards[0].$['menu-button']); - assertTrue(element.$.menu.getIfExists().menuOpen); + assertTrue(element.$.menu.getIfExists().open); }); });
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 7d9e4a3..8a80ee92 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -434,7 +434,7 @@ std::unique_ptr<base::Value> CastContentBrowserClient::GetServiceManifestOverlay( - const std::string& service_name) { + base::StringPiece service_name) { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); if (service_name != content::mojom::kBrowserServiceName) return nullptr;
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 0ed31c1..6df56aa50 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -154,7 +154,7 @@ content::RenderProcessHost* render_process_host) override; void RegisterInProcessServices(StaticServiceMap* services) override; std::unique_ptr<base::Value> GetServiceManifestOverlay( - const std::string& service_name) override; + base::StringPiece service_name) override; #if defined(OS_ANDROID) void GetAdditionalMappedFilesForChildProcess( const base::CommandLine& command_line,
diff --git a/components/cronet/url_request_context_config.cc b/components/cronet/url_request_context_config.cc index 78497f7..b93bf3d 100644 --- a/components/cronet/url_request_context_config.cc +++ b/components/cronet/url_request_context_config.cc
@@ -22,8 +22,8 @@ #include "net/dns/host_resolver.h" #include "net/dns/mapped_host_resolver.h" #include "net/http/http_server_properties.h" +#include "net/quic/chromium/quic_utils_chromium.h" #include "net/quic/core/quic_packets.h" -#include "net/quic/core/quic_utils.h" #include "net/socket/ssl_client_socket.h" #include "net/url_request/url_request_context_builder.h" @@ -118,7 +118,7 @@ if (quic_args->GetString(kQuicConnectionOptions, &quic_connection_options)) { context_builder->set_quic_connection_options( - net::QuicUtils::ParseQuicConnectionOptions(quic_connection_options)); + net::ParseQuicConnectionOptions(quic_connection_options)); } // TODO(rtenneti): Delete this option after apps stop using it.
diff --git a/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashFileManagerTest.java b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashFileManagerTest.java index 1ad66f19..7ff1ee0 100644 --- a/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashFileManagerTest.java +++ b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashFileManagerTest.java
@@ -12,6 +12,7 @@ import android.test.MoreAsserts; import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import java.io.File; @@ -401,6 +402,7 @@ */ @SmallTest @Feature({"Android-AppBase"}) + @DisabledTest(message = "crbug.com/676429") public void testMinidumpStorageRestrictionsGlobal() throws IOException { testMinidumpStorageRestrictions(false /* perUid */); }
diff --git a/components/nacl/DEPS b/components/nacl/DEPS index a5b0e6ab..a5cd353 100644 --- a/components/nacl/DEPS +++ b/components/nacl/DEPS
@@ -2,4 +2,5 @@ "+content/public/common", "+ipc", "+mojo/public", + "+services/service_manager/public", ]
diff --git a/components/nacl/broker/BUILD.gn b/components/nacl/broker/BUILD.gn index 08e4489..3a2b360 100644 --- a/components/nacl/broker/BUILD.gn +++ b/components/nacl/broker/BUILD.gn
@@ -4,6 +4,7 @@ import("//build/config/features.gni") import("//build/config/compiler/compiler.gni") +import("//services/service_manager/public/service_manifest.gni") # This file builds nacl64.exe, which is a 64-bit x86 Windows executable # used only in the 32-bit x86 Windows build. The :broker code runs both @@ -29,6 +30,7 @@ "//ipc", "//mojo/edk/system", "//sandbox", + "//services/service_manager/public/cpp", ] if (current_cpu == target_cpu) { @@ -36,6 +38,10 @@ } else { deps += [ ":content_dummy" ] } + + data_deps = [ + ":nacl_broker_manifest", + ] } # This exists just to make 'gn check' happy with :broker. It can't depend @@ -169,3 +175,8 @@ ] } } + +service_manifest("nacl_broker_manifest") { + name = "nacl_broker" + source = "nacl_broker_manifest.json" +}
diff --git a/components/nacl/broker/OWNERS b/components/nacl/broker/OWNERS new file mode 100644 index 0000000..39ccc030 --- /dev/null +++ b/components/nacl/broker/OWNERS
@@ -0,0 +1,3 @@ +# Mojo manifests +per-file *manifest.json=set noparent +per-file *manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/components/nacl/broker/nacl_broker_listener.cc b/components/nacl/broker/nacl_broker_listener.cc index c928b001..6161d66 100644 --- a/components/nacl/broker/nacl_broker_listener.cc +++ b/components/nacl/broker/nacl_broker_listener.cc
@@ -19,6 +19,7 @@ #include "components/nacl/common/nacl_cmd_line.h" #include "components/nacl/common/nacl_debug_exception_handler_win.h" #include "components/nacl/common/nacl_messages.h" +#include "components/nacl/common/nacl_service.h" #include "components/nacl/common/nacl_switches.h" #include "content/public/common/content_switches.h" #include "content/public/common/mojo_channel_switches.h" @@ -28,6 +29,7 @@ #include "mojo/edk/embedder/platform_channel_pair.h" #include "mojo/public/cpp/system/message_pipe.h" #include "sandbox/win/src/sandbox_policy.h" +#include "services/service_manager/public/cpp/service_context.h" namespace { @@ -42,14 +44,12 @@ NaClBrokerListener::~NaClBrokerListener() = default; void NaClBrokerListener::Listen() { - mojo::ScopedMessagePipeHandle handle( - mojo::edk::CreateChildMessagePipe( - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kMojoChannelToken))); - DCHECK(handle.is_valid()); - IPC::ChannelHandle channel_handle(handle.release()); + mojo::ScopedMessagePipeHandle channel_handle; + std::unique_ptr<service_manager::ServiceContext> service_context = + CreateNaClServiceContext(base::ThreadTaskRunnerHandle::Get(), + &channel_handle); - channel_ = IPC::Channel::CreateClient(channel_handle, this); + channel_ = IPC::Channel::CreateClient(channel_handle.release(), this); CHECK(channel_->Connect()); run_loop_.Run(); } @@ -138,7 +138,7 @@ mojo::ScopedMessagePipeHandle host_message_pipe = mojo::edk::CreateParentMessagePipe(mojo_channel_token, mojo_child_token); - cmd_line->AppendSwitchASCII(switches::kMojoChannelToken, + cmd_line->AppendSwitchASCII(switches::kServiceRequestChannelToken, mojo_channel_token); CHECK_EQ(MOJO_RESULT_OK, mojo::FuseMessagePipes(std::move(loader_message_pipe),
diff --git a/components/nacl/broker/nacl_broker_manifest.json b/components/nacl/broker/nacl_broker_manifest.json new file mode 100644 index 0000000..8a56b79 --- /dev/null +++ b/components/nacl/broker/nacl_broker_manifest.json
@@ -0,0 +1,13 @@ +{ + "name": "nacl_broker", + "display_name": "NaCl broker", + "interface_provider_specs": { + "service_manager:connector": { + "provides": { + "browser": [ + "IPC::mojom::ChannelBootstrap" + ] + } + } + } +}
diff --git a/components/nacl/browser/nacl_broker_host_win.cc b/components/nacl/browser/nacl_broker_host_win.cc index 4b2e9a0..fb6cd81 100644 --- a/components/nacl/browser/nacl_broker_host_win.cc +++ b/components/nacl/browser/nacl_broker_host_win.cc
@@ -10,6 +10,7 @@ #include "components/nacl/browser/nacl_broker_service_win.h" #include "components/nacl/browser/nacl_browser.h" #include "components/nacl/common/nacl_cmd_line.h" +#include "components/nacl/common/nacl_constants.h" #include "components/nacl/common/nacl_messages.h" #include "components/nacl/common/nacl_process_type.h" #include "components/nacl/common/nacl_switches.h" @@ -47,17 +48,12 @@ } bool NaClBrokerHost::Init() { - const std::string mojo_child_token = mojo::edk::GenerateRandomToken(); DCHECK(!process_); process_.reset(content::BrowserChildProcessHost::Create( static_cast<content::ProcessType>(PROCESS_TYPE_NACL_BROKER), this, - mojo_child_token)); + kNaClBrokerServiceName)); - // Create the channel that will be used for communicating with the broker. - const std::string mojo_channel_token = - process_->GetHost()->CreateChannelMojo(mojo_child_token); - if (mojo_channel_token.empty()) - return false; + process_->GetHost()->CreateChannelMojo(); // Create the path to the nacl broker/loader executable. base::FilePath nacl_path; @@ -69,7 +65,6 @@ cmd_line->AppendSwitchASCII(switches::kProcessType, switches::kNaClBrokerProcess); - cmd_line->AppendSwitchASCII(switches::kMojoChannelToken, mojo_channel_token); if (NaClBrowser::GetDelegate()->DialogsAreSuppressed()) cmd_line->AppendSwitch(switches::kNoErrorDialogs);
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index f788ae4f..f8b4711 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc
@@ -37,6 +37,7 @@ #include "components/nacl/browser/nacl_browser_delegate.h" #include "components/nacl/browser/nacl_host_message_filter.h" #include "components/nacl/common/nacl_cmd_line.h" +#include "components/nacl/common/nacl_constants.h" #include "components/nacl/common/nacl_host_messages.h" #include "components/nacl/common/nacl_messages.h" #include "components/nacl/common/nacl_process_type.h" @@ -228,11 +229,10 @@ process_type_(process_type), profile_directory_(profile_directory), render_view_id_(render_view_id), - mojo_child_token_(mojo::edk::GenerateRandomToken()), weak_factory_(this) { process_.reset(content::BrowserChildProcessHost::Create( static_cast<content::ProcessType>(PROCESS_TYPE_NACL_LOADER), this, - mojo_child_token_)); + kNaClLoaderServiceName)); // Set the display name so the user knows what plugin the process is running. // We aren't on the UI thread so getting the pref locale for language @@ -500,15 +500,7 @@ } bool NaClProcessHost::LaunchSelLdr() { - DCHECK(!mojo_child_token_.empty()); - std::string mojo_channel_token = - process_->GetHost()->CreateChannelMojo(mojo_child_token_); - // |mojo_child_token_| is no longer used. - base::STLClearObject(&mojo_child_token_); - if (mojo_channel_token.empty()) { - SendErrorToRenderer("CreateChannelMojo() failed"); - return false; - } + process_->GetHost()->CreateChannelMojo(); // Build command line for nacl. @@ -566,7 +558,6 @@ (uses_nonsfi_mode_ ? switches::kNaClLoaderNonSfiProcess : switches::kNaClLoaderProcess)); - cmd_line->AppendSwitchASCII(switches::kMojoChannelToken, mojo_channel_token); if (NaClBrowser::GetDelegate()->DialogsAreSuppressed()) cmd_line->AppendSwitch(switches::kNoErrorDialogs); @@ -578,7 +569,8 @@ #if defined(OS_WIN) if (RunningOnWOW64()) { if (!NaClBrokerService::GetInstance()->LaunchLoader( - weak_factory_.GetWeakPtr(), mojo_channel_token)) { + weak_factory_.GetWeakPtr(), + process_->GetServiceRequestChannelToken())) { SendErrorToRenderer("broker service did not launch process"); return false; }
diff --git a/components/nacl/browser/nacl_process_host.h b/components/nacl/browser/nacl_process_host.h index 6d2c06d..d3fd57a 100644 --- a/components/nacl/browser/nacl_process_host.h +++ b/components/nacl/browser/nacl_process_host.h
@@ -257,9 +257,6 @@ // reporting crash information. base::SharedMemory crash_info_shmem_; - // Randomly generated token identifying the child process to Mojo. - std::string mojo_child_token_; - base::WeakPtrFactory<NaClProcessHost> weak_factory_; DISALLOW_COPY_AND_ASSIGN(NaClProcessHost);
diff --git a/components/nacl/common/BUILD.gn b/components/nacl/common/BUILD.gn index 36a0dba..de3d469 100644 --- a/components/nacl/common/BUILD.gn +++ b/components/nacl/common/BUILD.gn
@@ -17,6 +17,8 @@ "nacl_messages.h", "nacl_process_type.h", "nacl_sandbox_type.h", + "nacl_service.cc", + "nacl_service.h", "nacl_types.cc", "nacl_types.h", "nacl_types_param_traits.cc", @@ -24,15 +26,19 @@ ] public_deps = [ + ":minimal_content_dummy", ":switches", ] deps = [ - ":minimal_content_dummy", ":nacl_error_code", "//base", "//base:base_static", + "//content/public/common:service_names", "//ipc", + "//ipc:mojom", + "//mojo/edk/system", + "//services/service_manager/public/cpp", ] } @@ -43,7 +49,9 @@ source_set("minimal_content_dummy") { check_includes = false sources = [ + "//content/public/common/content_descriptors.h", "//content/public/common/content_switches.h", + "//content/public/common/mojo_channel_switches.h", "//content/public/common/process_type.h", "//content/public/common/sandbox_type.h", ]
diff --git a/components/nacl/common/DEPS b/components/nacl/common/DEPS index 3b9fcea..c95ab33 100644 --- a/components/nacl/common/DEPS +++ b/components/nacl/common/DEPS
@@ -1,4 +1,6 @@ include_rules = [ "+native_client/src/public", "+native_client/src/trusted/service_runtime/nacl_error_code.h", + "+mojo/edk/embedder", + "+mojo/public", ]
diff --git a/components/nacl/common/nacl_constants.cc b/components/nacl/common/nacl_constants.cc index d3a8a63..81979f2 100644 --- a/components/nacl/common/nacl_constants.cc +++ b/components/nacl/common/nacl_constants.cc
@@ -21,4 +21,7 @@ const base::FilePath::CharType kInternalNaClPluginFileName[] = FILE_PATH_LITERAL("internal-nacl-plugin"); +const char kNaClBrokerServiceName[] = "nacl_broker"; +const char kNaClLoaderServiceName[] = "nacl_loader"; + } // namespace nacl
diff --git a/components/nacl/common/nacl_constants.h b/components/nacl/common/nacl_constants.h index 2b18e0e6..09df003 100644 --- a/components/nacl/common/nacl_constants.h +++ b/components/nacl/common/nacl_constants.h
@@ -20,6 +20,9 @@ extern const base::FilePath::CharType kInternalNaClPluginFileName[]; +extern const char kNaClBrokerServiceName[]; +extern const char kNaClLoaderServiceName[]; + } // namespace nacl #endif // COMPONENTS_NACL_COMMON_NACL_CONSTANTS_H_
diff --git a/components/nacl/common/nacl_service.cc b/components/nacl/common/nacl_service.cc new file mode 100644 index 0000000..ac22e57 --- /dev/null +++ b/components/nacl/common/nacl_service.cc
@@ -0,0 +1,113 @@ +// Copyright 2016 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. + +#include "components/nacl/common/nacl_service.h" + +#include <string> + +#include "base/command_line.h" +#include "content/public/common/mojo_channel_switches.h" +#include "content/public/common/service_names.mojom.h" +#include "ipc/ipc.mojom.h" +#include "mojo/edk/embedder/embedder.h" +#include "mojo/edk/embedder/scoped_ipc_support.h" +#include "mojo/edk/embedder/scoped_platform_handle.h" +#include "services/service_manager/public/cpp/interface_registry.h" +#include "services/service_manager/public/cpp/service.h" +#include "services/service_manager/public/cpp/service_context.h" +#include "services/service_manager/public/cpp/service_info.h" + +#if defined(OS_POSIX) +#include "base/posix/global_descriptors.h" +#include "content/public/common/content_descriptors.h" +#elif defined(OS_WIN) +#include "mojo/edk/embedder/platform_channel_pair.h" +#endif + +namespace { + +void EstablishMojoConnection() { +#if defined(OS_WIN) + mojo::edk::ScopedPlatformHandle platform_channel( + mojo::edk::PlatformChannelPair::PassClientHandleFromParentProcess( + *base::CommandLine::ForCurrentProcess())); +#else + mojo::edk::ScopedPlatformHandle platform_channel(mojo::edk::PlatformHandle( + base::GlobalDescriptors::GetInstance()->Get(kMojoIPCChannel))); +#endif + DCHECK(platform_channel.is_valid()); + mojo::edk::SetParentPipeHandle(std::move(platform_channel)); +} + +service_manager::mojom::ServiceRequest ConnectToServiceManager() { + const std::string service_request_channel_token = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kServiceRequestChannelToken); + DCHECK(!service_request_channel_token.empty()); + mojo::ScopedMessagePipeHandle parent_handle = + mojo::edk::CreateChildMessagePipe(service_request_channel_token); + DCHECK(parent_handle.is_valid()); + return mojo::MakeRequest<service_manager::mojom::Service>( + std::move(parent_handle)); +} + +void ConnectBootstrapChannel(IPC::mojom::ChannelBootstrapPtrInfo ptr, + IPC::mojom::ChannelBootstrapRequest request) { + mojo::FuseInterface(std::move(request), std::move(ptr)); +} + +class NaClService : public service_manager::Service { + public: + NaClService(IPC::mojom::ChannelBootstrapPtrInfo bootstrap, + std::unique_ptr<mojo::edk::ScopedIPCSupport> ipc_support); + ~NaClService() override; + + // Service overrides. + bool OnConnect(const service_manager::ServiceInfo& remote_info, + service_manager::InterfaceRegistry* registry) override; + + private: + IPC::mojom::ChannelBootstrapPtrInfo ipc_channel_bootstrap_; + std::unique_ptr<mojo::edk::ScopedIPCSupport> ipc_support_; + bool connected_ = false; +}; + +NaClService::NaClService( + IPC::mojom::ChannelBootstrapPtrInfo bootstrap, + std::unique_ptr<mojo::edk::ScopedIPCSupport> ipc_support) + : ipc_channel_bootstrap_(std::move(bootstrap)), + ipc_support_(std::move(ipc_support)) {} + +NaClService::~NaClService() = default; + +bool NaClService::OnConnect(const service_manager::ServiceInfo& remote_info, + service_manager::InterfaceRegistry* registry) { + if (remote_info.identity.name() != content::mojom::kBrowserServiceName) + return false; + + if (connected_) + return false; + + connected_ = true; + registry->AddInterface(base::Bind(&ConnectBootstrapChannel, + base::Passed(&ipc_channel_bootstrap_))); + return true; +} + +} // namespace + +std::unique_ptr<service_manager::ServiceContext> CreateNaClServiceContext( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + mojo::ScopedMessagePipeHandle* ipc_channel) { + auto ipc_support = + base::MakeUnique<mojo::edk::ScopedIPCSupport>(std::move(io_task_runner)); + EstablishMojoConnection(); + + IPC::mojom::ChannelBootstrapPtr bootstrap; + *ipc_channel = mojo::MakeRequest(&bootstrap).PassMessagePipe(); + return base::MakeUnique<service_manager::ServiceContext>( + base::MakeUnique<NaClService>(bootstrap.PassInterface(), + std::move(ipc_support)), + ConnectToServiceManager()); +}
diff --git a/components/nacl/common/nacl_service.h b/components/nacl/common/nacl_service.h new file mode 100644 index 0000000..887dfdda --- /dev/null +++ b/components/nacl/common/nacl_service.h
@@ -0,0 +1,21 @@ +// Copyright 2016 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. + +#ifndef COMPONENTS_NACL_COMMON_NACL_SERVICE_H_ +#define COMPONENTS_NACL_COMMON_NACL_SERVICE_H_ + +#include <memory> + +#include "base/single_thread_task_runner.h" +#include "mojo/public/cpp/system/message_pipe.h" + +namespace service_manager { +class ServiceContext; +} + +std::unique_ptr<service_manager::ServiceContext> CreateNaClServiceContext( + scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, + mojo::ScopedMessagePipeHandle* ipc_channel); + +#endif // COMPONENTS_NACL_COMMON_NACL_SERVICE_H_
diff --git a/components/nacl/loader/BUILD.gn b/components/nacl/loader/BUILD.gn index 6fa48361..e770d17b 100644 --- a/components/nacl/loader/BUILD.gn +++ b/components/nacl/loader/BUILD.gn
@@ -4,6 +4,7 @@ import("//build/config/features.gni") import("//build/config/nacl/config.gni") +import("//services/service_manager/public/service_manifest.gni") import("//testing/test.gni") assert(enable_nacl) @@ -39,6 +40,7 @@ "//ppapi/c", "//ppapi/proxy:ipc", "//sandbox", + "//services/service_manager/public/cpp", ] } @@ -50,10 +52,7 @@ check_includes = false sources = [ "//content/public/common/child_process_sandbox_support_linux.h", - "//content/public/common/content_descriptors.h", - "//content/public/common/content_switches.h", "//content/public/common/main_function_params.h", - "//content/public/common/mojo_channel_switches.h", "//content/public/common/sandbox_init.h", ] @@ -71,9 +70,11 @@ "//components/nacl/common", "//content/public/common", "//ppapi/shared_impl", + "//services/service_manager/public/cpp", ] data_deps = [ + ":nacl_loader_manifest", "//ppapi/native_client:irt", "//ppapi/native_client/src/untrusted/pnacl_support_extension", ] @@ -196,13 +197,6 @@ output_name = "nacl_helper_nonsfi" set_sources_assignment_filter([]) sources = [ - # TODO(brettw) can this just depend on //components/nacl/common? - "../common/nacl_messages.cc", - "../common/nacl_messages.h", - "../common/nacl_types.cc", - "../common/nacl_types.h", - "../common/nacl_types_param_traits.cc", - "../common/nacl_types_param_traits.h", "nacl_helper_linux.cc", "nacl_helper_linux.h", "nacl_trusted_listener.cc", @@ -215,6 +209,7 @@ deps = [ ":nacl_helper_nonsfi_sandbox", "//base", + "//components/nacl/common:minimal", "//components/nacl/common:mojo_bindings", "//components/nacl/common:switches", "//components/tracing", @@ -232,6 +227,7 @@ "//native_client/src/untrusted/nacl", "//ppapi/proxy", "//sandbox/linux:sandbox", + "//services/service_manager/public/cpp", ] } @@ -245,6 +241,7 @@ ] deps = [ "//base", + "//components/nacl/common:minimal", "//components/nacl/common:switches", "//content", "//sandbox/linux:sandbox", @@ -297,3 +294,8 @@ ] } } + +service_manifest("nacl_loader_manifest") { + name = "nacl_loader" + source = "nacl_loader_manifest.json" +}
diff --git a/components/nacl/loader/OWNERS b/components/nacl/loader/OWNERS new file mode 100644 index 0000000..39ccc030 --- /dev/null +++ b/components/nacl/loader/OWNERS
@@ -0,0 +1,3 @@ +# Mojo manifests +per-file *manifest.json=set noparent +per-file *manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/components/nacl/loader/nacl_helper_linux.cc b/components/nacl/loader/nacl_helper_linux.cc index cdbbafd0..df24f6d 100644 --- a/components/nacl/loader/nacl_helper_linux.cc +++ b/components/nacl/loader/nacl_helper_linux.cc
@@ -152,7 +152,7 @@ child_fds[content::ZygoteForkDelegate::kPIDOracleFDIndex].get())); base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kMojoChannelToken, channel_id); + switches::kServiceRequestChannelToken, channel_id); // Save the browser socket and close the rest. base::ScopedFD browser_fd(
diff --git a/components/nacl/loader/nacl_helper_win_64.cc b/components/nacl/loader/nacl_helper_win_64.cc index a17fe888..fb2ebe5 100644 --- a/components/nacl/loader/nacl_helper_win_64.cc +++ b/components/nacl/loader/nacl_helper_win_64.cc
@@ -26,8 +26,6 @@ #include "content/public/common/main_function_params.h" #include "content/public/common/sandbox_init.h" #include "mojo/edk/embedder/embedder.h" -#include "mojo/edk/embedder/platform_channel_pair.h" -#include "mojo/edk/embedder/scoped_ipc_support.h" #include "sandbox/win/src/sandbox_types.h" extern int NaClMain(const content::MainFunctionParams&); @@ -40,12 +38,6 @@ base::PlatformThread::SetName("CrNaClBrokerMain"); mojo::edk::Init(); - mojo::edk::ScopedIPCSupport mojo_ipc_support(main_message_loop.task_runner()); - mojo::edk::ScopedPlatformHandle platform_channel( - mojo::edk::PlatformChannelPair::PassClientHandleFromParentProcess( - *base::CommandLine::ForCurrentProcess())); - DCHECK(platform_channel.is_valid()); - mojo::edk::SetParentPipeHandle(std::move(platform_channel)); std::unique_ptr<base::PowerMonitorSource> power_monitor_source( new base::PowerMonitorDeviceSource());
diff --git a/components/nacl/loader/nacl_listener.cc b/components/nacl/loader/nacl_listener.cc index 8cf5a31..ecefbb8 100644 --- a/components/nacl/loader/nacl_listener.cc +++ b/components/nacl/loader/nacl_listener.cc
@@ -26,6 +26,7 @@ #include "build/build_config.h" #include "components/nacl/common/nacl.mojom.h" #include "components/nacl/common/nacl_messages.h" +#include "components/nacl/common/nacl_service.h" #include "components/nacl/common/nacl_switches.h" #include "components/nacl/loader/nacl_ipc_adapter.h" #include "components/nacl/loader/nacl_validation_db.h" @@ -34,16 +35,10 @@ #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_sync_channel.h" #include "ipc/ipc_sync_message_filter.h" -#include "mojo/edk/embedder/embedder.h" -#include "mojo/edk/embedder/scoped_ipc_support.h" #include "native_client/src/public/chrome_main.h" #include "native_client/src/public/nacl_app.h" #include "native_client/src/public/nacl_desc.h" - -#if defined(OS_POSIX) -#include "base/posix/global_descriptors.h" -#include "content/public/common/content_descriptors.h" -#endif +#include "services/service_manager/public/cpp/service_context.h" #if defined(OS_LINUX) #include "content/public/common/child_process_sandbox_support_linux.h" @@ -53,7 +48,6 @@ #include <io.h> #include "content/public/common/sandbox_init.h" -#include "mojo/edk/embedder/platform_channel_pair.h" #endif namespace { @@ -174,20 +168,6 @@ base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); DCHECK(g_listener == NULL); g_listener = this; - - mojo_ipc_support_ = - base::MakeUnique<mojo::edk::ScopedIPCSupport>(io_thread_.task_runner()); -#if defined(OS_WIN) - mojo::edk::ScopedPlatformHandle platform_channel( - mojo::edk::PlatformChannelPair::PassClientHandleFromParentProcess( - *base::CommandLine::ForCurrentProcess())); -#else - mojo::edk::ScopedPlatformHandle platform_channel( - mojo::edk::PlatformHandle( - base::GlobalDescriptors::GetInstance()->Get(kMojoIPCChannel))); -#endif - DCHECK(platform_channel.is_valid()); - mojo::edk::SetParentPipeHandle(std::move(platform_channel)); } NaClListener::~NaClListener() { @@ -236,17 +216,14 @@ }; void NaClListener::Listen() { - mojo::ScopedMessagePipeHandle handle( - mojo::edk::CreateChildMessagePipe( - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kMojoChannelToken))); - DCHECK(handle.is_valid()); - channel_ = IPC::SyncChannel::Create(this, io_thread_.task_runner().get(), &shutdown_event_); filter_ = channel_->CreateSyncMessageFilter(); channel_->AddFilter(new FileTokenMessageFilter()); - channel_->Init(handle.release(), IPC::Channel::MODE_CLIENT, true); + mojo::ScopedMessagePipeHandle channel_handle; + std::unique_ptr<service_manager::ServiceContext> service_context = + CreateNaClServiceContext(io_thread_.task_runner(), &channel_handle); + channel_->Init(channel_handle.release(), IPC::Channel::MODE_CLIENT, true); main_task_runner_ = base::ThreadTaskRunnerHandle::Get(); base::RunLoop().Run(); }
diff --git a/components/nacl/loader/nacl_listener.h b/components/nacl/loader/nacl_listener.h index f0a9806..ed95cc37 100644 --- a/components/nacl/loader/nacl_listener.h +++ b/components/nacl/loader/nacl_listener.h
@@ -28,12 +28,6 @@ class SyncMessageFilter; } -namespace mojo { -namespace edk { -class ScopedIPCSupport; -} // namespace edk -} // namespace mojo - // The NaClListener is an IPC channel listener that waits for a // request to start a NaCl module. class NaClListener : public IPC::Listener { @@ -125,8 +119,6 @@ bool is_started_; - std::unique_ptr<mojo::edk::ScopedIPCSupport> mojo_ipc_support_; - DISALLOW_COPY_AND_ASSIGN(NaClListener); };
diff --git a/components/nacl/loader/nacl_loader_manifest.json b/components/nacl/loader/nacl_loader_manifest.json new file mode 100644 index 0000000..7598054 --- /dev/null +++ b/components/nacl/loader/nacl_loader_manifest.json
@@ -0,0 +1,13 @@ +{ + "name": "nacl_loader", + "display_name": "NaCl loader", + "interface_provider_specs": { + "service_manager:connector": { + "provides": { + "browser": [ + "IPC::mojom::ChannelBootstrap" + ] + } + } + } +}
diff --git a/components/nacl/loader/nonsfi/nonsfi_listener.cc b/components/nacl/loader/nonsfi/nonsfi_listener.cc index 4c992b8..b7a43aa 100644 --- a/components/nacl/loader/nonsfi/nonsfi_listener.cc +++ b/components/nacl/loader/nonsfi/nonsfi_listener.cc
@@ -10,12 +10,12 @@ #include "base/file_descriptor_posix.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "base/posix/global_descriptors.h" #include "base/rand_util.h" #include "base/run_loop.h" #include "build/build_config.h" #include "components/nacl/common/nacl.mojom.h" #include "components/nacl/common/nacl_messages.h" +#include "components/nacl/common/nacl_service.h" #include "components/nacl/common/nacl_types.h" #include "components/nacl/loader/nacl_trusted_listener.h" #include "components/nacl/loader/nonsfi/nonsfi_main.h" @@ -24,11 +24,10 @@ #include "ipc/ipc_channel.h" #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_sync_channel.h" -#include "mojo/edk/embedder/embedder.h" -#include "mojo/edk/embedder/scoped_ipc_support.h" #include "native_client/src/public/nonsfi/irt_random.h" #include "ppapi/nacl_irt/irt_manifest.h" #include "ppapi/nacl_irt/plugin_startup.h" +#include "services/service_manager/public/cpp/service_context.h" #if !defined(OS_NACL_NONSFI) #error "This file must be built for nacl_helper_nonsfi." @@ -44,34 +43,21 @@ key_fd_map_(new std::map<std::string, int>) { io_thread_.StartWithOptions( base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); - - mojo_ipc_support_ = - base::MakeUnique<mojo::edk::ScopedIPCSupport>(io_thread_.task_runner()); - mojo::edk::ScopedPlatformHandle platform_channel( - mojo::edk::PlatformHandle( - base::GlobalDescriptors::GetInstance()->Get(kMojoIPCChannel))); - DCHECK(platform_channel.is_valid()); - mojo::edk::SetParentPipeHandle(std::move(platform_channel)); } NonSfiListener::~NonSfiListener() { } void NonSfiListener::Listen() { - mojo::ScopedMessagePipeHandle handle( - mojo::edk::CreateChildMessagePipe( - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kMojoChannelToken))); - DCHECK(handle.is_valid()); - IPC::ChannelHandle channel_handle = IPC::ChannelHandle(handle.release()); - - channel_ = IPC::SyncChannel::Create( - channel_handle, - IPC::Channel::MODE_CLIENT, - this, // As a Listener. - io_thread_.task_runner().get(), - true, // Create pipe now. - &shutdown_event_); + mojo::ScopedMessagePipeHandle channel_handle; + std::unique_ptr<service_manager::ServiceContext> service_context = + CreateNaClServiceContext(io_thread_.task_runner(), &channel_handle); + channel_ = IPC::SyncChannel::Create(channel_handle.release(), + IPC::Channel::MODE_CLIENT, + this, // As a Listener. + io_thread_.task_runner(), + true, // Create pipe now. + &shutdown_event_); base::RunLoop().Run(); }
diff --git a/components/nacl/loader/nonsfi/nonsfi_listener.h b/components/nacl/loader/nonsfi/nonsfi_listener.h index 9b18cd84..d673c291 100644 --- a/components/nacl/loader/nonsfi/nonsfi_listener.h +++ b/components/nacl/loader/nonsfi/nonsfi_listener.h
@@ -20,12 +20,6 @@ class SyncChannel; } // namespace IPC -namespace mojo { -namespace edk { -class ScopedIPCSupport; -} // namespace edk -} // namespace mojo - class NaClTrustedListener; namespace nacl { @@ -52,7 +46,6 @@ base::WaitableEvent shutdown_event_; std::unique_ptr<IPC::SyncChannel> channel_; std::unique_ptr<NaClTrustedListener> trusted_listener_; - std::unique_ptr<mojo::edk::ScopedIPCSupport> mojo_ipc_support_; std::unique_ptr<std::map<std::string, int>> key_fd_map_;
diff --git a/components/network_session_configurator/network_session_configurator.cc b/components/network_session_configurator/network_session_configurator.cc index e1c9bb0..6074c56 100644 --- a/components/network_session_configurator/network_session_configurator.cc +++ b/components/network_session_configurator/network_session_configurator.cc
@@ -15,8 +15,8 @@ #include "components/variations/variations_associated_data.h" #include "components/version_info/version_info.h" #include "net/http/http_stream_factory.h" +#include "net/quic/chromium/quic_utils_chromium.h" #include "net/quic/core/quic_packets.h" -#include "net/quic/core/quic_utils.h" #include "net/url_request/url_fetcher.h" namespace { @@ -103,7 +103,7 @@ return net::QuicTagVector(); } - return net::QuicUtils::ParseQuicConnectionOptions(it->second); + return net::ParseQuicConnectionOptions(it->second); } bool ShouldQuicAlwaysRequireHandshakeConfirmation(
diff --git a/components/safe_browsing/BUILD.gn b/components/safe_browsing/BUILD.gn new file mode 100644 index 0000000..8b81a6e7 --- /dev/null +++ b/components/safe_browsing/BUILD.gn
@@ -0,0 +1,16 @@ +# Copyright 2016 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. + +source_set("safe_browsing") { + sources = [ + "base_ui_manager.cc", + "base_ui_manager.h", + ] + + deps = [ + "//base:base", + "//components/security_interstitials/content:unsafe_resource", + "//content/public/browser:browser", + ] +}
diff --git a/components/safe_browsing/DEPS b/components/safe_browsing/DEPS new file mode 100644 index 0000000..2f86b686 --- /dev/null +++ b/components/safe_browsing/DEPS
@@ -0,0 +1,5 @@ +include_rules = [ + "+components/safe_browsing_db", + "+components/security_interstitials/content", + "+content/public/browser", +]
diff --git a/components/safe_browsing/base_ui_manager.cc b/components/safe_browsing/base_ui_manager.cc new file mode 100644 index 0000000..3bdd8db --- /dev/null +++ b/components/safe_browsing/base_ui_manager.cc
@@ -0,0 +1,289 @@ +// Copyright 2016 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. + +#include "components/safe_browsing/base_ui_manager.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/macros.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/web_contents.h" + +using content::BrowserThread; +using content::NavigationEntry; +using content::WebContents; +using safe_browsing::HitReport; +using safe_browsing::SBThreatType; + +namespace { + +const void* const kWhitelistKey = &kWhitelistKey; + +// A WhitelistUrlSet holds the set of URLs that have been whitelisted +// for a specific WebContents, along with pending entries that are still +// undecided. Each URL is associated with the first SBThreatType that +// was seen for that URL. The URLs in this set should come from +// GetWhitelistUrl() or GetMainFrameWhitelistUrlForResource() (in +// SafeBrowsingUIManager) +class WhitelistUrlSet : public base::SupportsUserData::Data { + public: + WhitelistUrlSet() {} + bool Contains(const GURL url, SBThreatType* threat_type) { + auto found = map_.find(url); + if (found == map_.end()) + return false; + if (threat_type) + *threat_type = found->second; + return true; + } + void RemovePending(const GURL& url) { pending_.erase(url); } + void Insert(const GURL url, SBThreatType threat_type) { + if (Contains(url, nullptr)) + return; + map_[url] = threat_type; + RemovePending(url); + } + bool ContainsPending(const GURL& url, SBThreatType* threat_type) { + auto found = pending_.find(url); + if (found == pending_.end()) + return false; + if (threat_type) + *threat_type = found->second; + return true; + } + void InsertPending(const GURL url, SBThreatType threat_type) { + if (ContainsPending(url, nullptr)) + return; + pending_[url] = threat_type; + } + + private: + std::map<GURL, SBThreatType> map_; + std::map<GURL, SBThreatType> pending_; + DISALLOW_COPY_AND_ASSIGN(WhitelistUrlSet); +}; + +// Returns the URL that should be used in a WhitelistUrlSet for the +// resource loaded from |url| on a navigation |entry|. +GURL GetWhitelistUrl(const GURL& url, + bool is_subresource, + NavigationEntry* entry) { + if (is_subresource) { + if (!entry) + return GURL(); + return entry->GetURL().GetWithEmptyPath(); + } + return url.GetWithEmptyPath(); +} + +WhitelistUrlSet* GetOrCreateWhitelist(WebContents* web_contents) { + WhitelistUrlSet* site_list = + static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); + if (!site_list) { + site_list = new WhitelistUrlSet; + web_contents->SetUserData(kWhitelistKey, site_list); + } + return site_list; +} + +} // namespace + +namespace safe_browsing { + +BaseSafeBrowsingUIManager::BaseSafeBrowsingUIManager() {} + +void BaseSafeBrowsingUIManager::StopOnIOThread(bool shutdown) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + // TODO(ntfschr): implement this once SafeBrowsingService is componentized + return; +} + +BaseSafeBrowsingUIManager::~BaseSafeBrowsingUIManager() {} + +bool BaseSafeBrowsingUIManager::IsWhitelisted(const UnsafeResource& resource) { + NavigationEntry* entry = nullptr; + if (resource.is_subresource) { + entry = resource.GetNavigationEntryForResource(); + } + SBThreatType unused_threat_type; + return IsUrlWhitelistedOrPendingForWebContents( + resource.url, resource.is_subresource, entry, + resource.web_contents_getter.Run(), true, &unused_threat_type); +} + +// Check if the user has already seen and/or ignored a SB warning for this +// WebContents and top-level domain. +bool BaseSafeBrowsingUIManager::IsUrlWhitelistedOrPendingForWebContents( + const GURL& url, + bool is_subresource, + NavigationEntry* entry, + WebContents* web_contents, + bool whitelist_only, + SBThreatType* threat_type) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + GURL lookup_url = GetWhitelistUrl(url, is_subresource, entry); + if (lookup_url.is_empty()) + return false; + + WhitelistUrlSet* site_list = + static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); + if (!site_list) + return false; + + bool whitelisted = site_list->Contains(lookup_url, threat_type); + if (whitelist_only) { + return whitelisted; + } else { + return whitelisted || site_list->ContainsPending(lookup_url, threat_type); + } +} + +void BaseSafeBrowsingUIManager::OnBlockingPageDone( + const std::vector<UnsafeResource>& resources, + bool proceed, + WebContents* web_contents, + const GURL& main_frame_url) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + for (const auto& resource : resources) { + if (!resource.callback.is_null()) { + DCHECK(resource.callback_thread); + resource.callback_thread->PostTask( + FROM_HERE, base::Bind(resource.callback, proceed)); + } + + GURL whitelist_url = GetWhitelistUrl( + main_frame_url, false /* is subresource */, + nullptr /* no navigation entry needed for main resource */); + if (proceed) { + AddToWhitelistUrlSet(whitelist_url, web_contents, + false /* Pending -> permanent */, + resource.threat_type); + } else if (web_contents) { + // |web_contents| doesn't exist if the tab has been closed. + RemoveFromPendingWhitelistUrlSet(whitelist_url, web_contents); + } + } +} + +void BaseSafeBrowsingUIManager::DisplayBlockingPage( + const UnsafeResource& resource) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // TODO(ntfschr): implement this once SafeBrowsingBlockingPage is + // componentized + return; +} + +void BaseSafeBrowsingUIManager::EnsureWhitelistCreated( + WebContents* web_contents) { + GetOrCreateWhitelist(web_contents); +} + +void BaseSafeBrowsingUIManager::LogPauseDelay(base::TimeDelta time) { + return; +} + +// A safebrowsing hit is sent after a blocking page for malware/phishing +// or after the warning dialog for download urls, only for +// UMA || extended_reporting users. +void BaseSafeBrowsingUIManager::MaybeReportSafeBrowsingHit( + const HitReport& hit_report) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // TODO(ntfschr): implement this once we support reporting in WebView + return; +} + +void BaseSafeBrowsingUIManager::ReportSafeBrowsingHitOnIOThread( + const HitReport& hit_report) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + // TODO(ntfschr): implement this once we support reporting in WebView + return; +} + +// If the user had opted-in to send ThreatDetails, this gets called +// when the report is ready. +void BaseSafeBrowsingUIManager::SendSerializedThreatDetails( + const std::string& serialized) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + // TODO(ntfschr): implement this once we support reporting in WebView + return; +} + +// Record this domain in the given WebContents as either whitelisted or +// pending whitelisting (if an interstitial is currently displayed). If an +// existing WhitelistUrlSet does not yet exist, create a new WhitelistUrlSet. +void BaseSafeBrowsingUIManager::AddToWhitelistUrlSet(const GURL& whitelist_url, + WebContents* web_contents, + bool pending, + SBThreatType threat_type) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + // A WebContents might not exist if the tab has been closed. + if (!web_contents) + return; + + WhitelistUrlSet* site_list = GetOrCreateWhitelist(web_contents); + + if (whitelist_url.is_empty()) + return; + + if (pending) { + site_list->InsertPending(whitelist_url, threat_type); + } else { + site_list->Insert(whitelist_url, threat_type); + } + + // Notify security UI that security state has changed. + web_contents->DidChangeVisibleSecurityState(); +} + +void BaseSafeBrowsingUIManager::AddObserver(Observer* observer) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + observer_list_.AddObserver(observer); +} + +void BaseSafeBrowsingUIManager::RemoveObserver(Observer* observer) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + observer_list_.RemoveObserver(observer); +} + +void BaseSafeBrowsingUIManager::RemoveFromPendingWhitelistUrlSet( + const GURL& whitelist_url, + WebContents* web_contents) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + // A WebContents might not exist if the tab has been closed. + if (!web_contents) + return; + + // Use |web_contents| rather than |resource.web_contents_getter| + // here. By this point, a "Back" navigation could have already been + // committed, so the page loading |resource| might be gone and + // |web_contents_getter| may no longer be valid. + WhitelistUrlSet* site_list = + static_cast<WhitelistUrlSet*>(web_contents->GetUserData(kWhitelistKey)); + + if (whitelist_url.is_empty()) + return; + + // Note that this function does not DCHECK that |whitelist_url| + // appears in the pending whitelist. In the common case, it's expected + // that a URL is in the pending whitelist when it is removed, but it's + // not always the case. For example, if there are several blocking + // pages queued up for different resources on the same page, and the + // user goes back to dimiss the first one, the subsequent blocking + // pages get dismissed as well (as if the user had clicked "Back to + // safety" on each of them). In this case, the first dismissal will + // remove the main-frame URL from the pending whitelist, so the + // main-frame URL will have already been removed when the subsequent + // blocking pages are dismissed. + if (site_list->ContainsPending(whitelist_url, nullptr)) + site_list->RemovePending(whitelist_url); + + // Notify security UI that security state has changed. + web_contents->DidChangeVisibleSecurityState(); +} + +} // namespace safe_browsing
diff --git a/components/safe_browsing/base_ui_manager.h b/components/safe_browsing/base_ui_manager.h new file mode 100644 index 0000000..2c56060a --- /dev/null +++ b/components/safe_browsing/base_ui_manager.h
@@ -0,0 +1,154 @@ +// Copyright 2016 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. + +#ifndef COMPONENTS_SAFE_BROWSING_BASE_UI_MANAGER_H_ +#define COMPONENTS_SAFE_BROWSING_BASE_UI_MANAGER_H_ + +#include <string> +#include <vector> + +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/observer_list.h" +#include "base/supports_user_data.h" +#include "base/time/time.h" +#include "components/security_interstitials/content/unsafe_resource.h" + +class GURL; + +namespace content { +class NavigationEntry; +class WebContents; +} // namespace content + +namespace safe_browsing { + +// Construction needs to happen on the main thread. +class BaseSafeBrowsingUIManager + : public base::RefCountedThreadSafe<BaseSafeBrowsingUIManager> { + public: + typedef security_interstitials::UnsafeResource UnsafeResource; + + // Observer class can be used to get notified when a SafeBrowsing hit + // was found. + class Observer { + public: + // The |resource| was classified as unsafe by SafeBrowsing, and is + // not whitelisted. + // The |resource| must not be accessed after OnSafeBrowsingHit returns. + // This method will be called on the UI thread. + virtual void OnSafeBrowsingHit(const UnsafeResource& resource) = 0; + + protected: + Observer() {} + virtual ~Observer() {} + + private: + DISALLOW_COPY_AND_ASSIGN(Observer); + }; + + BaseSafeBrowsingUIManager(); + + // Called to stop or shutdown operations on the io_thread. This may be called + // multiple times during the life of the UIManager. Should be called + // on IO thread. If shutdown is true, the manager is disabled permanently. + virtual void StopOnIOThread(bool shutdown); + + // Called on the UI thread to display an interstitial page. + // |url| is the url of the resource that matches a safe browsing list. + // If the request contained a chain of redirects, |url| is the last url + // in the chain, and |original_url| is the first one (the root of the + // chain). Otherwise, |original_url| = |url|. + virtual void DisplayBlockingPage(const UnsafeResource& resource); + + // Log the user perceived delay caused by SafeBrowsing. This delay is the time + // delta starting from when we would have started reading data from the + // network, and ending when the SafeBrowsing check completes indicating that + // the current page is 'safe'. + virtual void LogPauseDelay(base::TimeDelta time); + + // Called on the IO thread by the ThreatDetails with the serialized + // protocol buffer, so the service can send it over. + virtual void SendSerializedThreatDetails(const std::string& serialized); + + // Report hits to the unsafe contents (malware, phishing, unsafe download URL) + // to the server. Can only be called on UI thread. If |post_data| is + // non-empty, the request will be sent as a POST instead of a GET. + // Will report only for UMA || is_extended_reporting. + virtual void MaybeReportSafeBrowsingHit( + const safe_browsing::HitReport& hit_report); + + // A convenience wrapper method for IsUrlWhitelistedOrPendingForWebContents. + virtual bool IsWhitelisted(const UnsafeResource& resource); + + // Checks if we already displayed or are displaying an interstitial + // for the top-level site |url| in a given WebContents. If + // |whitelist_only|, it returns true only if the user chose to ignore + // the interstitial. Otherwise, it returns true if an interstitial for + // |url| is already displaying *or* if the user has seen an + // interstitial for |url| before in this WebContents and proceeded + // through it. Called on the UI thread. + // + // If the resource was found in the whitelist or pending for the + // whitelist, |threat_type| will be set to the SBThreatType for which + // the URL was first whitelisted. + virtual bool IsUrlWhitelistedOrPendingForWebContents( + const GURL& url, + bool is_subresource, + content::NavigationEntry* entry, + content::WebContents* web_contents, + bool whitelist_only, + SBThreatType* threat_type); + + // The blocking page for |web_contents| on the UI thread has + // completed, with |proceed| set to true if the user has chosen to + // proceed through the blocking page and false + // otherwise. |web_contents| is the WebContents that was displaying + // the blocking page. |main_frame_url| is the top-level URL on which + // the blocking page was displayed. If |proceed| is true, + // |main_frame_url| is whitelisted so that the user will not see + // another warning for that URL in this WebContents. + virtual void OnBlockingPageDone(const std::vector<UnsafeResource>& resources, + bool proceed, + content::WebContents* web_contents, + const GURL& main_frame_url); + + // Add and remove observers. These methods must be invoked on the UI thread. + virtual void AddObserver(Observer* observer); + virtual void RemoveObserver(Observer* remove); + + protected: + virtual ~BaseSafeBrowsingUIManager(); + + // Updates the whitelist URL set for |web_contents|. Called on the UI thread. + void AddToWhitelistUrlSet(const GURL& whitelist_url, + content::WebContents* web_contents, + bool is_pending, + SBThreatType threat_type); + + // Call protocol manager on IO thread to report hits of unsafe contents. + virtual void ReportSafeBrowsingHitOnIOThread( + const safe_browsing::HitReport& hit_report); + + // Removes |whitelist_url| from the pending whitelist for + // |web_contents|. Called on the UI thread. + void RemoveFromPendingWhitelistUrlSet(const GURL& whitelist_url, + content::WebContents* web_contents); + + // Ensures that |web_contents| has its whitelist set in its userdata + static void EnsureWhitelistCreated(content::WebContents* web_contents); + + base::ObserverList<Observer> observer_list_; + + private: + friend class base::RefCountedThreadSafe<BaseSafeBrowsingUIManager>; + + DISALLOW_COPY_AND_ASSIGN(BaseSafeBrowsingUIManager); +}; + +} // namespace safe_browsing + +#endif // COMPONENTS_SAFE_BROWSING_BASE_UI_MANAGER_H_
diff --git a/components/safe_browsing_db/BUILD.gn b/components/safe_browsing_db/BUILD.gn index e7e788c..13bdd1b 100644 --- a/components/safe_browsing_db/BUILD.gn +++ b/components/safe_browsing_db/BUILD.gn
@@ -78,9 +78,11 @@ "hit_report.cc", "hit_report.h", ] + public_deps = [ + ":util", + ] deps = [ ":safe_browsing_prefs", - ":util", "//components/metrics", "//url", ]
diff --git a/components/security_interstitials/content/BUILD.gn b/components/security_interstitials/content/BUILD.gn index b5632d2..d044aaa 100644 --- a/components/security_interstitials/content/BUILD.gn +++ b/components/security_interstitials/content/BUILD.gn
@@ -8,9 +8,12 @@ "unsafe_resource.h", ] + public_deps = [ + "//components/safe_browsing_db:hit_report", + ] + deps = [ "//base", - "//components/safe_browsing_db:hit_report", "//components/safe_browsing_db:util", "//content/public/browser", ]
diff --git a/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc b/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc index 1eda249..9c70075 100644 --- a/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc +++ b/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc
@@ -81,8 +81,9 @@ int misspelling_start = 0; int misspelling_length = 0; static_cast<blink::WebSpellCheckClient*>(provider()) - ->spellCheck(blink::WebString(base::WideToUTF16(test_cases[i].input)), - misspelling_start, misspelling_length, nullptr); + ->checkSpelling( + blink::WebString(base::WideToUTF16(test_cases[i].input)), + misspelling_start, misspelling_length, nullptr); EXPECT_EQ(test_cases[i].expected_misspelling_start, misspelling_start) << "Improper misspelling location found with the languages " @@ -233,8 +234,9 @@ int misspelling_start; int misspelling_length; static_cast<blink::WebSpellCheckClient*>(provider()) - ->spellCheck(blink::WebString(base::WideToUTF16(kTestCases[i].input)), - misspelling_start, misspelling_length, &suggestions); + ->checkSpelling( + blink::WebString(base::WideToUTF16(kTestCases[i].input)), + misspelling_start, misspelling_length, &suggestions); EXPECT_EQ(kTestCases[i].expected_misspelling_start, misspelling_start); EXPECT_EQ(kTestCases[i].expected_misspelling_length, misspelling_length);
diff --git a/components/spellcheck/renderer/spellcheck_provider.cc b/components/spellcheck/renderer/spellcheck_provider.cc index 097d0c96..9aeb92aa 100644 --- a/components/spellcheck/renderer/spellcheck_provider.cc +++ b/components/spellcheck/renderer/spellcheck_provider.cc
@@ -122,7 +122,7 @@ #endif // USE_BROWSER_SPELLCHECKER } -void SpellCheckProvider::spellCheck( +void SpellCheckProvider::checkSpelling( const WebString& text, int& offset, int& length,
diff --git a/components/spellcheck/renderer/spellcheck_provider.h b/components/spellcheck/renderer/spellcheck_provider.h index 682e43de..fd849f4 100644 --- a/components/spellcheck/renderer/spellcheck_provider.h +++ b/components/spellcheck/renderer/spellcheck_provider.h
@@ -76,7 +76,7 @@ void OnDestruct() override; // blink::WebSpellCheckClient implementation. - void spellCheck( + void checkSpelling( const blink::WebString& text, int& offset, int& length,
diff --git a/components/test_runner/spell_check_client.cc b/components/test_runner/spell_check_client.cc index 2173211..c2e562f 100644 --- a/components/test_runner/spell_check_client.cc +++ b/components/test_runner/spell_check_client.cc
@@ -44,7 +44,7 @@ } // blink::WebSpellCheckClient -void SpellCheckClient::spellCheck( +void SpellCheckClient::checkSpelling( const blink::WebString& text, int& misspelled_offset, int& misspelled_length,
diff --git a/components/test_runner/spell_check_client.h b/components/test_runner/spell_check_client.h index cb0d7ab..d9189c8 100644 --- a/components/test_runner/spell_check_client.h +++ b/components/test_runner/spell_check_client.h
@@ -41,7 +41,7 @@ void Reset(); // blink::WebSpellCheckClient implementation. - void spellCheck( + void checkSpelling( const blink::WebString& text, int& offset, int& length, @@ -62,7 +62,7 @@ // Tests related to spell checking should enable it manually. bool enabled_ = false; - // The mock spellchecker used in spellCheck(). + // The mock spellchecker used in checkSpelling(). MockSpellCheck spell_check_; blink::WebString last_requested_text_check_string_;
diff --git a/components/toolbar/toolbar_model_impl.cc b/components/toolbar/toolbar_model_impl.cc index b57c64b..b51addad3 100644 --- a/components/toolbar/toolbar_model_impl.cc +++ b/components/toolbar/toolbar_model_impl.cc
@@ -69,6 +69,9 @@ gfx::VectorIconId ToolbarModelImpl::GetVectorIcon() const { #if !defined(OS_ANDROID) && !defined(OS_IOS) + if (GetURL().SchemeIs("chrome-extension")) + return gfx::VectorIconId::EXTENSION; + switch (GetSecurityLevel(false)) { case security_state::NONE: case security_state::HTTP_SHOW_WARNING:
diff --git a/content/BUILD.gn b/content/BUILD.gn index 85f4a51..33c2d22 100644 --- a/content/BUILD.gn +++ b/content/BUILD.gn
@@ -92,6 +92,7 @@ "public/common/content_switches.cc", "public/common/content_switches.h", "public/common/mojo_channel_switches.cc", + "public/common/mojo_channel_switches.h", ] set_sources_assignment_filter(sources_assignment_filter)
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc index d311660a..3bca51b7 100644 --- a/content/browser/browser_child_process_host_impl.cc +++ b/content/browser/browser_child_process_host_impl.cc
@@ -297,6 +297,10 @@ data_.handle = handle; } +std::string BrowserChildProcessHostImpl::GetServiceRequestChannelToken() { + return child_connection_->service_token(); +} + void BrowserChildProcessHostImpl::ForceShutdown() { DCHECK_CURRENTLY_ON(BrowserThread::IO); g_child_process_list.Get().remove(this);
diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h index 9ac631e..08521db 100644 --- a/content/browser/browser_child_process_host_impl.h +++ b/content/browser/browser_child_process_host_impl.h
@@ -80,6 +80,7 @@ override; void SetName(const base::string16& name) override; void SetHandle(base::ProcessHandle handle) override; + std::string GetServiceRequestChannelToken() override; // ChildProcessHostDelegate implementation: bool CanShutdown() override;
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 32e5563..80a7c51 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -1205,10 +1205,6 @@ parts_->PostMainMessageLoopRun(); } -#if defined(USE_AURA) - env_.reset(); -#endif - system_stats_monitor_.reset(); // Destroying the GpuProcessHostUIShims on the UI thread posts a task to
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index bb77021..6295537f 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc
@@ -157,11 +157,6 @@ } void ResourceLoader::StartRequest() { - if (delegate_->HandleExternalProtocol(this, request_->url())) { - CancelAndIgnore(); - return; - } - // Give the handler a chance to delay the URLRequest from being started. bool defer_start = false; if (!handler_->OnWillStart(request_->url(), &defer_start)) { @@ -273,12 +268,6 @@ } } - if (delegate_->HandleExternalProtocol(this, redirect_info.new_url)) { - // The request is complete so we can remove it. - CancelAndIgnore(); - return; - } - scoped_refptr<ResourceResponse> response = new ResourceResponse(); PopulateResourceResponse(info, request_.get(), response.get()); delegate_->DidReceiveRedirect(this, redirect_info.new_url, response.get()); @@ -286,6 +275,12 @@ Cancel(); } else if (*defer) { deferred_stage_ = DEFERRED_REDIRECT; // Follow redirect when resumed. + DCHECK(deferred_redirect_url_.is_empty()); + deferred_redirect_url_ = redirect_info.new_url; + } else if (delegate_->HandleExternalProtocol(this, redirect_info.new_url)) { + // The request is complete so we can remove it. + CancelAndIgnore(); + return; } } @@ -450,7 +445,7 @@ StartRequestInternal(); break; case DEFERRED_REDIRECT: - request_->FollowDeferredRedirect(); + FollowDeferredRedirectInternal(); break; case DEFERRED_READ: base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -478,10 +473,17 @@ void ResourceLoader::StartRequestInternal() { DCHECK(!request_->is_pending()); + // Note: at this point any possible deferred start actions are already over. + if (!request_->status().is_success()) { return; } + if (delegate_->HandleExternalProtocol(this, request_->url())) { + CancelAndIgnore(); + return; + } + started_request_ = true; request_->Start(); @@ -534,6 +536,17 @@ } } +void ResourceLoader::FollowDeferredRedirectInternal() { + DCHECK(!deferred_redirect_url_.is_empty()); + GURL redirect_url = deferred_redirect_url_; + deferred_redirect_url_ = GURL(); + if (delegate_->HandleExternalProtocol(this, redirect_url)) { + CancelAndIgnore(); + } else { + request_->FollowDeferredRedirect(); + } +} + void ResourceLoader::CompleteResponseStarted() { ResourceRequestInfoImpl* info = GetRequestInfo(); scoped_refptr<ResourceResponse> response = new ResourceResponse();
diff --git a/content/browser/loader/resource_loader.h b/content/browser/loader/resource_loader.h index 43b7530..40603a4 100644 --- a/content/browser/loader/resource_loader.h +++ b/content/browser/loader/resource_loader.h
@@ -16,6 +16,7 @@ #include "content/browser/ssl/ssl_error_handler.h" #include "content/common/content_export.h" #include "net/url_request/url_request.h" +#include "url/gurl.h" namespace net { class X509Certificate; @@ -83,6 +84,7 @@ void StartRequestInternal(); void CancelRequestInternal(int error, bool from_renderer); + void FollowDeferredRedirectInternal(); void CompleteResponseStarted(); void ReadMore(bool is_continuation); void ResumeReading(); @@ -139,6 +141,9 @@ bool started_request_; int times_cancelled_after_request_start_; + // Stores the URL from a deferred redirect. + GURL deferred_redirect_url_; + base::WeakPtrFactory<ResourceLoader> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ResourceLoader);
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc index 6515453..cda1a544 100644 --- a/content/browser/loader/resource_loader_unittest.cc +++ b/content/browser/loader/resource_loader_unittest.cc
@@ -7,8 +7,10 @@ #include <stddef.h> #include <stdint.h> +#include <deque> #include <memory> #include <utility> +#include <vector> #include "base/files/file.h" #include "base/files/file_util.h" @@ -501,7 +503,18 @@ bool HandleExternalProtocol(ResourceLoader* loader, const GURL& url) override { EXPECT_EQ(loader, loader_.get()); - return false; + ++handle_external_protocol_; + + // Check that calls to HandleExternalProtocol always happen after the calls + // to the ResourceHandler's OnWillStart and OnRequestRedirected. + EXPECT_EQ(handle_external_protocol_, + raw_ptr_resource_handler_->on_will_start_called() + + raw_ptr_resource_handler_->on_request_redirected_called()); + + bool return_value = handle_external_protocol_results_.front(); + if (handle_external_protocol_results_.size() > 1) + handle_external_protocol_results_.pop_front(); + return return_value; } void DidStartRequest(ResourceLoader* loader) override { EXPECT_EQ(loader, loader_.get()); @@ -548,6 +561,12 @@ int did_received_redirect_ = 0; int did_receive_response_ = 0; int did_finish_loading_ = 0; + int handle_external_protocol_ = 0; + + // Allows controlling the return values of sequential calls to + // HandleExternalProtocol. Values are removed by the measure they are used + // but the last one which is used for all following calls. + std::deque<bool> handle_external_protocol_results_{false}; net::URLRequestJobFactoryImpl job_factory_; TestNetworkQualityEstimator network_quality_estimator_; @@ -749,6 +768,7 @@ EXPECT_EQ(1, did_received_redirect_); EXPECT_EQ(1, did_receive_response_); EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(2, handle_external_protocol_); EXPECT_EQ(1, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called()); EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); @@ -765,12 +785,53 @@ EXPECT_EQ(0, did_received_redirect_); EXPECT_EQ(1, did_receive_response_); EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(1, handle_external_protocol_); EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called()); EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body()); } +// Test the case where ResourceHandler defers nothing and the request is handled +// as an external protocol on start. +TEST_F(ResourceLoaderTest, SyncExternalProtocolHandlingOnStart) { + handle_external_protocol_results_ = {true}; + + loader_->StartRequest(); + raw_ptr_resource_handler_->WaitUntilResponseComplete(); + EXPECT_EQ(0, did_start_request_); + EXPECT_EQ(0, did_received_redirect_); + EXPECT_EQ(0, did_receive_response_); + EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(1, handle_external_protocol_); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); + EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called()); + EXPECT_EQ(net::ERR_ABORTED, + raw_ptr_resource_handler_->final_status().error()); + EXPECT_TRUE(raw_ptr_resource_handler_->body().empty()); +} + +// Test the case where ResourceHandler defers nothing and the request is handled +// as an external protocol on redirect. +TEST_F(ResourceLoaderTest, SyncExternalProtocolHandlingOnRedirect) { + handle_external_protocol_results_ = {false, true}; + + loader_->StartRequest(); + raw_ptr_resource_handler_->WaitUntilResponseComplete(); + EXPECT_EQ(1, did_start_request_); + EXPECT_EQ(1, did_received_redirect_); + EXPECT_EQ(0, did_receive_response_); + EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(2, handle_external_protocol_); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_request_redirected_called()); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called()); + EXPECT_EQ(net::ERR_ABORTED, + raw_ptr_resource_handler_->final_status().error()); + EXPECT_TRUE(raw_ptr_resource_handler_->body().empty()); +} + // Test the case the ResourceHandler defers everything. TEST_F(ResourceLoaderTest, AsyncResourceHandler) { raw_ptr_resource_handler_->set_defer_on_will_start(true); @@ -791,11 +852,13 @@ EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); + EXPECT_EQ(0, handle_external_protocol_); // Resume and run until OnRequestRedirected. raw_ptr_resource_handler_->Resume(); raw_ptr_resource_handler_->WaitUntilDeferred(); EXPECT_EQ(1, raw_ptr_resource_handler_->on_request_redirected_called()); + EXPECT_EQ(1, handle_external_protocol_); // Spinning the message loop should not advance the state further. base::RunLoop().RunUntilIdle(); @@ -804,11 +867,13 @@ EXPECT_EQ(1, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_will_read_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); + EXPECT_EQ(1, handle_external_protocol_); // Resume and run until OnResponseStarted. raw_ptr_resource_handler_->Resume(); raw_ptr_resource_handler_->WaitUntilDeferred(); EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_started_called()); + EXPECT_EQ(2, handle_external_protocol_); // Spinning the message loop should not advance the state further. base::RunLoop().RunUntilIdle(); @@ -830,7 +895,7 @@ EXPECT_EQ(0, raw_ptr_resource_handler_->on_read_eof()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); - // Resume and run until the final 0-byte read, signalling EOF. + // Resume and run until the final 0-byte read, signaling EOF. raw_ptr_resource_handler_->Resume(); raw_ptr_resource_handler_->WaitUntilDeferred(); EXPECT_EQ(1, raw_ptr_resource_handler_->on_read_eof()); @@ -860,6 +925,7 @@ EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called()); EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body()); + EXPECT_EQ(2, handle_external_protocol_); } // Same as above, except reads complete asynchronously and there's no redirect. @@ -883,11 +949,13 @@ EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); + EXPECT_EQ(0, handle_external_protocol_); // Resume and run until OnResponseStarted. raw_ptr_resource_handler_->Resume(); raw_ptr_resource_handler_->WaitUntilDeferred(); EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_started_called()); + EXPECT_EQ(1, handle_external_protocol_); // Spinning the message loop should not advance the state further. base::RunLoop().RunUntilIdle(); @@ -939,6 +1007,7 @@ EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called()); EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error()); EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body()); + EXPECT_EQ(1, handle_external_protocol_); } TEST_F(ResourceLoaderTest, SyncCancelOnWillStart) { @@ -949,6 +1018,7 @@ base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, did_start_request_); EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(0, handle_external_protocol_); EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_started_called()); @@ -968,6 +1038,7 @@ EXPECT_EQ(1, did_received_redirect_); EXPECT_EQ(0, did_receive_response_); EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(1, handle_external_protocol_); EXPECT_EQ(1, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_will_read_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_read_completed_called()); @@ -1090,6 +1161,7 @@ base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, did_start_request_); EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(0, handle_external_protocol_); EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_started_called()); @@ -1109,6 +1181,7 @@ EXPECT_EQ(1, did_received_redirect_); EXPECT_EQ(0, did_receive_response_); EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(1, handle_external_protocol_); EXPECT_EQ(1, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_will_read_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_read_completed_called()); @@ -1204,6 +1277,67 @@ EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body()); } +// Tests the request being deferred and then being handled as an external +// protocol, both on start. +TEST_F(ResourceLoaderTest, AsyncExternalProtocolHandlingOnStart) { + handle_external_protocol_results_ = {true}; + raw_ptr_resource_handler_->set_defer_on_will_start(true); + + loader_->StartRequest(); + raw_ptr_resource_handler_->WaitUntilDeferred(); + EXPECT_EQ(0, did_finish_loading_); + EXPECT_EQ(0, handle_external_protocol_); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); + EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); + + raw_ptr_resource_handler_->Resume(); + raw_ptr_resource_handler_->WaitUntilResponseComplete(); + EXPECT_EQ(0, did_start_request_); + EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(1, handle_external_protocol_); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); + EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); + EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_started_called()); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called()); + + EXPECT_EQ(net::ERR_ABORTED, + raw_ptr_resource_handler_->final_status().error()); + EXPECT_EQ("", raw_ptr_resource_handler_->body()); +} + +// Tests the request being deferred and then being handled as an external +// protocol, both on redirect. +TEST_F(ResourceLoaderTest, AsyncExternalProtocolHandlingOnRedirect) { + handle_external_protocol_results_ = {false, true}; + raw_ptr_resource_handler_->set_defer_on_request_redirected(true); + + loader_->StartRequest(); + raw_ptr_resource_handler_->WaitUntilDeferred(); + EXPECT_EQ(1, did_start_request_); + EXPECT_EQ(1, did_received_redirect_); + EXPECT_EQ(0, did_finish_loading_); + EXPECT_EQ(1, handle_external_protocol_); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_request_redirected_called()); + EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); + + raw_ptr_resource_handler_->Resume(); + raw_ptr_resource_handler_->WaitUntilResponseComplete(); + EXPECT_EQ(1, did_start_request_); + EXPECT_EQ(1, did_received_redirect_); + EXPECT_EQ(0, did_receive_response_); + EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(2, handle_external_protocol_); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_request_redirected_called()); + EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_started_called()); + EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called()); + + EXPECT_EQ(net::ERR_ABORTED, + raw_ptr_resource_handler_->final_status().error()); + EXPECT_EQ("", raw_ptr_resource_handler_->body()); +} + TEST_F(ResourceLoaderTest, RequestFailsOnStart) { SetUpResourceLoaderForUrl( net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase( @@ -1215,6 +1349,7 @@ EXPECT_EQ(0, did_received_redirect_); EXPECT_EQ(0, did_receive_response_); EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(1, handle_external_protocol_); EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_started_called()); @@ -1274,6 +1409,7 @@ EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_started_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); + EXPECT_EQ(1, handle_external_protocol_); raw_ptr_resource_handler_->CancelWithError(net::ERR_FAILED); raw_ptr_resource_handler_->WaitUntilResponseComplete(); @@ -1281,6 +1417,7 @@ EXPECT_EQ(0, did_received_redirect_); EXPECT_EQ(0, did_receive_response_); EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(1, handle_external_protocol_); EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_started_called()); @@ -1301,12 +1438,14 @@ EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_started_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_read_completed_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called()); + EXPECT_EQ(1, handle_external_protocol_); raw_ptr_resource_handler_->CancelWithError(net::ERR_FAILED); raw_ptr_resource_handler_->WaitUntilResponseComplete(); EXPECT_EQ(0, did_received_redirect_); EXPECT_EQ(1, did_receive_response_); EXPECT_EQ(1, did_finish_loading_); + EXPECT_EQ(1, handle_external_protocol_); EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called()); EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called()); EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_started_called());
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 7eab342..c6076ce6 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -114,10 +114,31 @@ BuiltinManifestProvider() {} ~BuiltinManifestProvider() override {} - void AddManifestValue(const std::string& name, - std::unique_ptr<base::Value> manifest_contents) { + void AddServiceManifest(base::StringPiece name, int resource_id) { + std::string contents = + GetContentClient() + ->GetDataResource(resource_id, ui::ScaleFactor::SCALE_FACTOR_NONE) + .as_string(); + DCHECK(!contents.empty()); + + std::unique_ptr<base::Value> manifest_value = + base::JSONReader::Read(contents); + DCHECK(manifest_value); + + std::unique_ptr<base::Value> overlay_value = + GetContentClient()->browser()->GetServiceManifestOverlay(name); + if (overlay_value) { + base::DictionaryValue* manifest_dictionary = nullptr; + bool result = manifest_value->GetAsDictionary(&manifest_dictionary); + DCHECK(result); + base::DictionaryValue* overlay_dictionary = nullptr; + result = overlay_value->GetAsDictionary(&overlay_dictionary); + DCHECK(result); + MergeDictionary(manifest_dictionary, overlay_dictionary); + } + auto result = manifests_.insert( - std::make_pair(name, std::move(manifest_contents))); + std::make_pair(name.as_string(), std::move(manifest_value))); DCHECK(result.second) << "Duplicate manifest entry: " << name; } @@ -238,30 +259,13 @@ }; for (size_t i = 0; i < arraysize(kManifests); ++i) { - std::string contents = GetContentClient()->GetDataResource( - kManifests[i].resource_id, - ui::ScaleFactor::SCALE_FACTOR_NONE).as_string(); - base::debug::Alias(&i); - CHECK(!contents.empty()); - - std::unique_ptr<base::Value> manifest_value = - base::JSONReader::Read(contents); - base::debug::Alias(&contents); - CHECK(manifest_value); - - std::unique_ptr<base::Value> overlay_value = - GetContentClient()->browser()->GetServiceManifestOverlay( - kManifests[i].name); - if (overlay_value) { - base::DictionaryValue* manifest_dictionary = nullptr; - CHECK(manifest_value->GetAsDictionary(&manifest_dictionary)); - base::DictionaryValue* overlay_dictionary = nullptr; - CHECK(overlay_value->GetAsDictionary(&overlay_dictionary)); - MergeDictionary(manifest_dictionary, overlay_dictionary); - } - - manifest_provider->AddManifestValue(kManifests[i].name, - std::move(manifest_value)); + manifest_provider->AddServiceManifest(kManifests[i].name, + kManifests[i].resource_id); + } + for (const auto& manifest : + GetContentClient()->browser()->GetExtraServiceManifests()) { + manifest_provider->AddServiceManifest(manifest.name, + manifest.resource_id); } in_process_context_ = new InProcessServiceManagerContext; request = in_process_context_->Start(std::move(manifest_provider));
diff --git a/content/public/browser/browser_child_process_host.h b/content/public/browser/browser_child_process_host.h index 7b5b9025..7f8bb93 100644 --- a/content/public/browser/browser_child_process_host.h +++ b/content/public/browser/browser_child_process_host.h
@@ -92,6 +92,9 @@ // this object. virtual void SetHandle(base::ProcessHandle handle) = 0; + // Returns the child message pipe token for the service request. + virtual std::string GetServiceRequestChannelToken() = 0; + #if defined(OS_MACOSX) // Returns a PortProvider used to get the task port for child processes. static base::PortProvider* GetPortProvider();
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 279bede..6db33e99e 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -420,10 +420,15 @@ #endif // defined(OS_WIN) std::unique_ptr<base::Value> ContentBrowserClient::GetServiceManifestOverlay( - const std::string& name) { + base::StringPiece name) { return nullptr; } +std::vector<ContentBrowserClient::ServiceManifestInfo> +ContentBrowserClient::GetExtraServiceManifests() { + return std::vector<ContentBrowserClient::ServiceManifestInfo>(); +} + std::unique_ptr<MemoryCoordinatorDelegate> ContentBrowserClient::GetMemoryCoordinatorDelegate() { return std::unique_ptr<MemoryCoordinatorDelegate>();
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 4c4c1cf6..9c78311f 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -709,7 +709,19 @@ // with content's own for |name|. Additional entries will be appended to their // respective sections. virtual std::unique_ptr<base::Value> GetServiceManifestOverlay( - const std::string& name); + base::StringPiece name); + + struct ServiceManifestInfo { + // The name of the service. + std::string name; + + // The resource ID of the manifest. + int resource_id; + }; + + // Allows the embedder to provide extra service manifests to be registered + // with the service manager context. + virtual std::vector<ServiceManifestInfo> GetExtraServiceManifests(); // Allows to override the visibility state of a RenderFrameHost. // |visibility_state| should not be null. It will only be set if needed.
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 2b44625..402b298 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -219,8 +219,7 @@ } std::unique_ptr<base::Value> -ShellContentBrowserClient::GetServiceManifestOverlay( - const std::string& name) { +ShellContentBrowserClient::GetServiceManifestOverlay(base::StringPiece name) { int id = -1; if (name == content::mojom::kBrowserServiceName) id = IDR_CONTENT_SHELL_BROWSER_MANIFEST_OVERLAY;
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h index d1937bfb..7b9d9d8 100644 --- a/content/shell/browser/shell_content_browser_client.h +++ b/content/shell/browser/shell_content_browser_client.h
@@ -39,7 +39,7 @@ void RegisterInProcessServices(StaticServiceMap* services) override; void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override; std::unique_ptr<base::Value> GetServiceManifestOverlay( - const std::string& name) override; + base::StringPiece name) override; void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; void ResourceDispatcherHostCreated() override;
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py index 1e022fe8..27c127d 100755 --- a/content/test/gpu/generate_buildbot_json.py +++ b/content/test/gpu/generate_buildbot_json.py
@@ -1087,17 +1087,6 @@ 'tab_capture_end2end_tests_run', ], }, - 'video_decode_accelerator_unittest': { - 'tester_configs': [ - { - 'os_types': ['win'] - }, - ], - 'args': [ - '--test_video_data=' - '../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1' - ], - }, } # This requires a hack because the isolate's name is different than
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index 7b26540a..4df0363 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -48,8 +48,6 @@ bug=660844) # WebGL 2.0.1 self.Fail('conformance2/rendering/rendering-sampling-feedback-loop.html', bug=660844) # WebGL 2.0.1 - self.Fail('conformance2/rendering/read-draw-when-missing-image.html', - ['linux', 'nvidia', 'opengl'], bug=672719) # WebGL 2.0.1 self.Fail('conformance2/textures/misc/' + 'integer-cubemap-specification-order-bug.html', bug=483282) # owner:cwallez, test might be buggy @@ -588,8 +586,6 @@ # Linux Intel with ANGLE only self.Fail('deqp/functional/gles3/framebufferblit/conversion_07.html', ['linux', 'intel', 'opengl'], bug=598902) - self.Fail('conformance2/rendering/read-draw-when-missing-image.html', - ['linux', 'intel', 'opengl'], bug=672719) # WebGL 2.0.1 # Linux AMD only. # It looks like AMD shader compiler rejects many valid ES3 semantics.
diff --git a/content/zygote/zygote_linux.cc b/content/zygote/zygote_linux.cc index c196a7fc..900463e4 100644 --- a/content/zygote/zygote_linux.cc +++ b/content/zygote/zygote_linux.cc
@@ -562,8 +562,9 @@ base::GlobalDescriptors::Mapping mapping; std::string process_type; std::string channel_id; - const std::string channel_id_prefix = std::string("--") - + switches::kMojoChannelToken + std::string("="); + const std::string channel_id_prefix = std::string("--") + + switches::kServiceRequestChannelToken + + std::string("="); if (!iter.ReadString(&process_type)) return -1;
diff --git a/docs/es6_chromium.md b/docs/es6_chromium.md index e9dc7c89..946a48a 100644 --- a/docs/es6_chromium.md +++ b/docs/es6_chromium.md
@@ -110,6 +110,46 @@ The following features are allowed in Chromium development. +## `=>` (Arrow Functions) + +Arrow functions provide a concise syntax to create a function, and fix a number +of difficulties with `this` (e.g. eliminating the need to write `const self = +this`). Particularly useful for nested functions or callbacks. + +Prefer arrow functions over `.bind(this)`. + +Arrow functions have an implicit return when used without a body block. + +**Usage Example:** + +```js +// General usage, eliminating need for .bind(this). +setTimeout(() => { + this.doSomething(); +}, 1000); // no need for .bind(this) or const self = this. + +// Another example... +window.addEventListener('scroll', (event) => { + this.doSomething(event); +}); // no need for .bind(this) or const self = this. + +// Implicit return: returns the value if expression not inside a body block. +() => 1 // returns 1. +() => {1} // returns undefined - body block does not implicitly return. +() => {return 1;} // returns 1. +``` + +**Documentation:** [link](http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions) + +**Discussion Notes / Link to Thread:** + +**Note**: => does not work in iOS9. Don't use it in code that runs on Chrome for +iOS. There's a presubmit that should warn you about this. + +[Discussion thread](https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/iJrC4PVSfoU) + +--- + ## `Promise` The Promise object is used for asynchronous computations. A Promise represents a @@ -224,41 +264,6 @@ --- -## `=>` (Arrow Functions) - -Arrow functions provide a concise syntax to create a function, and fix a number -of difficulties with `this` (e.g. eliminating the need to write `const self = -this`). Particularly useful for nested functions or callbacks. - -Prefer arrow functions over `.bind(this)`. - -Arrow functions have an implicit return when used without a body block. - -**Usage Example:** - -```js -// General usage, eliminating need for .bind(this). -setTimeout(() => { - this.doSomething(); -}, 1000); // no need for .bind(this) or const self = this. - -// Another example... -window.addEventListener('scroll', (event) => { - this.doSomething(event); -}); // no need for .bind(this) or const self = this. - -// Implicit return: returns the value if expression not inside a body block. -() => 1 // returns 1. -() => {1} // returns undefined - body block does not implicitly return. -() => {return 1;} // returns 1. -``` - -**Documentation:** [link](http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions) - -**Discussion Notes / Link to Thread:** - ---- - ## Classes OOP-style and boilerplate-free class syntax, including inheritance, `super()`,
diff --git a/extensions/renderer/BUILD.gn b/extensions/renderer/BUILD.gn index 03ee799..8579e36 100644 --- a/extensions/renderer/BUILD.gn +++ b/extensions/renderer/BUILD.gn
@@ -19,6 +19,8 @@ "api_activity_logger.h", "api_binding.cc", "api_binding.h", + "api_binding_bridge.cc", + "api_binding_bridge.h", "api_binding_hooks.cc", "api_binding_hooks.h", "api_binding_types.h",
diff --git a/extensions/renderer/api_binding.cc b/extensions/renderer/api_binding.cc index 35da283..bff8eba 100644 --- a/extensions/renderer/api_binding.cc +++ b/extensions/renderer/api_binding.cc
@@ -167,12 +167,16 @@ DCHECK(success.FromJust()); } - if (binding_hooks_) - binding_hooks_->InitializeInContext(context, api_name_); + binding_hooks_->InitializeInContext(context, api_name_); return object; } +v8::Local<v8::Object> APIBinding::GetJSHookInterface( + v8::Local<v8::Context> context) { + return binding_hooks_->GetJSHookInterface(api_name_, context); +} + void APIBinding::HandleCall(const std::string& name, const APISignature* signature, gin::Arguments* arguments) { @@ -185,8 +189,7 @@ v8::Local<v8::Context> context = isolate->GetCurrentContext(); // Check for a custom hook to handle the method. - if (binding_hooks_ && - binding_hooks_->HandleRequest(api_name_, name, context, + if (binding_hooks_->HandleRequest(api_name_, name, context, signature, arguments)) { return; // Handled by a custom hook. }
diff --git a/extensions/renderer/api_binding.h b/extensions/renderer/api_binding.h index 22fc44851..b4353a9 100644 --- a/extensions/renderer/api_binding.h +++ b/extensions/renderer/api_binding.h
@@ -75,6 +75,10 @@ APIEventHandler* event_handler, const AvailabilityCallback& is_available); + // Returns the JS interface to use when registering hooks with legacy custom + // bindings. + v8::Local<v8::Object> GetJSHookInterface(v8::Local<v8::Context> context); + private: // Handles a call an API method with the given |name| and matches the // arguments against |signature|. @@ -94,8 +98,7 @@ // The callback to use when an API is invoked with valid arguments. APIMethodCallback method_callback_; - // The registered hooks for this API. Null if there are no registered custom - // hooks. + // The registered hooks for this API. std::unique_ptr<APIBindingHooks> binding_hooks_; // The reference map for all known types; required to outlive this object.
diff --git a/extensions/renderer/api_binding_bridge.cc b/extensions/renderer/api_binding_bridge.cc new file mode 100644 index 0000000..e8321ff4 --- /dev/null +++ b/extensions/renderer/api_binding_bridge.cc
@@ -0,0 +1,99 @@ +// Copyright 2016 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. + +#include "extensions/renderer/api_binding_bridge.h" + +#include "gin/converter.h" +#include "gin/object_template_builder.h" + +namespace extensions { + +namespace { + +const char kApiObjectKey[] = "extensions::bridge::api_object"; +const char kHookInterfaceKey[] = "extensions::bridge::hook_object"; + +v8::Local<v8::Private> GetPrivatePropertyName(v8::Isolate* isolate, + const char* key) { + return v8::Private::ForApi(isolate, gin::StringToSymbol(isolate, key)); +} + +} // namespace + +gin::WrapperInfo APIBindingBridge::kWrapperInfo = {gin::kEmbedderNativeGin}; + +APIBindingBridge::APIBindingBridge(v8::Local<v8::Context> context, + v8::Local<v8::Value> api_object, + v8::Local<v8::Value> js_hook_interface, + const std::string& extension_id, + const std::string& context_type, + const binding::RunJSFunction& run_js) + : extension_id_(extension_id), + context_type_(context_type), + run_js_(run_js) { + v8::Isolate* isolate = context->GetIsolate(); + v8::Local<v8::Object> wrapper = GetWrapper(isolate); + v8::Maybe<bool> result = wrapper->SetPrivate( + context, GetPrivatePropertyName(isolate, kApiObjectKey), api_object); + if (!result.IsJust() || !result.FromJust()) { + NOTREACHED(); + return; + } + result = wrapper->SetPrivate(context, + GetPrivatePropertyName(isolate, + kHookInterfaceKey), + js_hook_interface); + DCHECK(result.IsJust() && result.FromJust()); +} + +APIBindingBridge::~APIBindingBridge() {} + +gin::ObjectTemplateBuilder APIBindingBridge::GetObjectTemplateBuilder( + v8::Isolate* isolate) { + return Wrappable<APIBindingBridge>::GetObjectTemplateBuilder(isolate) + .SetMethod("registerCustomHook", &APIBindingBridge::RegisterCustomHook); +} + +void APIBindingBridge::RegisterCustomHook(v8::Isolate* isolate, + v8::Local<v8::Function> function) { + // The object and arguments here are meant to match those passed to the hook + // functions in binding.js. + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + v8::Local<v8::Object> hook_object = v8::Object::New(isolate); + v8::Local<v8::Object> wrapper = GetWrapper(isolate); + v8::Local<v8::Value> hook_interface = + wrapper->GetPrivate( + context, GetPrivatePropertyName(isolate, kHookInterfaceKey)) + .ToLocalChecked(); + v8::Maybe<bool> result = hook_object->CreateDataProperty( + context, gin::StringToSymbol(isolate, "apiFunctions"), hook_interface); + if (!result.IsJust() || !result.FromJust()) + return; + + v8::Local<v8::Value> api_object = + wrapper + ->GetPrivate(context, GetPrivatePropertyName(isolate, kApiObjectKey)) + .ToLocalChecked(); + result = hook_object->CreateDataProperty( + context, gin::StringToSymbol(isolate, "compiledApi"), api_object); + if (!result.IsJust() || !result.FromJust()) + return; + + // TODO(devlin): The binding.js version of these hooks also has a 'schema' + // property. I wonder if we can factor that out? If not, we'll need to add it + // here. + + result = hook_object->SetPrototype(context, v8::Null(isolate)); + if (!result.IsJust() || !result.FromJust()) + return; + + v8::Local<v8::String> extension_id = + gin::StringToSymbol(isolate, extension_id_); + v8::Local<v8::String> context_type = + gin::StringToSymbol(isolate, context_type_); + v8::Local<v8::Value> args[] = {hook_object, extension_id, context_type}; + run_js_.Run(function, context, arraysize(args), args); +} + +} // namespace extensions
diff --git a/extensions/renderer/api_binding_bridge.h b/extensions/renderer/api_binding_bridge.h new file mode 100644 index 0000000..cfd85ea6 --- /dev/null +++ b/extensions/renderer/api_binding_bridge.h
@@ -0,0 +1,62 @@ +// Copyright 2016 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. + +#ifndef EXTENSIONS_RENDERER_API_BINDING_BRIDGE_H_ +#define EXTENSIONS_RENDERER_API_BINDING_BRIDGE_H_ + +#include <string> + +#include "base/macros.h" +#include "extensions/renderer/api_binding_types.h" +#include "gin/wrappable.h" +#include "v8/include/v8.h" + +namespace extensions { + +// An object that serves as a bridge between the current JS-centric bindings and +// the new native bindings system. This basically needs to conform to the public +// methods of the Binding prototype in binding.js. +class APIBindingBridge final : public gin::Wrappable<APIBindingBridge> { + public: + APIBindingBridge(v8::Local<v8::Context> context, + v8::Local<v8::Value> api_object, + v8::Local<v8::Value> js_hook_interface, + const std::string& extension_id, + const std::string& context_type, + const binding::RunJSFunction& run_js); + ~APIBindingBridge() override; + + static gin::WrapperInfo kWrapperInfo; + + // gin::Wrappable: + gin::ObjectTemplateBuilder GetObjectTemplateBuilder( + v8::Isolate* isolate) final; + + private: + // Runs the given function and registers custom hooks. + // The function takes three arguments: an object, + // { + // apiFunctions: <JSHookInterface> (see api_bindings_hooks.cc), + // compiledApi: <the API object> + // } + // as well as a string for the extension ID and a string for the context type. + // This should register any hooks that the JS needs for the given API. + void RegisterCustomHook(v8::Isolate* isolate, + v8::Local<v8::Function> function); + + // The id of the extension that owns the context this belongs to. + std::string extension_id_; + + // The type of context this belongs to. + std::string context_type_; + + // A function to run JS safely. + binding::RunJSFunction run_js_; + + DISALLOW_COPY_AND_ASSIGN(APIBindingBridge); +}; + +} // namespace extensions + +#endif // EXTENSIONS_RENDERER_API_BINDING_BRIDGE_H_
diff --git a/extensions/renderer/api_binding_hooks.cc b/extensions/renderer/api_binding_hooks.cc index b2540f4..108a563 100644 --- a/extensions/renderer/api_binding_hooks.cc +++ b/extensions/renderer/api_binding_hooks.cc
@@ -84,33 +84,6 @@ gin::WrapperInfo JSHookInterface::kWrapperInfo = {gin::kEmbedderNativeGin}; -// Creates and returns JS object for the hook interface to allow for -// registering custom hooks from JS. -v8::Local<v8::Object> CreateJSHookInterface(const std::string& api_name, - v8::Local<v8::Context> context) { - gin::PerContextData* per_context_data = gin::PerContextData::From(context); - DCHECK(per_context_data); - APIHooksPerContextData* data = static_cast<APIHooksPerContextData*>( - per_context_data->GetUserData(kExtensionAPIHooksPerContextKey)); - if (!data) { - auto api_data = - base::MakeUnique<APIHooksPerContextData>(context->GetIsolate()); - data = api_data.get(); - per_context_data->SetUserData(kExtensionAPIHooksPerContextKey, - api_data.release()); - } - - DCHECK(data->hook_interfaces.find(api_name) == data->hook_interfaces.end()); - - gin::Handle<JSHookInterface> hooks = - gin::CreateHandle(context->GetIsolate(), new JSHookInterface(api_name)); - CHECK(!hooks.IsEmpty()); - v8::Local<v8::Object> hooks_object = hooks.ToV8().As<v8::Object>(); - data->hook_interfaces[api_name].Reset(context->GetIsolate(), hooks_object); - - return hooks_object; -} - } // namespace APIBindingHooks::APIBindingHooks(const binding::RunJSFunction& run_js) @@ -168,7 +141,7 @@ std::vector<v8::Local<v8::Value>> v8_args; // TODO(devlin): Right now, this doesn't support exceptions or return values, // which we will need to at some point. - if (arguments->GetRemaining(&v8_args)) { + if (arguments->Length() == 0 || arguments->GetRemaining(&v8_args)) { v8::Local<v8::Function> handler = js_hook_iter->second.Get(context->GetIsolate()); run_js_.Run(handler, context, v8_args.size(), v8_args.data()); @@ -194,9 +167,37 @@ v8::Local<v8::Function> function; if (!gin::ConvertFromV8(context->GetIsolate(), func_as_value, &function)) return; - v8::Local<v8::Object> api_hooks = CreateJSHookInterface(api_name, context); + v8::Local<v8::Value> api_hooks = GetJSHookInterface(api_name, context); v8::Local<v8::Value> args[] = {api_hooks}; run_js_.Run(function, context, arraysize(args), args); } +v8::Local<v8::Object> APIBindingHooks::GetJSHookInterface( + const std::string& api_name, + v8::Local<v8::Context> context) { + gin::PerContextData* per_context_data = gin::PerContextData::From(context); + DCHECK(per_context_data); + APIHooksPerContextData* data = static_cast<APIHooksPerContextData*>( + per_context_data->GetUserData(kExtensionAPIHooksPerContextKey)); + if (!data) { + auto api_data = + base::MakeUnique<APIHooksPerContextData>(context->GetIsolate()); + data = api_data.get(); + per_context_data->SetUserData(kExtensionAPIHooksPerContextKey, + api_data.release()); + } + + auto iter = data->hook_interfaces.find(api_name); + if (iter != data->hook_interfaces.end()) + return iter->second.Get(context->GetIsolate()); + + gin::Handle<JSHookInterface> hooks = + gin::CreateHandle(context->GetIsolate(), new JSHookInterface(api_name)); + CHECK(!hooks.IsEmpty()); + v8::Local<v8::Object> hooks_object = hooks.ToV8().As<v8::Object>(); + data->hook_interfaces[api_name].Reset(context->GetIsolate(), hooks_object); + + return hooks_object; +} + } // namespace extensions
diff --git a/extensions/renderer/api_binding_hooks.h b/extensions/renderer/api_binding_hooks.h index 587425f4..9c74621 100644 --- a/extensions/renderer/api_binding_hooks.h +++ b/extensions/renderer/api_binding_hooks.h
@@ -63,6 +63,10 @@ const APISignature* signature, gin::Arguments* arguments); + // Returns a JS interface that can be used to register hooks. + v8::Local<v8::Object> GetJSHookInterface(const std::string& api_name, + v8::Local<v8::Context> context); + private: // Whether we've tried to use any hooks associated with this object. bool hooks_used_ = false;
diff --git a/extensions/renderer/api_binding_test.cc b/extensions/renderer/api_binding_test.cc index a6588b91..9312a34f 100644 --- a/extensions/renderer/api_binding_test.cc +++ b/extensions/renderer/api_binding_test.cc
@@ -15,6 +15,10 @@ APIBindingTest::APIBindingTest() {} APIBindingTest::~APIBindingTest() {} +v8::ExtensionConfiguration* APIBindingTest::GetV8ExtensionConfiguration() { + return nullptr; +} + void APIBindingTest::SetUp() { // Much of this initialization is stolen from the somewhat-similar // gin::V8Test. @@ -31,7 +35,8 @@ isolate()->Enter(); v8::HandleScope handle_scope(isolate()); - v8::Local<v8::Context> context = v8::Context::New(isolate()); + v8::Local<v8::Context> context = + v8::Context::New(isolate(), GetV8ExtensionConfiguration()); context->Enter(); context_holder_ = base::MakeUnique<gin::ContextHolder>(isolate()); context_holder_->SetContext(context);
diff --git a/extensions/renderer/api_binding_test.h b/extensions/renderer/api_binding_test.h index 8c2d3f8f..d72de47 100644 --- a/extensions/renderer/api_binding_test.h +++ b/extensions/renderer/api_binding_test.h
@@ -26,6 +26,10 @@ APIBindingTest(); ~APIBindingTest() override; + // Returns the V8 ExtensionConfiguration to use for contexts. The default + // implementation returns null. + virtual v8::ExtensionConfiguration* GetV8ExtensionConfiguration(); + // testing::Test: void SetUp() override; void TearDown() override;
diff --git a/extensions/renderer/api_binding_unittest.cc b/extensions/renderer/api_binding_unittest.cc index 1476ff4..04c1806 100644 --- a/extensions/renderer/api_binding_unittest.cc +++ b/extensions/renderer/api_binding_unittest.cc
@@ -196,7 +196,7 @@ APIBinding binding( "test", *functions, nullptr, nullptr, base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), - nullptr, &refs); + base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); EXPECT_TRUE(refs.empty()); v8::HandleScope handle_scope(isolate()); @@ -297,7 +297,7 @@ APIBinding binding( "test", *functions, types.get(), nullptr, base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), - nullptr, &refs); + base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); EXPECT_EQ(2u, refs.size()); EXPECT_TRUE(base::ContainsKey(refs, "refObj")); EXPECT_TRUE(base::ContainsKey(refs, "refEnum")); @@ -343,7 +343,7 @@ APIBinding binding( "test", *functions, nullptr, nullptr, base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), - nullptr, &refs); + base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = ContextLocal(); @@ -386,7 +386,7 @@ APIBinding binding( "test", *functions, nullptr, events.get(), base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), - nullptr, &refs); + base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); v8::HandleScope handle_scope(isolate()); v8::Local<v8::Context> context = ContextLocal(); @@ -422,7 +422,7 @@ APIBinding binding( "test", *functions, nullptr, nullptr, base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), - nullptr, &refs); + base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); EXPECT_TRUE(refs.empty()); v8::HandleScope handle_scope(isolate());
diff --git a/extensions/renderer/api_bindings_system.cc b/extensions/renderer/api_bindings_system.cc index 8ab880bb..5db72a0 100644 --- a/extensions/renderer/api_bindings_system.cc +++ b/extensions/renderer/api_bindings_system.cc
@@ -29,10 +29,13 @@ const std::string& api_name, v8::Local<v8::Context> context, v8::Isolate* isolate, - const APIBinding::AvailabilityCallback& is_available) { + const APIBinding::AvailabilityCallback& is_available, + v8::Local<v8::Object>* hooks_interface_out) { std::unique_ptr<APIBinding>& binding = api_bindings_[api_name]; if (!binding) binding = CreateNewAPIBinding(api_name); + if (hooks_interface_out) + *hooks_interface_out = binding->GetJSHookInterface(context); return binding->CreateInstance( context, isolate, &event_handler_, is_available); } @@ -49,12 +52,17 @@ const base::ListValue* event_definitions = nullptr; api_schema.GetList("events", &event_definitions); - // Find the hooks for the API, if any exist. + // Find the hooks for the API. If none exist, an empty set will be created so + // we can use JS custom bindings. + // TODO(devlin): Once all legacy custom bindings are converted, we don't have + // to unconditionally pass in binding hooks. std::unique_ptr<APIBindingHooks> hooks; auto iter = binding_hooks_.find(api_name); if (iter != binding_hooks_.end()) { hooks = std::move(iter->second); binding_hooks_.erase(iter); + } else { + hooks = base::MakeUnique<APIBindingHooks>(call_js_); } return base::MakeUnique<APIBinding>(
diff --git a/extensions/renderer/api_bindings_system.h b/extensions/renderer/api_bindings_system.h index e7173c4..1183392 100644 --- a/extensions/renderer/api_bindings_system.h +++ b/extensions/renderer/api_bindings_system.h
@@ -58,7 +58,8 @@ const std::string& api_name, v8::Local<v8::Context> context, v8::Isolate* isolate, - const APIBinding::AvailabilityCallback& is_available); + const APIBinding::AvailabilityCallback& is_available, + v8::Local<v8::Object>* hooks_interface_out); // Responds to the request with the given |request_id|, calling the callback // with |response|.
diff --git a/extensions/renderer/api_bindings_system_unittest.cc b/extensions/renderer/api_bindings_system_unittest.cc index 654f11a5..5a4ec225 100644 --- a/extensions/renderer/api_bindings_system_unittest.cc +++ b/extensions/renderer/api_bindings_system_unittest.cc
@@ -210,10 +210,10 @@ v8::Local<v8::Context> context = ContextLocal(); v8::Local<v8::Object> alpha_api = bindings_system()->CreateAPIInstance( - kAlphaAPIName, context, isolate(), base::Bind(&AllowAllAPIs)); + kAlphaAPIName, context, isolate(), base::Bind(&AllowAllAPIs), nullptr); ASSERT_FALSE(alpha_api.IsEmpty()); v8::Local<v8::Object> beta_api = bindings_system()->CreateAPIInstance( - kBetaAPIName, context, isolate(), base::Bind(&AllowAllAPIs)); + kBetaAPIName, context, isolate(), base::Bind(&AllowAllAPIs), nullptr); ASSERT_FALSE(beta_api.IsEmpty()); { @@ -321,7 +321,7 @@ base::Bind(hook, &did_call)); v8::Local<v8::Object> alpha_api = bindings_system()->CreateAPIInstance( - kAlphaAPIName, context, isolate(), base::Bind(&AllowAllAPIs)); + kAlphaAPIName, context, isolate(), base::Bind(&AllowAllAPIs), nullptr); ASSERT_FALSE(alpha_api.IsEmpty()); { @@ -408,7 +408,8 @@ auto add_api_to_chrome = [this, &chrome, &context](const std::string& api_name) { v8::Local<v8::Object> api = bindings_system()->CreateAPIInstance( - api_name, context, context->GetIsolate(), base::Bind(&AllowAllAPIs)); + api_name, context, context->GetIsolate(), base::Bind(&AllowAllAPIs), + nullptr); ASSERT_FALSE(api.IsEmpty()) << api_name; v8::Maybe<bool> res = chrome->Set( context, gin::StringToV8(context->GetIsolate(), api_name), api);
diff --git a/extensions/renderer/api_request_handler.cc b/extensions/renderer/api_request_handler.cc index e23e33b..3b31cd979 100644 --- a/extensions/renderer/api_request_handler.cc +++ b/extensions/renderer/api_request_handler.cc
@@ -55,6 +55,7 @@ pending_requests_.erase(iter); v8::Isolate* isolate = pending_request.isolate; + v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = pending_request.context.Get(isolate); std::unique_ptr<content::V8ValueConverter> converter( content::V8ValueConverter::create());
diff --git a/extensions/renderer/module_system.cc b/extensions/renderer/module_system.cc index 3cdf194d..3d7128ad 100644 --- a/extensions/renderer/module_system.cc +++ b/extensions/renderer/module_system.cc
@@ -542,6 +542,16 @@ &ModuleSystem::NativeLazyFieldGetter); } +void ModuleSystem::OnNativeBindingCreated( + const std::string& api_name, + v8::Local<v8::Value> api_bridge_value) { + v8::HandleScope scope(GetIsolate()); + if (source_map_->Contains(api_name)) { + NativesEnabledScope enabled(this); + LoadModuleWithNativeAPIBridge(api_name, api_bridge_value); + } +} + v8::Local<v8::Value> ModuleSystem::RunString(v8::Local<v8::String> code, v8::Local<v8::String> name) { return context_->RunScript( @@ -622,7 +632,7 @@ v8::Local<v8::String> left = ToV8StringUnsafe( GetIsolate(), "(function(define, require, requireNative, requireAsync, exports, " - "console, privates," + "console, privates, apiBridge," "$Array, $Function, $JSON, $Object, $RegExp, $String, $Error) {" "'use strict';"); v8::Local<v8::String> right = ToV8StringUnsafe(GetIsolate(), "\n})"); @@ -660,6 +670,13 @@ } v8::Local<v8::Value> ModuleSystem::LoadModule(const std::string& module_name) { + return LoadModuleWithNativeAPIBridge(module_name, + v8::Undefined(GetIsolate())); +} + +v8::Local<v8::Value> ModuleSystem::LoadModuleWithNativeAPIBridge( + const std::string& module_name, + v8::Local<v8::Value> api_bridge) { v8::EscapableHandleScope handle_scope(GetIsolate()); v8::Local<v8::Context> v8_context = context()->v8_context(); v8::Context::Scope context_scope(v8_context); @@ -729,6 +746,7 @@ console::AsV8Object(GetIsolate()), GetPropertyUnsafe(v8_context, natives, "privates", v8::NewStringType::kInternalized), + api_bridge, // exposed as apiBridge. // Each safe builtin. Keep in order with the arguments in WrapSource. context_->safe_builtins()->GetArray(), context_->safe_builtins()->GetFunction(),
diff --git a/extensions/renderer/module_system.h b/extensions/renderer/module_system.h index 75f5819..c15ffb0 100644 --- a/extensions/renderer/module_system.h +++ b/extensions/renderer/module_system.h
@@ -153,6 +153,13 @@ exception_handler_ = std::move(handler); } + // Called when a native binding is created in order to run any custom binding + // code to set up various hooks. + // TODO(devlin): We can get rid of this once we convert all our custom + // bindings. + void OnNativeBindingCreated(const std::string& api_name, + v8::Local<v8::Value> api_bridge_value); + protected: friend class ModuleSystemTestEnvironment; friend class ScriptContext; @@ -209,6 +216,9 @@ // Loads and runs a Javascript module. v8::Local<v8::Value> LoadModule(const std::string& module_name); + v8::Local<v8::Value> LoadModuleWithNativeAPIBridge( + const std::string& module_name, + v8::Local<v8::Value> api_object); // Invoked when a module is loaded in response to a requireAsync call. // Resolves |resolver| with |value|.
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc index cfd3e47be..0669c14 100644 --- a/extensions/renderer/native_extension_bindings_system.cc +++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -10,9 +10,13 @@ #include "extensions/common/extension_api.h" #include "extensions/common/extension_messages.h" #include "extensions/common/features/feature_provider.h" +#include "extensions/renderer/api_binding_bridge.h" +#include "extensions/renderer/api_binding_hooks.h" +#include "extensions/renderer/module_system.h" #include "extensions/renderer/script_context.h" #include "extensions/renderer/script_context_set.h" #include "gin/converter.h" +#include "gin/handle.h" #include "gin/per_context_data.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" @@ -113,6 +117,7 @@ void NativeExtensionBindingsSystem::UpdateBindingsForContext( ScriptContext* context) { + v8::HandleScope handle_scope(context->isolate()); v8::Local<v8::Context> v8_context = context->v8_context(); v8::Local<v8::Object> chrome = GetOrCreateChrome(v8_context); if (chrome.IsEmpty()) @@ -232,13 +237,28 @@ if (has_property.FromJust()) { result = apis->GetRealNamedProperty(context, api_name).ToLocalChecked(); } else { + ScriptContext* script_context = + ScriptContextSet::GetContextByV8Context(context); std::string api_name_string; CHECK(gin::Converter<std::string>::FromV8(isolate, api_name, &api_name_string)); - result = data->bindings_system->api_system_.CreateAPIInstance( + v8::Local<v8::Object> hooks_interface; + APIBindingsSystem& api_system = data->bindings_system->api_system_; + result = api_system.CreateAPIInstance( api_name_string, context, isolate, - base::Bind(&IsAPIMethodAvailable, - ScriptContextSet::GetContextByV8Context(context))); + base::Bind(&IsAPIMethodAvailable, script_context), &hooks_interface); + + gin::Handle<APIBindingBridge> bridge_handle = gin::CreateHandle( + isolate, + new APIBindingBridge(context, result, hooks_interface, + script_context->GetExtensionID(), + script_context->GetContextTypeDescription(), + base::Bind(&CallJsFunction))); + v8::Local<v8::Value> native_api_bridge = bridge_handle.ToV8(); + + script_context->module_system()->OnNativeBindingCreated(api_name_string, + native_api_bridge); + v8::Maybe<bool> success = apis->CreateDataProperty(context, api_name, result); if (!success.IsJust() || !success.FromJust())
diff --git a/extensions/renderer/native_extension_bindings_system_unittest.cc b/extensions/renderer/native_extension_bindings_system_unittest.cc index ea5d5bb..62d4d99d 100644 --- a/extensions/renderer/native_extension_bindings_system_unittest.cc +++ b/extensions/renderer/native_extension_bindings_system_unittest.cc
@@ -6,6 +6,7 @@ #include "base/memory/ptr_util.h" #include "base/run_loop.h" +#include "base/strings/stringprintf.h" #include "components/crx_file/id_util.h" #include "extensions/common/extension.h" #include "extensions/common/extension_builder.h" @@ -15,8 +16,12 @@ #include "extensions/common/value_builder.h" #include "extensions/renderer/api_binding_test.h" #include "extensions/renderer/api_binding_test_util.h" +#include "extensions/renderer/module_system.h" +#include "extensions/renderer/safe_builtins.h" #include "extensions/renderer/script_context.h" #include "extensions/renderer/script_context_set.h" +#include "extensions/renderer/string_source_map.h" +#include "extensions/renderer/test_v8_extension_configuration.h" namespace extensions { @@ -52,6 +57,10 @@ ~NativeExtensionBindingsSystemUnittest() override {} protected: + v8::ExtensionConfiguration* GetV8ExtensionConfiguration() override { + return TestV8ExtensionConfiguration::GetConfiguration(); + } + void SetUp() override { script_context_set_ = base::MakeUnique<ScriptContextSet>(&extension_ids_); bindings_system_ = base::MakeUnique<NativeExtensionBindingsSystem>( @@ -87,6 +96,8 @@ Feature::Context context_type) { auto script_context = base::MakeUnique<ScriptContext>( v8_context, nullptr, extension, context_type, extension, context_type); + script_context->set_module_system( + base::MakeUnique<ModuleSystem>(script_context.get(), source_map())); ScriptContext* raw_script_context = script_context.get(); raw_script_contexts_.push_back(raw_script_context); script_context_set_->AddForTesting(std::move(script_context)); @@ -99,6 +110,7 @@ return bindings_system_.get(); } const ExtensionHostMsg_Request_Params& last_params() { return last_params_; } + StringSourceMap* source_map() { return &source_map_; } private: ExtensionIdSet extension_ids_; @@ -106,6 +118,7 @@ std::vector<ScriptContext*> raw_script_contexts_; std::unique_ptr<NativeExtensionBindingsSystem> bindings_system_; ExtensionHostMsg_Request_Params last_params_; + StringSourceMap source_map_; DISALLOW_COPY_AND_ASSIGN(NativeExtensionBindingsSystemUnittest); }; @@ -260,4 +273,82 @@ EXPECT_TRUE(power_object->IsUndefined()); } +// Tests that traditional custom bindings can be used with the native bindings +// system. +TEST_F(NativeExtensionBindingsSystemUnittest, TestBridgingToJSCustomBindings) { + // Custom binding code. This basically utilizes the interface in binding.js in + // order to test backwards compatibility. + const char kCustomBinding[] = + "apiBridge.registerCustomHook((api, extensionId, contextType) => {\n" + " api.apiFunctions.setHandleRequest('queryState',\n" + " (time, callback) => {\n" + " this.timeArg = time;\n" + " callback('active');\n" + " });\n" + " this.hookedExtensionId = extensionId;\n" + " this.hookedContextType = contextType;\n" + " api.compiledApi.hookedApiProperty = 'someProperty';\n" + "});\n"; + + source_map()->RegisterModule("idle", kCustomBinding); + + scoped_refptr<Extension> extension = CreateExtension("foo", {"idle"}); + RegisterExtension(extension->id()); + + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = ContextLocal(); + + ScriptContext* script_context = CreateScriptContext( + context, extension.get(), Feature::BLESSED_EXTENSION_CONTEXT); + script_context->set_url(extension->url()); + + bindings_system()->UpdateBindingsForContext(script_context); + + { + // Call the function correctly. + const char kCallIdleQueryState[] = + "(function() {\n" + " chrome.idle.queryState(30, function(state) {\n" + " this.responseState = state;\n" + " });\n" + "});"; + + v8::Local<v8::Function> call_idle_query_state = + FunctionFromString(context, kCallIdleQueryState); + RunFunctionOnGlobal(call_idle_query_state, context, 0, nullptr); + } + + auto get_property_as_string = [&context](v8::Local<v8::Object> object, + base::StringPiece property_name) { + std::unique_ptr<base::Value> property = + GetBaseValuePropertyFromObject(object, context, property_name); + if (!property) + return std::string(); + return ValueToString(*property); + }; + + // To start, check that the properties we set when running the hooks are + // correct. We do this after calling the function because the API objects (and + // thus the hooks) are set up lazily. + v8::Local<v8::Object> global = context->Global(); + EXPECT_EQ(base::StringPrintf("\"%s\"", extension->id().c_str()), + get_property_as_string(global, "hookedExtensionId")); + EXPECT_EQ("\"BLESSED_EXTENSION\"", + get_property_as_string(global, "hookedContextType")); + v8::Local<v8::Value> idle_api = + V8ValueFromScriptSource(context, "chrome.idle"); + ASSERT_FALSE(idle_api.IsEmpty()); + ASSERT_TRUE(idle_api->IsObject()); + EXPECT_EQ("\"someProperty\"", + get_property_as_string(idle_api.As<v8::Object>(), + "hookedApiProperty")); + + // Next, we need to check two pieces: first, that the custom handler was + // called with the proper arguments.... + EXPECT_EQ("30", get_property_as_string(global, "timeArg")); + + // ...and second, that the callback was called with the proper result. + EXPECT_EQ("\"active\"", get_property_as_string(global, "responseState")); +} + } // namespace extensions
diff --git a/extensions/renderer/resources/test_custom_bindings.js b/extensions/renderer/resources/test_custom_bindings.js index 2737efeb..00753315 100644 --- a/extensions/renderer/resources/test_custom_bindings.js +++ b/extensions/renderer/resources/test_custom_bindings.js
@@ -5,7 +5,7 @@ // test_custom_bindings.js // mini-framework for ExtensionApiTest browser tests -var binding = require('binding').Binding.create('test'); +var binding = apiBridge || require('binding').Binding.create('test'); var environmentSpecificBindings = require('test_environment_specific_bindings'); var GetExtensionAPIDefinitionsForTest = @@ -357,4 +357,5 @@ environmentSpecificBindings.registerHooks(api); }); -exports.$set('binding', binding.generate()); +if (!apiBridge) + exports.$set('binding', binding.generate());
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index a9e5d3c..8fe53bb 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -8015,12 +8015,14 @@ const Framebuffer::Attachment* read_buffer = is_feedback_loop == FeedbackLoopUnknown ? read_framebuffer->GetReadBufferAttachment() : nullptr; + bool draw_buffer_has_image = false; for (uint32_t ii = 0; ii < group_->max_draw_buffers(); ++ii) { GLenum dst_format = GetBoundColorDrawBufferInternalFormat( static_cast<GLint>(ii)); GLenum dst_type = GetBoundColorDrawBufferType(static_cast<GLint>(ii)); if (dst_format == 0) continue; + draw_buffer_has_image = true; if (!src_internal_format) { read_framebuffer_miss_image = true; } @@ -8057,6 +8059,8 @@ } } } + if (draw_framebuffer && !draw_buffer_has_image) + mask_blit &= ~GL_COLOR_BUFFER_BIT; } if (is_feedback_loop == FeedbackLoopTrue) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name, @@ -15876,7 +15880,6 @@ return error::kNoError; } break; - case GL_SAMPLES_PASSED: case GL_ANY_SAMPLES_PASSED: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: if (!features().occlusion_query_boolean) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index 5e02f31..5c88abf 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -1484,6 +1484,17 @@ int entries_per_cmd_; }; +TEST_P(GLES3DecoderTest, BeginInvalidTargetQueryFails) { + BeginQueryEXT begin_cmd; + begin_cmd.Init(GL_SAMPLES_PASSED, + kNewClientId, + kSharedMemoryId, + kSharedMemoryOffset); + EXPECT_EQ(error::kNoError, ExecuteCmd(begin_cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); +} + + TEST_P(GLES3DecoderTest, BindTransformFeedbackValidArgs) { EXPECT_CALL(*gl_, BindTransformFeedback(GL_TRANSFORM_FEEDBACK, kServiceTransformFeedbackId));
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index 2f39568..6b93df46 100644 --- a/gpu/config/gpu_driver_bug_list_json.cc +++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@ { "name": "gpu driver bug list", // Please update the version number whenever you change this file. - "version": "9.25", + "version": "9.26", "entries": [ { "id": 1, @@ -1739,7 +1739,11 @@ "description": "Mac Drivers store texture level parameters on int16_t that overflow", "cr_bugs": [610153], "os": { - "type": "macosx" + "type": "macosx", + "version": { + "op": "<", + "value": "10.12.2" + } }, "features": [ "use_shadowed_tex_level_params"
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index 1bfe88ff..8ba656c 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -61,7 +61,7 @@ std::unique_ptr<base::Value> HeadlessContentBrowserClient::GetServiceManifestOverlay( - const std::string& name) { + base::StringPiece name) { if (name != content::mojom::kBrowserServiceName || browser_->options()->mojo_service_names.empty()) return nullptr;
diff --git a/headless/lib/browser/headless_content_browser_client.h b/headless/lib/browser/headless_content_browser_client.h index 511083bf..3f44381 100644 --- a/headless/lib/browser/headless_content_browser_client.h +++ b/headless/lib/browser/headless_content_browser_client.h
@@ -23,7 +23,7 @@ content::WebPreferences* prefs) override; content::DevToolsManagerDelegate* GetDevToolsManagerDelegate() override; std::unique_ptr<base::Value> GetServiceManifestOverlay( - const std::string& name) override; + base::StringPiece name) override; private: HeadlessBrowserImpl* browser_; // Not owned.
diff --git a/media/gpu/media_foundation_video_encode_accelerator_win.cc b/media/gpu/media_foundation_video_encode_accelerator_win.cc index 05948420..a43e2ad 100644 --- a/media/gpu/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/media_foundation_video_encode_accelerator_win.cc
@@ -34,13 +34,12 @@ const int32_t kDefaultTargetBitrate = 5000000; const size_t kMaxFrameRateNumerator = 30; const size_t kMaxFrameRateDenominator = 1; -const size_t kMaxResolutionWidth = 1920; -const size_t kMaxResolutionHeight = 1088; +const size_t kMaxResolutionWidth = 3840; +const size_t kMaxResolutionHeight = 2176; const size_t kNumInputBuffers = 3; // Media Foundation uses 100 nanosecond units for time, see // https://msdn.microsoft.com/en-us/library/windows/desktop/ms697282(v=vs.85).aspx const size_t kOneMicrosecondInMFSampleTimeUnits = 10; -const size_t kOneSecondInMFSampleTimeUnits = 10000000; const size_t kOutputSampleBufferSizeRatio = 4; constexpr const wchar_t* const kMediaFoundationVideoEncoderDLLs[] = { @@ -177,7 +176,6 @@ input_visible_size_) .GetArea(); - if (!SetEncoderModes()) { DLOG(ERROR) << "Failed setting encoder parameters."; return false; @@ -187,13 +185,27 @@ DLOG(ERROR) << "Failed initializing input-output samples."; return false; } - input_sample_.Attach(mf::CreateEmptySampleWithBuffer( - VideoFrame::AllocationSize(PIXEL_FORMAT_I420, input_visible_size_), 2)); - output_sample_.Attach(mf::CreateEmptySampleWithBuffer( - bitstream_buffer_size_ * kOutputSampleBufferSizeRatio, 2)); + MFT_INPUT_STREAM_INFO input_stream_info; HRESULT hr = - encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL); + encoder_->GetInputStreamInfo(input_stream_id_, &input_stream_info); + RETURN_ON_HR_FAILURE(hr, "Couldn't get input stream info", false); + input_sample_.Attach(mf::CreateEmptySampleWithBuffer( + input_stream_info.cbSize + ? input_stream_info.cbSize + : VideoFrame::AllocationSize(PIXEL_FORMAT_I420, input_visible_size_), + input_stream_info.cbAlignment)); + + MFT_OUTPUT_STREAM_INFO output_stream_info; + hr = encoder_->GetOutputStreamInfo(output_stream_id_, &output_stream_info); + RETURN_ON_HR_FAILURE(hr, "Couldn't get output stream info", false); + output_sample_.Attach(mf::CreateEmptySampleWithBuffer( + output_stream_info.cbSize + ? output_stream_info.cbSize + : bitstream_buffer_size_ * kOutputSampleBufferSizeRatio, + output_stream_info.cbAlignment)); + + hr = encoder_->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, NULL); RETURN_ON_HR_FAILURE(hr, "Couldn't set ProcessMessage", false); // Pin all client callbacks to the main task runner initially. It can be @@ -340,8 +352,33 @@ bool MediaFoundationVideoEncodeAccelerator::InitializeInputOutputSamples() { DCHECK(main_client_task_runner_->BelongsToCurrentThread()); + DWORD input_count = 0; + DWORD output_count = 0; + HRESULT hr = encoder_->GetStreamCount(&input_count, &output_count); + RETURN_ON_HR_FAILURE(hr, "Couldn't get stream count", false); + if (input_count < 1 || output_count < 1) { + LOG(ERROR) << "Stream count too few: input " << input_count << ", output " + << output_count; + return false; + } + + std::vector<DWORD> input_ids(input_count, 0); + std::vector<DWORD> output_ids(output_count, 0); + hr = encoder_->GetStreamIDs(input_count, input_ids.data(), output_count, + output_ids.data()); + if (hr == S_OK) { + input_stream_id_ = input_ids[0]; + output_stream_id_ = output_ids[0]; + } else if (hr == E_NOTIMPL) { + input_stream_id_ = 0; + output_stream_id_ = 0; + } else { + LOG(ERROR) << "Couldn't find stream ids."; + return false; + } + // Initialize output parameters. - HRESULT hr = MFCreateMediaType(imf_output_media_type_.Receive()); + hr = MFCreateMediaType(imf_output_media_type_.Receive()); RETURN_ON_HR_FAILURE(hr, "Couldn't create media type", false); hr = imf_output_media_type_->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video); RETURN_ON_HR_FAILURE(hr, "Couldn't set media type", false); @@ -350,7 +387,7 @@ hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); hr = MFSetAttributeRatio(imf_output_media_type_.get(), MF_MT_FRAME_RATE, - frame_rate_, kMaxFrameRateDenominator); + frame_rate_, 1); RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); hr = MFSetAttributeSize(imf_output_media_type_.get(), MF_MT_FRAME_SIZE, input_visible_size_.width(), @@ -362,7 +399,8 @@ hr = imf_output_media_type_->SetUINT32(MF_MT_MPEG2_PROFILE, eAVEncH264VProfile_Base); RETURN_ON_HR_FAILURE(hr, "Couldn't set codec profile", false); - hr = encoder_->SetOutputType(0, imf_output_media_type_.get(), 0); + hr = encoder_->SetOutputType(output_stream_id_, imf_output_media_type_.get(), + 0); RETURN_ON_HR_FAILURE(hr, "Couldn't set output media type", false); // Initialize input parameters. @@ -373,7 +411,7 @@ hr = imf_input_media_type_->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_YV12); RETURN_ON_HR_FAILURE(hr, "Couldn't set video format", false); hr = MFSetAttributeRatio(imf_input_media_type_.get(), MF_MT_FRAME_RATE, - frame_rate_, kMaxFrameRateDenominator); + frame_rate_, 1); RETURN_ON_HR_FAILURE(hr, "Couldn't set frame rate", false); hr = MFSetAttributeSize(imf_input_media_type_.get(), MF_MT_FRAME_SIZE, input_visible_size_.width(), @@ -382,7 +420,7 @@ hr = imf_input_media_type_->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive); RETURN_ON_HR_FAILURE(hr, "Couldn't set interlace mode", false); - hr = encoder_->SetInputType(0, imf_input_media_type_.get(), 0); + hr = encoder_->SetInputType(input_stream_id_, imf_input_media_type_.get(), 0); RETURN_ON_HR_FAILURE(hr, "Couldn't set input media type", false); return SUCCEEDED(hr); @@ -401,7 +439,7 @@ var.ulVal = target_bitrate_; hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", false); - var.ulVal = eAVEncAdaptiveMode_FrameRate; + var.ulVal = eAVEncAdaptiveMode_Resolution; hr = codec_api_->SetValue(&CODECAPI_AVEncAdaptiveMode, &var); RETURN_ON_HR_FAILURE(hr, "Couldn't set FrameRate", false); var.vt = VT_BOOL; @@ -446,19 +484,23 @@ input_sample_->SetSampleTime(frame->timestamp().InMicroseconds() * kOneMicrosecondInMFSampleTimeUnits); - input_sample_->SetSampleDuration(kOneSecondInMFSampleTimeUnits / frame_rate_); + UINT64 sample_duration = 1; + HRESULT hr = + MFFrameRateToAverageTimePerFrame(frame_rate_, 1, &sample_duration); + RETURN_ON_HR_FAILURE(hr, "Couldn't calculate sample duration", ); + input_sample_->SetSampleDuration(sample_duration); // Release frame after input is copied. frame = nullptr; - HRESULT hr = encoder_->ProcessInput(0, input_sample_.get(), 0); + hr = encoder_->ProcessInput(input_stream_id_, input_sample_.get(), 0); // According to MSDN, if encoder returns MF_E_NOTACCEPTING, we need to try // processing the output. This error indicates that encoder does not accept // any more input data. if (hr == MF_E_NOTACCEPTING) { DVLOG(3) << "MF_E_NOTACCEPTING"; ProcessOutput(); - hr = encoder_->ProcessInput(0, input_sample_.get(), 0); + hr = encoder_->ProcessInput(input_stream_id_, input_sample_.get(), 0); if (!SUCCEEDED(hr)) { NotifyError(kPlatformFailureError); RETURN_ON_HR_FAILURE(hr, "Couldn't encode", ); @@ -476,15 +518,24 @@ DVLOG(3) << __func__; DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); + DWORD output_status = 0; + HRESULT hr = encoder_->GetOutputStatus(&output_status); + RETURN_ON_HR_FAILURE(hr, "Couldn't get output status", ); + if (output_status != MFT_OUTPUT_STATUS_SAMPLE_READY) { + DVLOG(3) << "Output isnt ready"; + return; + } + MFT_OUTPUT_DATA_BUFFER output_data_buffer = {0}; output_data_buffer.dwStreamID = 0; output_data_buffer.dwStatus = 0; output_data_buffer.pEvents = NULL; output_data_buffer.pSample = output_sample_.get(); DWORD status = 0; - HRESULT hr = encoder_->ProcessOutput(0, 1, &output_data_buffer, &status); + hr = encoder_->ProcessOutput(output_stream_id_, 1, &output_data_buffer, + &status); if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { - DVLOG(3) << "MF_E_TRANSFORM_NEED_MORE_INPUT"; + DVLOG(3) << "MF_E_TRANSFORM_NEED_MORE_INPUT" << status; return; } RETURN_ON_HR_FAILURE(hr, "Couldn't get encoded data", ); @@ -580,20 +631,19 @@ DVLOG(3) << __func__; DCHECK(encoder_thread_task_runner_->BelongsToCurrentThread()); - frame_rate_ = framerate ? framerate : 1; - target_bitrate_ = bitrate ? bitrate : 1; + frame_rate_ = + framerate + ? std::min(framerate, static_cast<uint32_t>(kMaxFrameRateNumerator)) + : 1; - VARIANT var; - var.vt = VT_UI4; - var.ulVal = target_bitrate_; - HRESULT hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); - RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", ); - - hr = imf_output_media_type_->SetUINT32(MF_MT_AVG_BITRATE, target_bitrate_); - RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", ); - hr = MFSetAttributeRatio(imf_output_media_type_.get(), MF_MT_FRAME_RATE, - frame_rate_, kMaxFrameRateDenominator); - RETURN_ON_HR_FAILURE(hr, "Couldn't set output type params", ); + if (target_bitrate_ != bitrate) { + target_bitrate_ = bitrate ? bitrate : 1; + VARIANT var; + var.vt = VT_UI4; + var.ulVal = target_bitrate_; + HRESULT hr = codec_api_->SetValue(&CODECAPI_AVEncCommonMeanBitRate, &var); + RETURN_ON_HR_FAILURE(hr, "Couldn't set bitrate", ); + } } void MediaFoundationVideoEncodeAccelerator::DestroyTask() {
diff --git a/media/gpu/media_foundation_video_encode_accelerator_win.h b/media/gpu/media_foundation_video_encode_accelerator_win.h index 5e46694..cd67630 100644 --- a/media/gpu/media_foundation_video_encode_accelerator_win.h +++ b/media/gpu/media_foundation_video_encode_accelerator_win.h
@@ -115,14 +115,17 @@ gfx::Size input_visible_size_; size_t bitstream_buffer_size_; - int32_t frame_rate_; - int32_t target_bitrate_; + uint32_t frame_rate_; + uint32_t target_bitrate_; size_t u_plane_offset_; size_t v_plane_offset_; base::win::ScopedComPtr<IMFTransform> encoder_; base::win::ScopedComPtr<ICodecAPI> codec_api_; + DWORD input_stream_id_; + DWORD output_stream_id_; + base::win::ScopedComPtr<IMFMediaType> imf_input_media_type_; base::win::ScopedComPtr<IMFMediaType> imf_output_media_type_;
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_empy_enum_array.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_empy_enum_array.data new file mode 100644 index 0000000..21af8a3 --- /dev/null +++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_empy_enum_array.data
@@ -0,0 +1,22 @@ +[dist4]message_header // num_bytes +[u4]0 // version +[u4]0 // interface ID +[u4]15 // name +[u4]0 // flags +[u4]0 // padding +[anchr]message_header + +[dist4]method15_params // num_bytes +[u4]0 // version +[dist8]enum_array_0 // param0 +[u8]0 // param1 +[anchr]method15_params + +[anchr]enum_array_0 +[dist4]enum_array_0_member // num_bytes +[u4]0 // num_elements +[anchr]enum_array_0_member + +[u8]0x5678 // This is not part of the array above (which is + // empty), so enum validation shouldn't be done on + // it.
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_empy_enum_array.expected b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_empy_enum_array.expected new file mode 100644 index 0000000..7ef22e9 --- /dev/null +++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_good_empy_enum_array.expected
@@ -0,0 +1 @@ +PASS
diff --git a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.data b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.data index 1cd34849..0a46e0a4 100644 --- a/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.data +++ b/mojo/public/interfaces/bindings/tests/data/validation/conformance_mthd15_uknown_non_extensible_enum_array_value.data
@@ -15,7 +15,7 @@ [anchr]enum_array_0 [dist4]enum_array_0_member // num_bytes [u4]2 // num_elements +[u4]1 [u4]0x5678 // Unknown value is not allowed for non-extensible // enum. -[u4]1 [anchr]enum_array_0_member
diff --git a/mojo/public/js/codec.js b/mojo/public/js/codec.js index 3ee2274..06a62436 100644 --- a/mojo/public/js/codec.js +++ b/mojo/public/js/codec.js
@@ -819,7 +819,7 @@ Interface.prototype.encode = function(encoder, val) { var interfacePtrInfo = - val ? val.ptr.passInterface() : new InterfacePtrInfo(null, 0); + val ? val.ptr.passInterface() : new types.InterfacePtrInfo(null, 0); encoder.encodeHandle(interfacePtrInfo.handle); encoder.writeUint32(interfacePtrInfo.version); };
diff --git a/mojo/public/js/validator.js b/mojo/public/js/validator.js index 1328c33..9f2b7cf 100644 --- a/mojo/public/js/validator.js +++ b/mojo/public/js/validator.js
@@ -109,7 +109,7 @@ return true; }; - Validator.prototype.validateEnum = function(offset, enumClass, nullable) { + Validator.prototype.validateEnum = function(offset, enumClass) { // Note: Assumes that enums are always 32 bits! But this matches // mojom::generate::pack::PackedField::GetSizeForKind, so it should be okay. var value = this.message.buffer.getInt32(offset); @@ -397,7 +397,8 @@ elementsOffset, numElements, elementType.cls, nullable, expectedDimensionSizes, currentDimension + 1); if (isEnumClass(elementType)) - return this.validateEnum(elementsOffset, elementType.cls, nullable); + return this.validateEnumElements(elementsOffset, numElements, + elementType.cls); return validationError.NONE; }; @@ -471,6 +472,18 @@ return validationError.NONE; }; + Validator.prototype.validateEnumElements = + function(offset, numElements, enumClass) { + var elementSize = codec.Enum.prototype.encodedSize; + for (var i = 0; i < numElements; i++) { + var elementOffset = offset + i * elementSize; + var err = this.validateEnum(elementOffset, enumClass); + if (err != validationError.NONE) + return err; + } + return validationError.NONE; + }; + var exports = {}; exports.validationError = validationError; exports.Validator = Validator;
diff --git a/mojo/public/tools/bindings/generators/mojom_js_generator.py b/mojo/public/tools/bindings/generators/mojom_js_generator.py index 0d774a5..0eedb31 100644 --- a/mojo/public/tools/bindings/generators/mojom_js_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_js_generator.py
@@ -234,9 +234,7 @@ def JavaScriptValidateEnumParams(field): - nullable = JavaScriptNullableParam(field) - enum_type = JavaScriptType(field.kind) - return "%s, %s" % (enum_type, nullable) + return JavaScriptType(field.kind) def JavaScriptValidateStructParams(field): nullable = JavaScriptNullableParam(field)
diff --git a/net/net.gypi b/net/net.gypi index 31d46a0c..c73346b 100644 --- a/net/net.gypi +++ b/net/net.gypi
@@ -972,6 +972,7 @@ 'quic/chromium/quic_stream_factory.cc', 'quic/chromium/quic_stream_factory.h', 'quic/chromium/quic_utils_chromium.h', + 'quic/chromium/quic_utils_chromium.cc', 'quic/core/congestion_control/bandwidth_sampler.cc', 'quic/core/congestion_control/bandwidth_sampler.h', 'quic/core/congestion_control/bbr_sender.cc',
diff --git a/net/quic/chromium/quic_utils_chromium.cc b/net/quic/chromium/quic_utils_chromium.cc new file mode 100644 index 0000000..7d3ba45 --- /dev/null +++ b/net/quic/chromium/quic_utils_chromium.cc
@@ -0,0 +1,31 @@ +// Copyright (c) 2016 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. + +#include "net/quic/chromium/quic_utils_chromium.h" + +#include "base/containers/adapters.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_split.h" + +namespace net { + +QuicTagVector ParseQuicConnectionOptions( + const std::string& connection_options) { + QuicTagVector options; + // Tokens are expected to be no more than 4 characters long, but + // handle overflow gracefully. + for (const base::StringPiece& token : + base::SplitStringPiece(connection_options, ",", base::TRIM_WHITESPACE, + base::SPLIT_WANT_ALL)) { + uint32_t option = 0; + for (char token_char : base::Reversed(token)) { + option <<= 8; + option |= static_cast<unsigned char>(token_char); + } + options.push_back(option); + } + return options; +} + +} // namespace net
diff --git a/net/quic/chromium/quic_utils_chromium.h b/net/quic/chromium/quic_utils_chromium.h index 03b5b39..8735e8b 100644 --- a/net/quic/chromium/quic_utils_chromium.h +++ b/net/quic/chromium/quic_utils_chromium.h
@@ -7,7 +7,11 @@ #ifndef NET_QUIC_CHROMIUM_QUIC_UTILS_CHROMIUM_H_ #define NET_QUIC_CHROMIUM_QUIC_UTILS_CHROMIUM_H_ +#include <string> + #include "base/logging.h" +#include "net/base/net_export.h" +#include "net/quic/core/quic_tag.h" namespace net { @@ -74,6 +78,11 @@ return &it->second; } +// Returns the list of QUIC tags represented by the comma separated +// string in |connection_options|. +NET_EXPORT QuicTagVector +ParseQuicConnectionOptions(const std::string& connection_options); + } // namespace net #endif // NET_QUIC_CHROMIUM_QUIC_UTILS_CHROMIUM_H_
diff --git a/net/quic/chromium/quic_utils_chromium_test.cc b/net/quic/chromium/quic_utils_chromium_test.cc index 9642568f..31d8c05 100644 --- a/net/quic/chromium/quic_utils_chromium_test.cc +++ b/net/quic/chromium/quic_utils_chromium_test.cc
@@ -6,13 +6,25 @@ #include <map> +#include "net/quic/core/crypto/crypto_protocol.h" #include "testing/gtest/include/gtest/gtest.h" - namespace net { namespace test { namespace { +TEST(QuicUtilsTest, ParseQuicConnectionOptions) { + QuicTagVector empty_options = ParseQuicConnectionOptions(""); + EXPECT_TRUE(empty_options.empty()); + + QuicTagVector parsed_options = ParseQuicConnectionOptions("TIMER,TBBR,REJ"); + QuicTagVector expected_options; + expected_options.push_back(kTIME); + expected_options.push_back(kTBBR); + expected_options.push_back(kREJ); + EXPECT_EQ(expected_options, parsed_options); +} + TEST(QuicUtilsChromiumTest, FindOrNullTest) { std::map<int, int> m; m[0] = 2;
diff --git a/net/quic/core/quic_utils.cc b/net/quic/core/quic_utils.cc index 479b6e1f..e0e69b69 100644 --- a/net/quic/core/quic_utils.cc +++ b/net/quic/core/quic_utils.cc
@@ -167,25 +167,6 @@ return "INVALID_TRANSMISSION_TYPE"; } -// static -QuicTagVector QuicUtils::ParseQuicConnectionOptions( - const std::string& connection_options) { - QuicTagVector options; - // Tokens are expected to be no more than 4 characters long, but we - // handle overflow gracefully. - for (const base::StringPiece& token : - base::SplitStringPiece(connection_options, ",", base::TRIM_WHITESPACE, - base::SPLIT_WANT_ALL)) { - uint32_t option = 0; - for (char token_char : base::Reversed(token)) { - option <<= 8; - option |= static_cast<unsigned char>(token_char); - } - options.push_back(option); - } - return options; -} - string QuicUtils::PeerAddressChangeTypeToString(PeerAddressChangeType type) { switch (type) { RETURN_STRING_LITERAL(NO_CHANGE);
diff --git a/net/quic/core/quic_utils.h b/net/quic/core/quic_utils.h index 09ded399..515d204 100644 --- a/net/quic/core/quic_utils.h +++ b/net/quic/core/quic_utils.h
@@ -14,7 +14,6 @@ #include "base/strings/string_piece.h" #include "net/base/int128.h" #include "net/quic/core/quic_error_codes.h" -#include "net/quic/core/quic_tag.h" #include "net/quic/core/quic_types.h" #include "net/quic/platform/api/quic_export.h" #include "net/quic/platform/api/quic_socket_address.h" @@ -62,11 +61,6 @@ // Returns TransmissionType as a char* static const char* TransmissionTypeToString(TransmissionType type); - // Returns the list of QUIC tags represented by the comma separated - // string in |connection_options|. - static QuicTagVector ParseQuicConnectionOptions( - const std::string& connection_options); - // Returns PeerAddressChangeType as a std::string. static std::string PeerAddressChangeTypeToString(PeerAddressChangeType type);
diff --git a/net/quic/core/quic_utils_test.cc b/net/quic/core/quic_utils_test.cc index ea18cb2..beac31b 100644 --- a/net/quic/core/quic_utils_test.cc +++ b/net/quic/core/quic_utils_test.cc
@@ -4,7 +4,6 @@ #include "net/quic/core/quic_utils.h" -#include "net/quic/core/crypto/crypto_protocol.h" #include "net/quic/core/quic_flags.h" #include "testing/gtest/include/gtest/gtest.h" @@ -15,19 +14,6 @@ namespace test { namespace { -TEST(QuicUtilsTest, ParseQuicConnectionOptions) { - QuicTagVector empty_options = QuicUtils::ParseQuicConnectionOptions(""); - EXPECT_EQ(0ul, empty_options.size()); - - QuicTagVector parsed_options = - QuicUtils::ParseQuicConnectionOptions("TIMER,TBBR,REJ"); - QuicTagVector expected_options; - expected_options.push_back(kTIME); - expected_options.push_back(kTBBR); - expected_options.push_back(kREJ); - EXPECT_EQ(expected_options, parsed_options); -} - TEST(QuicUtilsTest, DetermineAddressChangeType) { const string kIPv4String1 = "1.2.3.4"; const string kIPv4String2 = "1.2.3.5";
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 59460bd..7f8537f 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -10361,22 +10361,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Windows-10" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -10837,22 +10821,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0412", - "os": "Windows-10" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -11329,22 +11297,6 @@ }, "test": "tab_capture_end2end_tests", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Windows-10" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -11844,22 +11796,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0412", - "os": "Windows-10" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -12346,22 +12282,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6613", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -12799,22 +12719,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -13275,22 +13179,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0412", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -13724,22 +13612,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6779", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -14257,22 +14129,6 @@ }, "test": "tab_capture_end2end_tests", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "1002:6613", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -14749,22 +14605,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:041a", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -15241,22 +15081,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:0f02", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -15851,22 +15675,6 @@ }, "test": "tab_capture_end2end_tests", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -16366,22 +16174,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0412", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -16845,22 +16637,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -17372,22 +17148,6 @@ }, "test": "tab_capture_end2end_tests", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [
diff --git a/testing/buildbot/chromium.gpu.json b/testing/buildbot/chromium.gpu.json index 94b7c06..7bacd13 100644 --- a/testing/buildbot/chromium.gpu.json +++ b/testing/buildbot/chromium.gpu.json
@@ -1962,22 +1962,6 @@ }, "test": "gl_unittests", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [ @@ -2299,22 +2283,6 @@ }, "test": "tab_capture_end2end_tests", "use_xvfb": false - }, - { - "args": [ - "--test_video_data=../../media/test/data/test-25fps.h264:320:240:250:258:50:175:1" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:104a", - "os": "Windows-2008ServerR2-SP1" - } - ] - }, - "test": "video_decode_accelerator_unittest", - "use_xvfb": false } ], "isolated_scripts": [
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index fa87ae0..8b21a0a 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -947,12 +947,6 @@ "label": "//url:url_unittests", "type": "console_test_launcher", }, - - "video_decode_accelerator_unittest": { - "label": "//media/gpu:video_decode_accelerator_unittest", - "type": "raw", - "args": [], - }, "views_aura_mus_unittests": { "label": "//ui/views/mus:views_aura_mus_unittests", "type": "windowed_test_launcher",
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 75626bc5..516b20c 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -83,6 +83,8 @@ crbug.com/587737 [ Mac ] virtual/gpu-rasterization/images/color-profile-filter.html [ Timeout Failure ] crbug.com/624233 virtual/gpu-rasterization/images/color-profile-background-clip-text.html [ Pass Failure Crash ] +crbug.com/657839 [ Linux ] virtual/gpu-rasterization/images/color-profile-filter.html [ NeedsRebaseline ] + crbug.com/657839 images/color-profile-layer.html [ Skip ] crbug.com/626748 paint/invalidation/table/cached-change-row-border-color.html [ Failure ] @@ -1188,298 +1190,6 @@ crbug.com/658305 css3/filters/multiple-references-id-mutate-crash.html [ Failure Pass ] crbug.com/658305 css3/filters/reference-filter-update-on-attribute-change.html [ Failure Pass ] -crbug.com/657839 virtual/gpu-rasterization/images/embed-image.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-replaced-height-002.htm [ NeedsRebaseline ] -crbug.com/657839 ietestcenter/css3/bordersbackgrounds/background-color-border-box.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-invert-hw.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image-profile-match.html [ NeedsRebaseline ] -crbug.com/657839 virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality.html [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-tiled-gradient.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-017.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/inline-replaced-width-006.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-022.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-width-006.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/spinvalidation/paint/invalidation/compositing/page-scale-repaint.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/paletted-png-with-color-profile.html [ NeedsRebaseline ] -crbug.com/657839 css3/blending/mix-blend-mode-isolated-group-1.html [ NeedsRebaseline ] -crbug.com/657839 images/paletted-png-with-color-profile.html [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/block-replaced-height-001.htm [ NeedsRebaseline ] -crbug.com/657839 fast/reflections/reflection-masks-opacity.html [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-single-layer-no-blending.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-block-replaced-height-001.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-069.htm [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-multiple-background-layers.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-023.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-invert.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/block-replaced-height-003.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-contrast.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-brightness.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-border-image-source.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-029.htm [ NeedsRebaseline ] -crbug.com/657839 mhtml/invalid-bad-boundary2.mht [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-brightness-clamping-hw.html [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/inline-block-replaced-width-006.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/inline-block-replaced-width-001.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-031.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-width-005.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-small-document.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-height-001.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-height-002.htm [ NeedsRebaseline ] -crbug.com/657839 fast/canvas/canvas-toDataURL-webp.html [ NeedsRebaseline ] -crbug.com/657839 css3/blending/effect-background-blend-mode.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-replaced-height-003.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/inline-block-replaced-height-001.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-041.htm [ NeedsRebaseline ] -crbug.com/657839 ietestcenter/css3/bordersbackgrounds/background_color_padding_box.htm [ NeedsRebaseline ] -crbug.com/657839 fast/reflections/reflection-masks.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/block-replaced-height-002.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-border-image-source.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-blur-hw.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-combined.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-050.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-brightness-clamping.html [ NeedsRebaseline ] -crbug.com/657839 ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box.htm [ NeedsRebaseline ] -crbug.com/657839 ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling.htm [ NeedsRebaseline ] -crbug.com/657839 fast/canvas/canvas-toBlob-jpeg-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 svg/as-border-image/svg-as-border-image-2.html [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-image-image.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-029.htm [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-separate-layer-declaration.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-width-001.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-008.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-width-004.htm [ NeedsRebaseline ] -crbug.com/657839 fast/reflections/reflection-with-zoom.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-076.htm [ NeedsRebaseline ] -crbug.com/657839 svg/W3C-SVG-1.1/struct-image-04-t.svg [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-width-003.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-drop-shadow.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-009.htm [ NeedsRebaseline ] -crbug.com/657839 css3/blending/mix-blend-mode-isolated-group-2.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-hue-rotate-hw.html [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-opaque-layer.html [ NeedsRebaseline ] -crbug.com/657839 virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-large-abspos-div.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-003.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-block-replaced-height-002.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-022.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-grayscale-hw.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-062.htm [ NeedsRebaseline ] -crbug.com/657839 css3/blending/effect-background-blend-mode-stacking.html [ NeedsRebaseline ] -crbug.com/657839 virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-055.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 fast/canvas/canvas-toBlob-webp-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-043.htm [ NeedsRebaseline ] -crbug.com/657839 fast/borders/border-image-omit-right-slice.html [ NeedsRebaseline ] -crbug.com/657839 ietestcenter/css3/bordersbackgrounds/none-as-image-layer.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-jpeg-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 [ Mac ] css3/filters/effect-contrast-hw.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-saturate-hw.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/composited-reflected.html [ NeedsRebaseline ] -crbug.com/657839 compositing/reflections/simple-composited-reflections.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu/fast/canvas/canvas-toDataURL-webp.html [ NeedsRebaseline ] -crbug.com/657839 images/embed-image.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 images/object-image.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-048.htm [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-image-svg.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-008.htm [ NeedsRebaseline ] -crbug.com/657839 images/paint-subrect.html [ NeedsRebaseline ] -crbug.com/657839 tables/mozilla/bugs/bug82946-2.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-block-replaced-width-006.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-sepia.html [ NeedsRebaseline ] -crbug.com/657839 ietestcenter/css3/bordersbackgrounds/color-behind-images.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/object-image.html [ NeedsRebaseline ] -crbug.com/657839 images/png-color-profile-ignore-gamma.html [ NeedsRebaseline ] -crbug.com/657839 mhtml/image_document.mht [ NeedsRebaseline ] -crbug.com/657839 fast/css/background-shorthand-invalid-url.html [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-different-image-formats.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-width-011.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-030.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-020.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb.html [ NeedsRebaseline ] -crbug.com/657839 fast/inline/inline-box-background-long-image.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/block-replaced-width-006.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-064.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-034.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-016.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ NeedsRebaseline ] -crbug.com/657839 transforms/transformed-document-element.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-brightness-hw.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-saturate.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-hue-rotate.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-opacity-hw.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-010.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-drop-shadow-hw.html [ NeedsRebaseline ] -crbug.com/657839 virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu/fast/canvas/canvas-toDataURL-webp-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/paint-subrect.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-002.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu/fast/canvas/canvas-toDataURL-jpeg-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 fast/canvas/canvas-toBlob-jpeg-medium-quality.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image-profile-match.html [ NeedsRebaseline ] -crbug.com/657839 fast/reflections/reflection-masks-outset.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/regions-expanding.html [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/float-replaced-width-003.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/float-replaced-width-001.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb.html [ NeedsRebaseline ] -crbug.com/657839 fast/canvas/canvas-toDataURL-webp-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-block-replaced-width-001.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-036.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-027.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 ietestcenter/css3/bordersbackgrounds/order-of-images.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-replaced-width-001.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/crash-filter-change.html [ NeedsRebaseline ] -crbug.com/657839 paint/invalidation/compositing/page-scale-repaint.html [ NeedsRebaseline ] -crbug.com/657839 paint/invalidation/background-image-paint-invalidation-small-document.html [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/inline-replaced-width-001.htm [ NeedsRebaseline ] -crbug.com/657839 ietestcenter/css3/bordersbackgrounds/background_position_three_four_values.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-015.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-blur.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-replaced-height-001.htm [ NeedsRebaseline ] -crbug.com/657839 svg/W3C-SVG-1.1/struct-image-08-t.svg [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-grayscale.html [ NeedsRebaseline ] -crbug.com/657839 fast/canvas/canvas-toDataURL-jpeg-maximum-quality.html [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/block-replaced-width-001.htm [ NeedsRebaseline ] -crbug.com/657839 css3/blending/mix-blend-mode-isolated-group-3.html [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-default-value.html [ NeedsRebaseline ] -crbug.com/657839 fast/writing-mode/block-level-images.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-057.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-006.htm [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-image-color.html [ NeedsRebaseline ] -crbug.com/657839 ietestcenter/css3/bordersbackgrounds/background-size-aspect-ratio.htm [ NeedsRebaseline ] -crbug.com/657839 fast/reflections/reflection-direction.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-024.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-height-001.htm [ NeedsRebaseline ] -crbug.com/657839 paint/invalidation/background-image-paint-invalidation-large-abspos-div.html [ NeedsRebaseline ] -crbug.com/657839 virtual/threaded/compositing/visibility/visibility-image-layers.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-sepia-hw.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/block-replaced-height-001.htm [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-munsell-srgb-to-srgb.html [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-combined-hw.html [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/inline-replaced-height-001.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-071.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-013.htm [ NeedsRebaseline ] -crbug.com/657839 css3/filters/effect-opacity.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-width-002.htm [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-crossfade-image-gradient.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-replaced-width-006.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/block-replaced-width-006.htm [ NeedsRebaseline ] -crbug.com/657839 css3/blending/background-blend-mode-gradient-image.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/inline-block-replaced-height-003.htm [ NeedsRebaseline ] -crbug.com/657839 compositing/visibility/visibility-image-layers.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-munsell-adobe-to-srgb.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/png-color-profile-ignore-gamma.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/block-replaced-width-001.htm [ NeedsRebaseline ] -crbug.com/657839 paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/float-replaced-height-003.htm [ NeedsRebaseline ] -crbug.com/657839 compositing/masks/direct-image-mask.html [ NeedsRebaseline ] -crbug.com/657839 css3/blending/effect-background-blend-mode-tiled.html [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/absolute-replaced-width-001.htm [ NeedsRebaseline ] -crbug.com/657839 virtual/layout_ng/css2.1/20110323/float-replaced-width-005.htm [ NeedsRebaseline ] -crbug.com/657839 css2.1/20110323/width-replaced-element-001.htm [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-border-fade.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/cHRM_color_spin.html [ NeedsRebaseline ] -crbug.com/657839 svg/custom/group-opacity.svg [ NeedsRebaseline ] -crbug.com/657839 svg/W3C-SVG-1.1/struct-use-01-t.svg [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-animate.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image-canvas.html [ NeedsRebaseline ] -crbug.com/657839 media/color-profile-munsell-bt709-to-srgb.html [ NeedsRebaseline ] -crbug.com/657839 virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations.html [ NeedsRebaseline ] -crbug.com/657839 images/cross-fade-background-size.html [ NeedsRebaseline ] -crbug.com/657839 virtual/mojo-loading/http/tests/inspector/network/network-datareceived.html [ NeedsRebaseline ] -crbug.com/657839 images/color-jpeg-with-color-profile.html [ NeedsRebaseline ] -crbug.com/657839 svg/W3C-SVG-1.1/render-groups-01-b.svg [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-layer.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-group.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image-canvas-svg.html [ NeedsRebaseline ] -crbug.com/657839 images/png-suite/test.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-drag-image.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-filter.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-border-radius.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-layer-filter.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-object.html [ NeedsRebaseline ] -crbug.com/657839 svg/W3C-SVG-1.1/render-groups-03-t.svg [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-mask-image-svg.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image-canvas.html [ NeedsRebaseline ] -crbug.com/657839 [ Linux Mac ] virtual/gpu-rasterization/images/webp-color-profile-lossy.html [ NeedsRebaseline ] -crbug.com/657839 scrollbars/listbox-scrollbar-combinations.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-reflection.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image-filter-all.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/png-with-color-profile.html [ NeedsRebaseline ] -crbug.com/657839 svg/zoom/page/zoom-svg-through-object-with-absolute-size.xhtml [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-animate-rotate.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image-canvas-pattern.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-svg-fill-text.html [ NeedsRebaseline ] -crbug.com/657839 images/webp-color-profile-lossy-alpha.html [ NeedsRebaseline ] -crbug.com/657839 images/cHRM_color_spin.html [ NeedsRebaseline ] -crbug.com/657839 svg/filters/filter-source-position.svg [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image-pseudo-content.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-background-image-repeat.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image-canvas-svg.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-jpeg-with-color-profile.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-svg-foreign-object.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-background-image-cross-fade.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-background-image-cross-fade.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image-shape.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-iframe.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-animate.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/jpeg-with-color-profile.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-layer-filter.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image-shape.html [ NeedsRebaseline ] -crbug.com/657839 images/jpeg-with-color-profile.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-border-image.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-iframe.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-svg-foreign-object.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-animate-rotate.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-reflection.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-mask-image-svg.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-background-clip-text.html [ NeedsRebaseline ] -crbug.com/657839 svg/zoom/page/zoom-svg-through-object-with-absolute-size-2.xhtml [ NeedsRebaseline ] -crbug.com/657839 virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-group.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image-svg-resource-url.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-border-fade.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image-canvas-pattern.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-svg.html [ NeedsRebaseline ] -crbug.com/657839 images/webp-color-profile-lossy.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-drag-image.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image-object-fit.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-background-image-space.html [ NeedsRebaseline ] -crbug.com/657839 [ Linux Mac ] images/color-profile-background-image-space.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-background-image-cover.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-clip.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image-pseudo-content.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-svg-fill-text.html [ NeedsRebaseline ] -crbug.com/657839 media/color-profile-video-poster-image.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-background-image-cover.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-object.html [ NeedsRebaseline ] -crbug.com/657839 http/tests/inspector/network/network-datareceived.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image-object-fit.html [ NeedsRebaseline ] -crbug.com/657839 images/webp-color-profile-lossless.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-svg.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/png-suite/test.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-background-image-repeat.html [ NeedsRebaseline ] -crbug.com/657839 compositing/color-matching/image-color-matching.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/webp-color-profile-lossy-alpha.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-image-filter-all.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-image-svg-resource-url.html [ NeedsRebaseline ] -crbug.com/657839 svg/zoom/page/zoom-svg-through-object-with-percentage-size.xhtml [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/cross-fade-background-size.html [ NeedsRebaseline ] -crbug.com/657839 images/png-with-color-profile.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-clip.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/webp-color-profile-lossless.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-border-image.html [ NeedsRebaseline ] -crbug.com/657839 images/color-profile-background-image-cross-fade-png.html [ NeedsRebaseline ] -crbug.com/657839 virtual/gpu-rasterization/images/color-profile-border-radius.html [ NeedsRebaseline ] -crbug.com/657839 media/color-profile-munsell-bt601-smpte-to-srgb.html [ NeedsRebaseline ] -crbug.com/657839 [ Win ] virtual/gpu-rasterization/images/color-profile-filter.html [ NeedsRebaseline ] - crbug.com/267206 [ Mac ] fast/scrolling/scrollbar-tickmarks-hittest.html [ Timeout ] crbug.com/267206 [ Mac ] virtual/scroll_customization/fast/scrolling/scrollbar-tickmarks-hittest.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/reactions/HTMLElement-expected.txt b/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/reactions/HTMLElement-expected.txt index ad3f642..4c0d293 100644 --- a/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/reactions/HTMLElement-expected.txt +++ b/third_party/WebKit/LayoutTests/imported/wpt/custom-elements/reactions/HTMLElement-expected.txt
@@ -21,7 +21,7 @@ FAIL contextMenu on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute Failed to set the 'contextMenu' property on 'HTMLElement': The provided value is not of type 'HTMLMenuElement'. PASS spellcheck on HTMLElement must enqueue an attributeChanged reaction when adding spellcheck content attribute PASS spellcheck on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute -FAIL innerText on HTMLElement must enqueue a disconnected reaction assert_array_equals: lengths differ, expected 1 got 0 -FAIL outerText on HTMLElement must enqueue a disconnected reaction assert_array_equals: lengths differ, expected 1 got 0 +PASS innerText on HTMLElement must enqueue a disconnected reaction +PASS outerText on HTMLElement must enqueue a disconnected reaction Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/payments/resources/payment-request-mock.js b/third_party/WebKit/LayoutTests/payments/resources/payment-request-mock.js index 48ce72c..5d96e2d 100644 --- a/third_party/WebKit/LayoutTests/payments/resources/payment-request-mock.js +++ b/third_party/WebKit/LayoutTests/payments/resources/payment-request-mock.js
@@ -7,24 +7,19 @@ let paymentRequestMock = loadMojoModules( 'paymentRequestMock', ['components/payments/payment_request.mojom', - 'mojo/public/js/router', + 'mojo/public/js/bindings', ]).then(mojo => { - let [paymentRequest, router] = mojo.modules; + let [paymentRequest, bindings] = mojo.modules; class PaymentRequestMock { constructor(interfaceProvider) { interfaceProvider.addInterfaceOverrideForTesting( paymentRequest.PaymentRequest.name, - handle => this.connectPaymentRequest_(handle)); + handle => this.bindings_.addBinding(this, handle)); this.interfaceProvider_ = interfaceProvider; this.pendingResponse_ = null; - } - - connectPaymentRequest_(handle) { - this.paymentRequestStub_ = new paymentRequest.PaymentRequest.stubClass(this); - this.paymentRequestRouter_ = new router.Router(handle); - this.paymentRequestRouter_.setIncomingReceiver(this.paymentRequestStub_); + this.bindings_ = new bindings.BindingSet(paymentRequest.PaymentRequest); } init(client, supportedMethods, details, options) {
diff --git a/third_party/WebKit/LayoutTests/platform/android/images/paletted-png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/android/images/paletted-png-with-color-profile-expected.png index 93dc445..b5daa85 100644 --- a/third_party/WebKit/LayoutTests/platform/android/images/paletted-png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/android/images/paletted-png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/android/images/paletted-png-with-color-profile-expected.txt b/third_party/WebKit/LayoutTests/platform/android/images/paletted-png-with-color-profile-expected.txt new file mode 100644 index 0000000..231fddb2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/android/images/paletted-png-with-color-profile-expected.txt
@@ -0,0 +1,5 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/color-matching/image-color-matching-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/color-matching/image-color-matching-expected.png index 61b116d..07e9069 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/compositing/color-matching/image-color-matching-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/color-matching/image-color-matching-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-cross-fade-expected.png index 694f9a60..e5ed6397 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-cross-fade-png-expected.png index 694f9a60..e5ed6397 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-space-expected.png new file mode 100644 index 0000000..f54d8726 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-space-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-border-radius-expected.png index ee52c5e..9b8edfe 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-border-radius-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-border-radius-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-filter-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-filter-expected.png index a237139..7c96b563 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-group-expected.png index 9aab32d..c9010831 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-group-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-group-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-canvas-svg-expected.png index f876434..c1e917b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-expected.png index ec4ad0f..05c7b17 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-filter-all-expected.png index 67d876b..be5600f 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-shape-expected.png index 92c7265c..018140a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-layer-filter-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-layer-filter-expected.png index ff1bdb4..e575d50 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-layer-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-layer-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png index 0c02fd1..6c3a3192 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png index b2699ed..f3f281d2 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/cross-fade-background-size-expected.png index aaa6c63..a0705d76 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/jpeg-with-color-profile-expected.png index 81d51859..dd25bc0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/png-suite/test-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/png-suite/test-expected.png index bb53dc8..cbbbe3b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/png-suite/test-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/png-suite/test-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/png-with-color-profile-expected.png index 81d51859..dd25bc0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png index c75f489..d3a6ac2 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt709-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt709-to-srgb-expected.png index 4268cfb..eb5822a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt709-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/color-profile-munsell-bt709-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 3cedc22..83f9d738 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/linux/scrollbars/listbox-scrollbar-combinations-expected.png index 66c68fd..8bd8b9dc 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png index 9e8117c3..1786b57 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-03-t-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-03-t-expected.png index e325689..ea6fe1d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-03-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/render-groups-03-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-use-01-t-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-use-01-t-expected.png index fdb5b9b3..28a3f59 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-use-01-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-use-01-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png index 5bbf22b..f16ca70 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png index 5bbf22b..f16ca70 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png index e3c6431..b869e0da 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png index 7b8322d..e4d4f8c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png index 37afbc17..d78ce9a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png index 37afbc17..d78ce9a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png index d2ad9830..ace784a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png index 9d9f5b8..da8ce41 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-border-image-expected.png index 9df0fc9..6f101d5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-border-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-border-radius-expected.png index 3ec6d4a0..f4365827 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-border-radius-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-border-radius-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-group-expected.png index ac7f11c..ffd531b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-group-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-group-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-iframe-expected.png index 1dbe286..975e5fd6 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png index ec35bd05..2dbcf9a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png index 061cb938..5dd87ff 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png index e33eca3..68885d2 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-expected.png index 3045c185..eb1051c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png index 350a981..7df589692 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png index 10edd86..5f70429 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-layer-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-layer-expected.png index a817b3e..d91a693 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-layer-filter-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-layer-filter-expected.png index 47b972e..6d681b7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-layer-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-layer-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png index 8f8d655..eb1f211f4 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png index df31793c..6443a7f4 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-object-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-object-expected.png index 3ebdcbb..b2c39bb 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-object-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-svg-expected.png index 051e7a7a..0e3dbec 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-svg-fill-text-expected.png index 95a3d9d..3d66609a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png index 48bd86f..09bf797 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png index 0a2f9c67..987b1e19 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/png-suite/test-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/png-suite/test-expected.png index bb53dc8..cbbbe3b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/png-suite/test-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/png-suite/test-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/png-with-color-profile-expected.png index 0a2f9c67..987b1e19 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/webp-color-profile-lossy-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/webp-color-profile-lossy-expected.png index a34b059..37a31d5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/webp-color-profile-lossy-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu-rasterization/images/webp-color-profile-lossy-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png index 66c68fd..8bd8b9dc 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png index 66c68fd..8bd8b9dc 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png new file mode 100644 index 0000000..83f9d738 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png index bec7f4c..0fe346f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-srgb-to-srgb-expected.png index cb20800..1fd35f53 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png index d5a3eb8d..464fec30 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png index 55ff47d..0100a410 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.png index cb20800..1fd35f53 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png index fb8869f..a7a26b0792 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-size-aspect-ratio-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-size-aspect-ratio-expected.png index a0bd9771..7511c0e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-size-aspect-ratio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-size-aspect-ratio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background_position_three_four_values-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background_position_three_four_values-expected.png index d82e2b48..166bff2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background_position_three_four_values-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background_position_three_four_values-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png index 432de19..2547e36 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 8257577..9b4de59 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png new file mode 100644 index 0000000..2547e36 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png new file mode 100644 index 0000000..9b4de59 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/masks/direct-image-mask-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/masks/direct-image-mask-expected.png index 0490329..b429d396 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/compositing/masks/direct-image-mask-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/masks/direct-image-mask-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.png index c74de6a..7d792d8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/visibility/visibility-image-layers-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/visibility/visibility-image-layers-expected.png index 446c26e..3ded6ed 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/compositing/visibility/visibility-image-layers-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/visibility/visibility-image-layers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-001-expected.png index a4ccef3..7e78a464 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-002-expected.png index bcf93f9..7c756a0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-003-expected.png index be985725..6bcbf38 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-008-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-008-expected.png index b8cc13d..9f97e3ee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-008-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-008-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-009-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-009-expected.png index b8cc13d..9f97e3ee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-009-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-009-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-010-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-010-expected.png index ecea331..91b91c07 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-010-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-010-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-016-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-016-expected.png index b8cc13d..9f97e3ee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-016-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-016-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-017-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-017-expected.png index ecea331..91b91c07 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-017-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-017-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-022-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-022-expected.png index b8cc13d..9f97e3ee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-022-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-022-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-023-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-023-expected.png index b8cc13d..9f97e3ee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-023-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-023-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-024-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-024-expected.png index ecea331..91b91c07 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-024-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-024-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-029-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-029-expected.png index b8cc13d..9f97e3ee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-029-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-029-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-030-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-030-expected.png index b8cc13d..9f97e3ee 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-030-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-030-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-031-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-031-expected.png index ecea331..91b91c07 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-031-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-height-031-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-001-expected.png index 8cc0503..1d483451 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-006-expected.png index 9e53939..59a81c09 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-006-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-006-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-008-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-008-expected.png index 8cc0503..1d483451 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-008-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-008-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-013-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-013-expected.png index 9e53939..59a81c09 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-013-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-013-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-015-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-015-expected.png index 7f9efe6c..336d473c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-015-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-015-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-020-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-020-expected.png index 8acc10b..4e7aa5ec 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-020-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-020-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-022-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-022-expected.png index 13ed433..10fd51e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-022-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-022-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-027-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-027-expected.png index 8acc10b..4e7aa5ec 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-027-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-027-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-029-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-029-expected.png index 13ed433..10fd51e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-029-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-029-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-034-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-034-expected.png index 8acc10b..4e7aa5ec 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-034-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-034-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-036-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-036-expected.png index 071056ec..a51d3da 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-036-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-036-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-041-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-041-expected.png index 4d0f891c..6aeb0c53 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-041-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-041-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-043-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-043-expected.png index 071056ec..a51d3da 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-043-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-043-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-048-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-048-expected.png index 4d0f891c..6aeb0c53 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-048-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-048-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-050-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-050-expected.png index 071056ec..a51d3da 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-050-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-050-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-055-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-055-expected.png index 4d0f891c..6aeb0c53 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-055-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-055-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-057-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-057-expected.png index 071056ec..a51d3da 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-057-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-057-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-062-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-062-expected.png index 4d0f891c..6aeb0c53 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-062-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-062-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-064-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-064-expected.png index 071056ec..a51d3da 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-064-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-064-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-069-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-069-expected.png index 4d0f891c..6aeb0c53 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-069-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-069-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-071-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-071-expected.png index 071056ec..a51d3da 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-071-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-071-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-076-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-076-expected.png index 4d0f891c..6aeb0c53 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-076-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/absolute-replaced-width-076-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-001-expected.png index a4ccef3..7e78a464 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-002-expected.png index bcf93f9..7c756a0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-003-expected.png index be985725..6bcbf38 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-height-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-width-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-width-001-expected.png index e1a638e9..ed01d70 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-width-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-width-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-width-006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-width-006-expected.png index c32d553..e345baf 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-width-006-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/block-replaced-width-006-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-001-expected.png index a4ccef3..7e78a464 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-002-expected.png index bcf93f9..7c756a0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-003-expected.png index be985725..6bcbf38 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-height-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-001-expected.png index b59dfc1..4361530a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-002-expected.png index 499be22..4514bad 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-003-expected.png index 233459cf..0d528ed0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-004-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-004-expected.png index 499be22..4514bad 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-004-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-004-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-005-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-005-expected.png index b59dfc1..4361530a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-005-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-005-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-006-expected.png index 8cc0503..1d483451 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-006-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-006-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-011-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-011-expected.png index 9e53939..59a81c09 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-011-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/float-replaced-width-011-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-001-expected.png index a4ccef3..7e78a464 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-002-expected.png index bcf93f9..7c756a0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-003-expected.png index be985725..6bcbf38 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-height-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-width-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-width-001-expected.png index 8cc0503..1d483451 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-width-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-width-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-width-006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-width-006-expected.png index 9e53939..59a81c09 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-width-006-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-block-replaced-width-006-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-001-expected.png index a4ccef3..7e78a464 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-002-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-002-expected.png index bcf93f9..7c756a0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-002-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-002-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-003-expected.png index be985725..6bcbf38 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-003-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-height-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-width-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-width-001-expected.png index 408c931..400548d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-width-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-width-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-width-006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-width-006-expected.png index 9e53939..59a81c09 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-width-006-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/inline-replaced-width-006-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/width-replaced-element-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/width-replaced-element-001-expected.png index b951dd6..1c5a957 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/width-replaced-element-001-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/20110323/width-replaced-element-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png index 0c1132a..0a3a969 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-crossfade-image-gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-default-value-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-default-value-expected.png index c41d8d3..ee1e9975 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-default-value-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-default-value-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-different-image-formats-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-different-image-formats-expected.png index 77c4715f..bb12400 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-different-image-formats-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-different-image-formats-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-gradient-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-gradient-image-expected.png index 40c6959..f185cd9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-gradient-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-gradient-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-color-expected.png index 9287322..831c65c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-color-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-color-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-image-expected.png index 3e457272..77acc97 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-svg-expected.png index cf04bcd9..3bd939d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-multiple-background-layers-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-multiple-background-layers-expected.png index 7fb4e54..5996c66d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-multiple-background-layers-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-multiple-background-layers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-opaque-layer-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-opaque-layer-expected.png index d878f6d..df70497 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-opaque-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-opaque-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-separate-layer-declaration-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-separate-layer-declaration-expected.png index ded70c26..082cc73 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-separate-layer-declaration-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-separate-layer-declaration-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-single-layer-no-blending-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-single-layer-no-blending-expected.png index 539ed9a..ad92e33 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-single-layer-no-blending-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-single-layer-no-blending-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png index b27e050..c0931f23 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-expected.png index 0eb157d..73438bc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-stacking-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-stacking-expected.png index 30e46b8..271fe2a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-stacking-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-stacking-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-tiled-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-tiled-expected.png index 53561fe..808f2efc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-tiled-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/effect-background-blend-mode-tiled-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-1-expected.png index 40c37ff..f5c1d850 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-1-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-1-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-2-expected.png index ddc31cff..aa666e98 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-3-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-3-expected.png index fcc2d709..70648af7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-3-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/mix-blend-mode-isolated-group-3-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/composited-reflected-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/composited-reflected-expected.png index 87042936..c2bd2e0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/composited-reflected-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/composited-reflected-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/crash-filter-change-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/crash-filter-change-expected.png index 22155e6..23b6c15 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/crash-filter-change-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/crash-filter-change-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-blur-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-blur-expected.png index 4653c57..13c02324 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-blur-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-blur-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-blur-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-blur-hw-expected.png index a9d3ce30..484433f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-blur-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-blur-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.png index 2f2d48f..c69a35a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-hw-expected.png index 11d2bc2..44a547a1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-clamping-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.png index 52b82b81..0abdbacc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-hw-expected.png index 33c758f..3d35fb35 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-brightness-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-combined-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-combined-expected.png index 76005c9..f877155a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-combined-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-combined-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-combined-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-combined-hw-expected.png index 1766aaf..ca2b206c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-combined-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-combined-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-contrast-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-contrast-expected.png index 9be0679..20cc3e7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-contrast-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-contrast-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-contrast-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-contrast-hw-expected.png index 519dba3..9989f6f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-contrast-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-contrast-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-drop-shadow-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-drop-shadow-expected.png index 6902f44..f21c624 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-drop-shadow-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-drop-shadow-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-drop-shadow-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-drop-shadow-hw-expected.png index aee5ba8..be48eb9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-drop-shadow-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-drop-shadow-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-grayscale-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-grayscale-expected.png index 1b2f8d1c..235ec10 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-grayscale-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-grayscale-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-grayscale-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-grayscale-hw-expected.png index 1cc1be7..f3d6e48 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-grayscale-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-grayscale-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-hue-rotate-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-hue-rotate-expected.png index f153bc33..45e21c8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-hue-rotate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-hue-rotate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-hue-rotate-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-hue-rotate-hw-expected.png index a422f67..2b87476 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-hue-rotate-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-hue-rotate-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-invert-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-invert-expected.png index 1d15c3d..3e18449 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-invert-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-invert-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-invert-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-invert-hw-expected.png index 1d15c3d..3e18449 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-invert-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-invert-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-opacity-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-opacity-expected.png index 166cce0..67129a6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-opacity-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-opacity-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-opacity-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-opacity-hw-expected.png index 166cce0..67129a6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-opacity-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-opacity-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-saturate-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-saturate-expected.png index 7143a417..28e0c82 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-saturate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-saturate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-saturate-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-saturate-hw-expected.png index 8da5ac5e..ae3f27b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-saturate-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-saturate-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-sepia-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-sepia-expected.png index 2c71a6d..98c66ad 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-sepia-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-sepia-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-sepia-hw-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-sepia-hw-expected.png index 055c77c2..862dc2f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-sepia-hw-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/effect-sepia-hw-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/regions-expanding-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/regions-expanding-expected.png index d16f088..235bc6fb 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/regions-expanding-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/regions-expanding-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-omit-right-slice-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-omit-right-slice-expected.png index 5e8704f..38f419ff 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-omit-right-slice-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-omit-right-slice-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png index ffd9459..2486220 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png index 78afc3d..d5d98a7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png index f72affb..6a43329 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png index ee765b13..9284bc26 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-webp-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-webp-expected.png index d10a012..ce5f9d0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-webp-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-webp-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png index f72affb..6a43329 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/background-shorthand-invalid-url-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/background-shorthand-invalid-url-expected.png index f6c13486..edf9b1a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/background-shorthand-invalid-url-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/background-shorthand-invalid-url-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/inline/inline-box-background-long-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/inline/inline-box-background-long-image-expected.png index ede993f..dccca9c6 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/inline/inline-box-background-long-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/inline/inline-box-background-long-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-direction-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-direction-expected.png index 16e349ad..427402b1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-direction-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-direction-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-expected.png index 34fe91a..bab6d064 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-opacity-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-opacity-expected.png index 02742b5..4c0971e3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-opacity-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-opacity-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-outset-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-outset-expected.png index fee25ca..25ca44e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-outset-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-masks-outset-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-with-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-with-zoom-expected.png index 5c3eb181..e8fb280 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-with-zoom-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/reflections/reflection-with-zoom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/block-level-images-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/block-level-images-expected.png index 5eb0889..bc59779 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/block-level-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/block-level-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png index 163d4a0..a892d1e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-color-border-box-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-color-border-box-expected.png index a1fe58c..c68cb62 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-color-border-box-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-color-border-box-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-size-aspect-ratio-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-size-aspect-ratio-expected.png index 95e34d7..07fbe2a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-size-aspect-ratio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-size-aspect-ratio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_color_padding_box-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_color_padding_box-expected.png index a088011..719a5af 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_color_padding_box-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_color_padding_box-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_position_three_four_values-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_position_three_four_values-expected.png index e97c492..cb9df15 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_position_three_four_values-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_position_three_four_values-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png index 95d3c3d1..dba4339 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/color-behind-images-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/color-behind-images-expected.png index 681f151..82509ae 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/color-behind-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/color-behind-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/none-as-image-layer-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/none-as-image-layer-expected.png index 56e8adea..18ae257 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/none-as-image-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/none-as-image-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/order-of-images-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/order-of-images-expected.png index a0dcefa..42866aeb 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/order-of-images-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/order-of-images-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-image-source-expected.png index 85e94d3e..31baff2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-image-source-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-image-source-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-profile-match-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-profile-match-expected.png index 876685149..00d6dc84 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-profile-match-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-image-profile-match-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png index 5bd6f75..7f312cf8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.txt index 236d02d..46a120a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-adobe-to-srgb-expected.txt
@@ -18,7 +18,7 @@ Blue 35,40,135 46,60,153 29 Green 58,134,54 71,150,69 25 Red 159,26,43 177,44,56 29 -Yellow 234,191,24 238,200,27 10 +Yellow 234,191,23 238,200,27 11 Magenta 171,58,129 187,82,148 35 Cyan (*) 0,116,149 0,135,166 25 -------------------------------------------- @@ -30,7 +30,7 @@ Black 37,37,37 50,49,50 22 -------------------------------------------- -Result: total RMS color error: 27.52 +Result: total RMS color error: 27.54 * Munsell Cyan is outside 255 sRGB gamut
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-srgb-to-srgb-expected.png index 8fd322c79..8f5b3cf 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-srgb-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-srgb-to-srgb-expected.txt index 0680d53..9773c2a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-srgb-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-munsell-srgb-to-srgb-expected.txt
@@ -6,13 +6,13 @@ Blue Sky 76,103,138 94,123,156 32 Foliage 70,90,50 88,108,65 30 Blue Flower 111,108,161 130,129,177 33 -Bluish Green 85,179,155 100,190,171 25 +Bluish Green 85,178,155 100,190,171 25 -------------------------------------------- Orange 206,102,29 217,122,37 24 Purplish Blue 56,69,148 72,91,165 32 Moderate Red 179,62,80 194,84,98 32 Purple 72,42,88 91,59,107 32 -Yellow Green 144,178,46 160,188,60 23 +Yellow Green 144,178,47 160,188,60 23 Orange Yellow 222,147,33 230,163,42 20 -------------------------------------------- Blue 35,40,135 46,60,153 29 @@ -22,15 +22,15 @@ Magenta 171,58,130 187,82,148 34 Cyan (*) 15,116,149 0,135,166 30 -------------------------------------------- -White 240,239,232 243,242,237 7 +White 240,239,233 243,242,237 6 Neutral 8 189,189,189 201,201,201 21 Neutral 6.5 144,144,144 161,161,161 29 Neutral 5 103,103,102 122,122,121 33 -Neutral 3.5 65,66,65 83,83,83 31 +Neutral 3.5 65,65,66 83,83,83 31 Black 38,37,38 50,49,50 21 -------------------------------------------- -Result: total RMS color error: 27.69 +Result: total RMS color error: 27.68 * Munsell Cyan is outside 255 sRGB gamut
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/embed-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/embed-image-expected.png index c864bb5..3762441 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/embed-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/embed-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/object-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/object-image-expected.png index c864bb5..3762441 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/object-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/object-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/paint-subrect-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/paint-subrect-expected.png index 4a2cf136..64b6ca2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/paint-subrect-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/paint-subrect-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/paletted-png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/paletted-png-with-color-profile-expected.png index fc60ed6..eed4b62 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/paletted-png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/paletted-png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/png-color-profile-ignore-gamma-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/png-color-profile-ignore-gamma-expected.png index 7a18819..1e22023 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/images/png-color-profile-ignore-gamma-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/images/png-color-profile-ignore-gamma-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/mhtml/image_document-expected.png b/third_party/WebKit/LayoutTests/platform/mac/mhtml/image_document-expected.png index eb204e2..1e7ef03 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/mhtml/image_document-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/mhtml/image_document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/mhtml/invalid-bad-boundary2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/mhtml/invalid-bad-boundary2-expected.png index eb204e2..1e7ef03 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/mhtml/invalid-bad-boundary2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/mhtml/invalid-bad-boundary2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png index acc9e37..0e0935e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-small-document-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-small-document-expected.png index a1cbd5d0..e67ef295 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-small-document-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-small-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/compositing/page-scale-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/compositing/page-scale-repaint-expected.png index af72fc5..f45edb7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/compositing/page-scale-repaint-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/compositing/page-scale-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 6fc560f..74c45d1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-04-t-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-04-t-expected.png index f99ab4a..01725b0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-04-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-04-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-08-t-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-08-t-expected.png index 06a6cc6..770c01f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-08-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/struct-image-08-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-2-expected.png index e078332..a23e12b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/as-border-image/svg-as-border-image-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug82946-2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug82946-2-expected.png index 3baa6c2..baf0b2d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug82946-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug82946-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-document-element-expected.png b/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-document-element-expected.png index e3b34344..f37cda75 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-document-element-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/transforms/transformed-document-element-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png index ffd9459..2486220 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png index 78afc3d..d5d98a7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png index f72affb..6a43329 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png index ee765b13..9284bc26 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp-expected.png index d10a012..ce5f9d0 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png index f72affb..6a43329 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-border-image-source-expected.png index 63f81584..fb20e0f3d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-border-image-source-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-border-image-source-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-profile-match-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-profile-match-expected.png index eb644271..e4074609 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-profile-match-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-image-profile-match-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png index b7ccd77..385d70d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.txt index 236d02d..46a120a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.txt
@@ -18,7 +18,7 @@ Blue 35,40,135 46,60,153 29 Green 58,134,54 71,150,69 25 Red 159,26,43 177,44,56 29 -Yellow 234,191,24 238,200,27 10 +Yellow 234,191,23 238,200,27 11 Magenta 171,58,129 187,82,148 35 Cyan (*) 0,116,149 0,135,166 25 -------------------------------------------- @@ -30,7 +30,7 @@ Black 37,37,37 50,49,50 22 -------------------------------------------- -Result: total RMS color error: 27.52 +Result: total RMS color error: 27.54 * Munsell Cyan is outside 255 sRGB gamut
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.png index 8fd322c79..8f5b3cf 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.txt index 0680d53..9773c2a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/color-profile-munsell-srgb-to-srgb-expected.txt
@@ -6,13 +6,13 @@ Blue Sky 76,103,138 94,123,156 32 Foliage 70,90,50 88,108,65 30 Blue Flower 111,108,161 130,129,177 33 -Bluish Green 85,179,155 100,190,171 25 +Bluish Green 85,178,155 100,190,171 25 -------------------------------------------- Orange 206,102,29 217,122,37 24 Purplish Blue 56,69,148 72,91,165 32 Moderate Red 179,62,80 194,84,98 32 Purple 72,42,88 91,59,107 32 -Yellow Green 144,178,46 160,188,60 23 +Yellow Green 144,178,47 160,188,60 23 Orange Yellow 222,147,33 230,163,42 20 -------------------------------------------- Blue 35,40,135 46,60,153 29 @@ -22,15 +22,15 @@ Magenta 171,58,130 187,82,148 34 Cyan (*) 15,116,149 0,135,166 30 -------------------------------------------- -White 240,239,232 243,242,237 7 +White 240,239,233 243,242,237 6 Neutral 8 189,189,189 201,201,201 21 Neutral 6.5 144,144,144 161,161,161 29 Neutral 5 103,103,102 122,122,121 33 -Neutral 3.5 65,66,65 83,83,83 31 +Neutral 3.5 65,65,66 83,83,83 31 Black 38,37,38 50,49,50 21 -------------------------------------------- -Result: total RMS color error: 27.69 +Result: total RMS color error: 27.68 * Munsell Cyan is outside 255 sRGB gamut
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/embed-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/embed-image-expected.png index c864bb5..3762441 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/embed-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/embed-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/object-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/object-image-expected.png index c864bb5..3762441 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/object-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/object-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/paint-subrect-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/paint-subrect-expected.png index 4a2cf136..64b6ca2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/paint-subrect-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/paint-subrect-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/paletted-png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/paletted-png-with-color-profile-expected.png index fc60ed6..eed4b62 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/paletted-png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/paletted-png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/png-color-profile-ignore-gamma-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/png-color-profile-ignore-gamma-expected.png index 7a18819..1e22023 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/png-color-profile-ignore-gamma-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu-rasterization/images/png-color-profile-ignore-gamma-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png index ffd9459..2486220 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png index 78afc3d..d5d98a7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-jpeg-medium-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png index f72affb..6a43329 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toBlob-webp-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png index 7590fb20..fc0cbd96 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-jpeg-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-webp-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-webp-expected.png index 68c4a40..e426a101 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-webp-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-webp-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png index f72affb..6a43329 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/canvas-toDataURL-webp-maximum-quality-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/block-replaced-height-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/block-replaced-height-001-expected.png new file mode 100644 index 0000000..7e78a464 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/block-replaced-height-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/block-replaced-width-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/block-replaced-width-001-expected.png new file mode 100644 index 0000000..ed01d70 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/block-replaced-width-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/block-replaced-width-006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/block-replaced-width-006-expected.png new file mode 100644 index 0000000..e345baf --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/block-replaced-width-006-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/float-replaced-width-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/float-replaced-width-001-expected.png new file mode 100644 index 0000000..4361530a --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/float-replaced-width-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/float-replaced-width-003-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/float-replaced-width-003-expected.png new file mode 100644 index 0000000..0d528ed0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/float-replaced-width-003-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/float-replaced-width-005-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/float-replaced-width-005-expected.png new file mode 100644 index 0000000..4361530a --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/float-replaced-width-005-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-block-replaced-height-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-block-replaced-height-001-expected.png new file mode 100644 index 0000000..7e78a464 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-block-replaced-height-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-block-replaced-width-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-block-replaced-width-001-expected.png new file mode 100644 index 0000000..1d483451 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-block-replaced-width-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-block-replaced-width-006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-block-replaced-width-006-expected.png new file mode 100644 index 0000000..59a81c09 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-block-replaced-width-006-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-replaced-height-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-replaced-height-001-expected.png new file mode 100644 index 0000000..7e78a464 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-replaced-height-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-replaced-width-001-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-replaced-width-001-expected.png new file mode 100644 index 0000000..400548d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-replaced-width-001-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-replaced-width-006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-replaced-width-006-expected.png new file mode 100644 index 0000000..59a81c09 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/layout_ng/css2.1/20110323/inline-replaced-width-006-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png new file mode 100644 index 0000000..0e0935e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-small-document-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-small-document-expected.png new file mode 100644 index 0000000..e67ef295 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/background-image-paint-invalidation-small-document-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/compositing/page-scale-repaint-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/compositing/page-scale-repaint-expected.png new file mode 100644 index 0000000..f45edb7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/compositing/page-scale-repaint-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png new file mode 100644 index 0000000..74c45d1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/compositing/visibility/visibility-image-layers-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/compositing/visibility/visibility-image-layers-expected.png index 446c26e..3ded6ed 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/compositing/visibility/visibility-image-layers-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/compositing/visibility/visibility-image-layers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/color-matching/image-color-matching-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/color-matching/image-color-matching-expected.png index 60e2094..9f3bc37 100644 --- a/third_party/WebKit/LayoutTests/platform/win/compositing/color-matching/image-color-matching-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/color-matching/image-color-matching-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/cHRM_color_spin-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/cHRM_color_spin-expected.png index 0ae215e..5286dbfb 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/cHRM_color_spin-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/cHRM_color_spin-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-jpeg-with-color-profile-expected.png index 127a446c..8114e46 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-animate-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-animate-expected.png index 4ee6230..21f9a15 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-animate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-animate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-animate-rotate-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-animate-rotate-expected.png index 5768c8a..5032ce8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-animate-rotate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-animate-rotate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-clip-text-expected.png index ddc721c..7ee7d53 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-clip-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-clip-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cover-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cover-expected.png index 1f3ecd3b..1a27a04c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cover-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-expected.png index a5fcf54a..62c0608 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-png-expected.png index a5fcf54a..62c0608 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-repeat-expected.png index e21c4d27..6b1acac1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-repeat-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-repeat-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-fade-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-fade-expected.png index 3dfa6ba..9a79763 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-image-expected.png index 624dabf..2b7b3df 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-radius-expected.png index a30898a..d176be8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-radius-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-radius-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-clip-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-clip-expected.png index 7ca57b57..ff07c6a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-clip-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-clip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png index 142e144..938db221 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-drag-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-filter-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-filter-expected.png index 43036a3..3422705 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png index 387cbc47..6887fe5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-iframe-expected.png index 435a7d4..773fb705 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-expected.png index cbba464f..bbb07903 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-pattern-expected.png index a7cb379..13efa39 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-svg-expected.png index 04c8ca9d..d359ffc 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-expected.png index a1e42b20..8d47b0ff 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-filter-all-expected.png index 8127cb92..939e8f7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-object-fit-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-object-fit-expected.png index 21c9226..3e4b818 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-object-fit-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-object-fit-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-pseudo-content-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-pseudo-content-expected.png index 4d7d9a9..baa7551 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-pseudo-content-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-pseudo-content-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-shape-expected.png index 61ebcc7f..561000e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-svg-resource-url-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-svg-resource-url-expected.png index 48258f9a..341dc128 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-svg-resource-url-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-image-svg-resource-url-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-filter-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-filter-expected.png index 5bd11f27..0857f456 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-layer-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-mask-image-svg-expected.png index da54fbb..ca15240 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-mask-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-mask-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png index e01a7d16..51620b77 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.txt index eaa06fe0..20ccc5c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-munsell-adobe-to-srgb-expected.txt
@@ -19,7 +19,7 @@ Green 71,149,70 71,150,69 1 Red 176,45,56 177,44,56 1 Yellow 239,200,27 238,200,27 1 -Magenta 187,82,147 187,82,148 1 +Magenta 186,82,147 187,82,148 1 Cyan (*) 0,135,165 0,135,166 1 -------------------------------------------- White 243,242,236 243,242,237 1
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-object-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-object-expected.png index 76df340..1ee0a34 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-object-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-reflection-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-reflection-expected.png index af53c6ec..6c0969e9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-reflection-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-reflection-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-expected.png index 614c593b..5070f24 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png index d883196e..9dbd9b6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-foreign-object-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-foreign-object-expected.png index eeb1015..0b1223f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-foreign-object-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-foreign-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png index 5ee7b72..21492ee 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/jpeg-with-color-profile-expected.png index af94831..df4281fb 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/png-suite/test-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/png-suite/test-expected.png index 9a7dfa2e..5f626efc 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/png-suite/test-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/png-suite/test-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/png-with-color-profile-expected.png index af94831..df4281fb 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossless-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossless-expected.png index d3f2f19..829f86b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossless-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossless-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossy-alpha-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossy-alpha-expected.png index 2603967..c7c6b394 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossy-alpha-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossy-alpha-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossy-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossy-expected.png index a34b059..37a31d5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossy-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/images/webp-color-profile-lossy-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png index f085d0c..d0a09e02 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.txt index 29d2fff..4623a12 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt601-smpte-to-srgb-expected.txt
@@ -3,7 +3,7 @@ -------------------------------------------- Dark Skin 115,80,65 115,80,64 1 Light Skin 195,150,130 195,151,130 1 -Blue Sky 94,123,156 94,123,156 0 +Blue Sky 94,123,155 94,123,156 1 Foliage 88,108,66 88,108,65 1 Blue Flower 130,129,177 130,129,177 0 Bluish Green 100,189,171 100,190,171 1 @@ -13,7 +13,7 @@ Moderate Red 194,84,98 194,84,98 0 Purple 91,59,107 91,59,107 0 Yellow Green 160,187,60 160,188,60 1 -Orange Yellow 230,163,43 230,163,42 1 +Orange Yellow 230,163,42 230,163,42 0 -------------------------------------------- Blue 47,60,153 46,60,153 1 Green 71,150,69 71,150,69 0
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.png index 2aa5374..78313a1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.txt index e72f6630..285f906 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-munsell-bt709-to-srgb-expected.txt
@@ -5,7 +5,7 @@ Light Skin 195,151,129 195,151,130 1 Blue Sky 94,123,155 94,123,156 1 Foliage 88,108,65 88,108,65 0 -Blue Flower 130,129,176 130,129,177 1 +Blue Flower 129,129,176 130,129,177 1 Bluish Green 101,190,171 100,190,171 1 -------------------------------------------- Orange 217,122,37 217,122,37 0
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-video-poster-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-video-poster-image-expected.png index 2b31978..388f5069 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/color-profile-video-poster-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/color-profile-video-poster-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 5a6bf3c..91ff34ff 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win/scrollbars/listbox-scrollbar-combinations-expected.png index 95d8e1c5..4c5e3c3 100644 --- a/third_party/WebKit/LayoutTests/platform/win/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-01-b-expected.png index a6973fc..f05ad46 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-01-b-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-01-b-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-03-t-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-03-t-expected.png index 76cc87b..21bc1a8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-03-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/render-groups-03-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-use-01-t-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-use-01-t-expected.png index 5627dac..3c39acf1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-use-01-t-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-use-01-t-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/group-opacity-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/group-opacity-expected.png index c3d513d..2ef2f6d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/group-opacity-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/group-opacity-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/filters/filter-source-position-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/filters/filter-source-position-expected.png index 38270c5..465a17bf 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/filters/filter-source-position-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/filters/filter-source-position-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png index e9c30e7..0d34586 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png index e9c30e7..0d34586 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-absolute-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png index 2a766fb..9bd8a9b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-svg-through-object-with-percentage-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cHRM_color_spin-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cHRM_color_spin-expected.png index 0ae215e..5286dbfb 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cHRM_color_spin-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cHRM_color_spin-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-jpeg-with-color-profile-expected.png index 127a446c..8114e46 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-animate-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-animate-expected.png index 4ee6230..21f9a15 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-animate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-animate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-animate-rotate-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-animate-rotate-expected.png index 5768c8a..5032ce8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-animate-rotate-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-animate-rotate-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png index ca26061d..c98dad7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cover-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png index 8f5608bd..8d6656ab 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png index 8f5608bd..8d6656ab 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-cross-fade-png-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png index 12c55af..ac812b8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-repeat-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png index d98896c..f09159e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-background-image-space-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-fade-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-fade-expected.png index f8b5b71..ad4f227 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-fade-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-fade-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-image-expected.png index b4c92bdf..c63227a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-radius-expected.png index 0c4088b..1b93ee58 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-radius-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-border-radius-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-clip-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-clip-expected.png index 7ca57b57..ff07c6a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-clip-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-clip-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png index 142e144..938db221 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-drag-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-filter-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-filter-expected.png index 912566e..e29fd8e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-group-expected.png index a5b6506..abb11b6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-group-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-group-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-iframe-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-iframe-expected.png index 50e91aa4..2cb8795 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-iframe-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png index 427a654a..57d4053 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png index bee0767..9f9f414 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-pattern-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png index b23d075..1b99679 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-canvas-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-expected.png index 7863957..59d77e4 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png index 5572520..778812b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-filter-all-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-object-fit-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-object-fit-expected.png index 21c9226..3e4b818 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-object-fit-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-object-fit-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-pseudo-content-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-pseudo-content-expected.png index 4d7d9a9..baa7551 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-pseudo-content-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-pseudo-content-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png index 0673f50..356366ea1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-shape-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-svg-resource-url-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-svg-resource-url-expected.png index 48258f9a..341dc128 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-svg-resource-url-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-image-svg-resource-url-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-layer-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-layer-expected.png index 651eb3c..590d410 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-layer-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-layer-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-layer-filter-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-layer-filter-expected.png index 1ae9bb5..4a13efc 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-layer-filter-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-layer-filter-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png index 22668c03..95b3dd1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png index 9ab4289f..756cb355 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.txt index eaa06fe0..20ccc5c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-munsell-adobe-to-srgb-expected.txt
@@ -19,7 +19,7 @@ Green 71,149,70 71,150,69 1 Red 176,45,56 177,44,56 1 Yellow 239,200,27 238,200,27 1 -Magenta 187,82,147 187,82,148 1 +Magenta 186,82,147 187,82,148 1 Cyan (*) 0,135,165 0,135,166 1 -------------------------------------------- White 243,242,236 243,242,237 1
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-object-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-object-expected.png index 7cd107c5..55dae2f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-object-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-reflection-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-reflection-expected.png index b781572..e495e01 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-reflection-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-reflection-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-expected.png index 5e828c2..1287cea 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-fill-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-fill-text-expected.png index 43702d7..12bb3a6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-fill-text-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-fill-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-foreign-object-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-foreign-object-expected.png index d60d1d0..0a8d5d2e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-foreign-object-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/color-profile-svg-foreign-object-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png index 427c9c8..271e04b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/cross-fade-background-size-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png index 34379ae..0525e7a5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/jpeg-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/png-suite/test-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/png-suite/test-expected.png index 9a7dfa2e..5f626efc 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/png-suite/test-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/png-suite/test-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/png-with-color-profile-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/png-with-color-profile-expected.png index 34379ae..0525e7a5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/png-with-color-profile-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/png-with-color-profile-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/webp-color-profile-lossless-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/webp-color-profile-lossless-expected.png index d3f2f19..829f86b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/webp-color-profile-lossless-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/webp-color-profile-lossless-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/webp-color-profile-lossy-alpha-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/webp-color-profile-lossy-alpha-expected.png index 2603967..c7c6b394 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/webp-color-profile-lossy-alpha-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu-rasterization/images/webp-color-profile-lossy-alpha-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png index 95d8e1c5..4c5e3c3 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png index 95d8e1c5..4c5e3c3 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png new file mode 100644 index 0000000..91ff34ff --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png index 270d2a1..dfacd82c 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png index 5884531e..1d45828 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png index 5884531e..1d45828 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/prefer_compositing_to_lcd_text/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png index 5884531e..1d45828 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/rootlayerscrolls/scrollbars/listbox-scrollbar-combinations-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png new file mode 100644 index 0000000..dfacd82c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/spinvalidation/paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js b/third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js index 455601e..9bd8ac0 100644 --- a/third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js +++ b/third_party/WebKit/LayoutTests/usb/resources/usb-helpers.js
@@ -35,11 +35,10 @@ function usbMocks(mojo) { return define('USB Mocks', [ 'mojo/public/js/bindings', - 'mojo/public/js/connection', 'device/usb/public/interfaces/chooser_service.mojom', 'device/usb/public/interfaces/device_manager.mojom', 'device/usb/public/interfaces/device.mojom', - ], (bindings, connection, chooserService, deviceManager, device) => { + ], (bindings, chooserService, deviceManager, device) => { function assertDeviceInfoEquals(device, info) { assert_equals(device.usbVersionMajor, info.usb_version_major); assert_equals(device.usbVersionMinor, info.usb_version_minor); @@ -323,21 +322,17 @@ class MockDeviceManager { constructor() { + this.bindingSet = new bindings.BindingSet(deviceManager.DeviceManager); + this.mockDevices_ = new Map(); this.deviceCloseHandler_ = null; this.client_ = null; } - bindToPipe(pipe) { - this.stub_ = connection.bindHandleToStub( - pipe, deviceManager.DeviceManager); - bindings.StubBindings(this.stub_).delegate = this; - } - reset() { this.mockDevices_.forEach(device => { - for (var stub of device.stubs) - bindings.StubBindings(stub).close(); + for (var binding of device.bindingArray) + binding.close(); this.client_.onDeviceRemoved(device.info); }); this.mockDevices_.clear(); @@ -346,7 +341,7 @@ addMockDevice(info) { let device = { info: info, - stubs: [] + bindingArray: [] }; this.mockDevices_.set(info.guid, device); if (this.client_) @@ -355,8 +350,8 @@ removeMockDevice(info) { let device = this.mockDevices_.get(info.guid); - for (var stub of device.stubs) - bindings.StubBindings(stub).close(); + for (var binding of device.bindingArray) + binding.close(); this.mockDevices_.delete(info.guid); if (this.client_) this.client_.onDeviceRemoved(info); @@ -379,14 +374,13 @@ if (deviceData === undefined) { request.close(); } else { - var stub = connection.bindHandleToStub(request.handle, device.Device); - var mock = new MockDevice(deviceData.info); - bindings.StubBindings(stub).delegate = mock; - bindings.StubBindings(stub).connectionErrorHandler = () => { + var binding = new bindings.Binding( + device.Device, new MockDevice(deviceData.info), request); + binding.setConnectionErrorHandler(() => { if (this.deviceCloseHandler_) this.deviceCloseHandler_(deviceData.info); - }; - deviceData.stubs.push(stub); + }); + deviceData.bindingArray.push(binding); } } @@ -397,13 +391,10 @@ class MockChooserService { constructor() { - this.chosenDevice_ = null; - } + this.bindingSet = new bindings.BindingSet( + chooserService.ChooserService); - bindToPipe(pipe) { - this.stub_ = connection.bindHandleToStub( - pipe, chooserService.ChooserService); - bindings.StubBindings(this.stub_).delegate = this; + this.chosenDevice_ = null; } setChosenDevice(deviceInfo) { @@ -418,15 +409,15 @@ let mockDeviceManager = new MockDeviceManager; mojo.frameInterfaces.addInterfaceOverrideForTesting( deviceManager.DeviceManager.name, - pipe => { - mockDeviceManager.bindToPipe(pipe); + handle => { + mockDeviceManager.bindingSet.addBinding(mockDeviceManager, handle); }); let mockChooserService = new MockChooserService; mojo.frameInterfaces.addInterfaceOverrideForTesting( chooserService.ChooserService.name, - pipe => { - mockChooserService.bindToPipe(pipe); + handle => { + mockChooserService.bindingSet.addBinding(mockChooserService, handle); }); return fakeUsbDevices().then(fakeDevices => Promise.resolve({
diff --git a/third_party/WebKit/LayoutTests/usb/usbDevice-iframe.html b/third_party/WebKit/LayoutTests/usb/usbDevice-iframe.html index 347b9971..f275c44 100644 --- a/third_party/WebKit/LayoutTests/usb/usbDevice-iframe.html +++ b/third_party/WebKit/LayoutTests/usb/usbDevice-iframe.html
@@ -38,7 +38,8 @@ (frameInterfaces) => { frameInterfaces.addInterfaceOverrideForTesting( usb.DeviceManager.name, - pipe => { mockDeviceManager.bindToPipe(pipe); }); + handle => { mockDeviceManager.bindingSet.addBinding( + mockDeviceManager, handle); }); iframe.contentWindow.postMessage('Ready', '*'); }); } @@ -83,7 +84,8 @@ (frameInterfaces) => { frameInterfaces.addInterfaceOverrideForTesting( usb.DeviceManager.name, - pipe => { mockDeviceManager.bindToPipe(pipe); }); + handle => { mockDeviceManager.bindingSet.addBinding( + mockDeviceManager, handle); }); iframe.contentWindow.postMessage('Ready', '*'); }); }
diff --git a/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.cpp index dd9c0f09..aeabc41 100644 --- a/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.cpp
@@ -148,15 +148,15 @@ underlyingFraction, *value.interpolableValue); } -void CSSBasicShapeInterpolationType::apply( +void CSSBasicShapeInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { BasicShapePropertyFunctions::setBasicShape( - cssProperty(), *environment.state().style(), + cssProperty(), *state.style(), BasicShapeInterpolationFunctions::createBasicShape( interpolableValue, *nonInterpolableValue, - environment.state().cssToLengthConversionData())); + state.cssToLengthConversionData())); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.h index a59078938..df616f53 100644 --- a/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSBasicShapeInterpolationType.h
@@ -23,9 +23,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp index 4398239..bec967f 100644 --- a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp
@@ -331,10 +331,10 @@ } } -void CSSBorderImageLengthBoxInterpolationType::apply( +void CSSBorderImageLengthBoxInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { const SideNumbers& sideNumbers = toCSSBorderImageLengthBoxNonInterpolableValue(nonInterpolableValue) ->sideNumbers(); @@ -343,18 +343,18 @@ ->sideNonInterpolableValues(); const InterpolableList& list = toInterpolableList(interpolableValue); const auto& convertSide = - [&sideNumbers, &list, &environment, + [&sideNumbers, &list, &state, &nonInterpolableValues](size_t index) -> BorderImageLength { if (sideNumbers.isNumber[index]) return clampTo<double>(toInterpolableNumber(list.get(index))->value(), 0); return LengthInterpolationFunctions::createLength( *list.get(index), nonInterpolableValues[index].get(), - environment.state().cssToLengthConversionData(), ValueRangeNonNegative); + state.cssToLengthConversionData(), ValueRangeNonNegative); }; BorderImageLengthBox box(convertSide(SideTop), convertSide(SideRight), convertSide(SideBottom), convertSide(SideLeft)); BorderImageLengthBoxPropertyFunctions::setBorderImageLengthBox( - cssProperty(), *environment.state().style(), box); + cssProperty(), *state.style(), box); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.h index 306bae2..16ffcc3 100644 --- a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.h
@@ -23,9 +23,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.cpp index 3a3ea9d..a0d75c1d8 100644 --- a/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.cpp
@@ -262,25 +262,24 @@ underlyingValueOwner.set(*this, value); } -void CSSClipInterpolationType::apply( +void CSSClipInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { const ClipAutos& autos = toCSSClipNonInterpolableValue(nonInterpolableValue)->clipAutos(); const InterpolableList& list = toInterpolableList(interpolableValue); - const auto& convertIndex = [&list, &environment](bool isAuto, size_t index) { + const auto& convertIndex = [&list, &state](bool isAuto, size_t index) { if (isAuto) return Length(Auto); return LengthInterpolationFunctions::createLength( - *list.get(index), nullptr, - environment.state().cssToLengthConversionData(), ValueRangeAll); + *list.get(index), nullptr, state.cssToLengthConversionData(), + ValueRangeAll); }; - environment.state().style()->setClip( - LengthBox(convertIndex(autos.isTopAuto, ClipTop), - convertIndex(autos.isRightAuto, ClipRight), - convertIndex(autos.isBottomAuto, ClipBottom), - convertIndex(autos.isLeftAuto, ClipLeft))); + state.style()->setClip(LengthBox(convertIndex(autos.isTopAuto, ClipTop), + convertIndex(autos.isRightAuto, ClipRight), + convertIndex(autos.isBottomAuto, ClipBottom), + convertIndex(autos.isLeftAuto, ClipLeft))); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.h index ee580aaf..e8ed22e 100644 --- a/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSClipInterpolationType.h
@@ -25,9 +25,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.cpp index 93f1624..410d124a 100644 --- a/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.cpp
@@ -247,21 +247,21 @@ *environment.state().style())); } -void CSSColorInterpolationType::apply( +void CSSColorInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue*, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { const InterpolableList& colorPair = toInterpolableList(interpolableValue); DCHECK_EQ(colorPair.length(), InterpolableColorPairIndexCount); ColorPropertyFunctions::setUnvisitedColor( - cssProperty(), *environment.state().style(), + cssProperty(), *state.style(), resolveInterpolableColor( - *colorPair.get(Unvisited), environment.state(), false, + *colorPair.get(Unvisited), state, false, cssProperty() == CSSPropertyTextDecorationColor)); ColorPropertyFunctions::setVisitedColor( - cssProperty(), *environment.state().style(), + cssProperty(), *state.style(), resolveInterpolableColor( - *colorPair.get(Visited), environment.state(), true, + *colorPair.get(Visited), state, true, cssProperty() == CSSPropertyTextDecorationColor)); }
diff --git a/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.h index 624e810..8e31028 100644 --- a/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSColorInterpolationType.h
@@ -21,9 +21,9 @@ InterpolationValue maybeConvertUnderlyingValue( const InterpolationEnvironment&) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; static std::unique_ptr<InterpolableValue> createInterpolableColor( const Color&);
diff --git a/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.cpp index 980ef0f7..3af3c3a 100644 --- a/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.cpp
@@ -272,10 +272,10 @@ const_cast<NonInterpolableValue*>(value.nonInterpolableValue.get()); } -void CSSFilterListInterpolationType::apply( +void CSSFilterListInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { const InterpolableList& interpolableList = toInterpolableList(interpolableValue); const NonInterpolableList& nonInterpolableList = @@ -285,13 +285,13 @@ FilterOperations filterOperations; filterOperations.operations().reserveCapacity(length); - for (size_t i = 0; i < length; i++) + for (size_t i = 0; i < length; i++) { filterOperations.operations().push_back( - FilterInterpolationFunctions::createFilter(*interpolableList.get(i), - *nonInterpolableList.get(i), - environment.state())); - FilterListPropertyFunctions::setFilterList( - cssProperty(), *environment.state().style(), std::move(filterOperations)); + FilterInterpolationFunctions::createFilter( + *interpolableList.get(i), *nonInterpolableList.get(i), state)); + } + FilterListPropertyFunctions::setFilterList(cssProperty(), *state.style(), + std::move(filterOperations)); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.h index 9831d15..010464d 100644 --- a/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSFilterListInterpolationType.h
@@ -23,9 +23,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp index 3c6f82b..72522469 100644 --- a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.cpp
@@ -131,18 +131,17 @@ return convertFontSize(environment.state().style()->specifiedFontSize()); } -void CSSFontSizeInterpolationType::apply( +void CSSFontSizeInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue*, - InterpolationEnvironment& environment) const { - const FontDescription& parentFont = - environment.state().parentFontDescription(); + StyleResolverState& state) const { + const FontDescription& parentFont = state.parentFontDescription(); Length fontSizeLength = LengthInterpolationFunctions::createLength( - interpolableValue, nullptr, environment.state().fontSizeConversionData(), + interpolableValue, nullptr, state.fontSizeConversionData(), ValueRangeNonNegative); float fontSize = floatValueForLength(fontSizeLength, parentFont.getSize().value); - environment.state().fontBuilder().setSize(FontDescription::Size( + state.fontBuilder().setSize(FontDescription::Size( 0, fontSize, !fontSizeLength.isPercentOrCalc() || parentFont.isAbsoluteSize())); }
diff --git a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.h index 5af6a92c..304da5f 100644 --- a/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSFontSizeInterpolationType.h
@@ -18,9 +18,9 @@ InterpolationValue maybeConvertUnderlyingValue( const InterpolationEnvironment&) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.cpp index 9e5054d..2c5699e 100644 --- a/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.cpp
@@ -132,11 +132,11 @@ return createFontWeightValue(environment.state().style()->fontWeight()); } -void CSSFontWeightInterpolationType::apply( +void CSSFontWeightInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue*, - InterpolationEnvironment& environment) const { - environment.state().fontBuilder().setWeight( + StyleResolverState& state) const { + state.fontBuilder().setWeight( doubleToFontWeight(toInterpolableNumber(interpolableValue).value())); }
diff --git a/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.h index 39b6111..fdb0499a9 100644 --- a/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSFontWeightInterpolationType.h
@@ -19,9 +19,9 @@ InterpolationValue maybeConvertUnderlyingValue( const InterpolationEnvironment&) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue createFontWeightValue(FontWeight) const;
diff --git a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp index ada30fa..c3be227 100644 --- a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.cpp
@@ -235,14 +235,14 @@ underlyingValueOwner.set(*this, value); } -void CSSImageInterpolationType::apply( +void CSSImageInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { ImagePropertyFunctions::setStyleImage( - cssProperty(), *environment.state().style(), + cssProperty(), *state.style(), resolveStyleImage(cssProperty(), interpolableValue, nonInterpolableValue, - environment.state())); + state)); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.h index 3d863217..82f185f 100644 --- a/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSImageInterpolationType.h
@@ -22,9 +22,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; static InterpolationValue maybeConvertCSSValue(const CSSValue&, bool acceptGradients);
diff --git a/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.cpp index 35413313..0e10f90 100644 --- a/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.cpp
@@ -165,10 +165,10 @@ underlyingValueOwner.set(*this, value); } -void CSSImageListInterpolationType::apply( +void CSSImageListInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { const InterpolableList& interpolableList = toInterpolableList(interpolableValue); const size_t length = interpolableList.length(); @@ -177,12 +177,13 @@ toNonInterpolableList(*nonInterpolableValue); DCHECK_EQ(nonInterpolableList.length(), length); StyleImageList imageList(length); - for (size_t i = 0; i < length; i++) + for (size_t i = 0; i < length; i++) { imageList[i] = CSSImageInterpolationType::resolveStyleImage( cssProperty(), *interpolableList.get(i), nonInterpolableList.get(i), - environment.state()); - ImageListPropertyFunctions::setImageList( - cssProperty(), *environment.state().style(), imageList); + state); + } + ImageListPropertyFunctions::setImageList(cssProperty(), *state.style(), + imageList); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.h index 0d56d57..b2d171f 100644 --- a/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSImageListInterpolationType.h
@@ -21,9 +21,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertStyleImageList(const StyleImageList&) const;
diff --git a/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.cpp index ee6082f..2c41e0e 100644 --- a/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.cpp
@@ -260,11 +260,11 @@ underlyingValueOwner.set(*this, value); } -void CSSImageSliceInterpolationType::apply( +void CSSImageSliceInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { - ComputedStyle& style = *environment.state().style(); + StyleResolverState& state) const { + ComputedStyle& style = *state.style(); const InterpolableList& list = toInterpolableList(interpolableValue); const SliceTypes& types = toCSSImageSliceNonInterpolableValue(nonInterpolableValue)->types();
diff --git a/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.h index e05acec..3d61e22e 100644 --- a/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSImageSliceInterpolationType.h
@@ -23,9 +23,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp index 1264045..6785e24 100644 --- a/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSInterpolationType.cpp
@@ -89,4 +89,14 @@ return maybeConvertValue(*value, environment.state(), conversionCheckers); } +void CSSInterpolationType::apply( + const InterpolableValue& interpolableValue, + const NonInterpolableValue* nonInterpolableValue, + InterpolationEnvironment& environment) const { + // TODO(alancutter): Add support for applying registered custom property + // values. + return applyStandardPropertyValue(interpolableValue, nonInterpolableValue, + environment.state()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSInterpolationType.h index a780357..0898733 100644 --- a/third_party/WebKit/Source/core/animation/CSSInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSInterpolationType.h
@@ -30,6 +30,12 @@ virtual InterpolationValue maybeConvertValue(const CSSValue&, const StyleResolverState&, ConversionCheckers&) const = 0; + void apply(const InterpolableValue&, + const NonInterpolableValue*, + InterpolationEnvironment&) const final; + virtual void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const = 0; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.cpp index 8f3b82e..87053e37 100644 --- a/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.cpp
@@ -129,11 +129,10 @@ value.nonInterpolableValue.get()); } -void CSSLengthInterpolationType::apply( +void CSSLengthInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { - StyleResolverState& state = environment.state(); + StyleResolverState& state) const { ComputedStyle& style = *state.style(); float zoom = effectiveZoom(style); Length length = LengthInterpolationFunctions::createLength(
diff --git a/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.h index 6e219910..e774aa48 100644 --- a/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSLengthInterpolationType.h
@@ -23,9 +23,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: float effectiveZoom(const ComputedStyle&) const;
diff --git a/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.cpp index c3a82e0..c4f8a65 100644 --- a/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.cpp
@@ -147,10 +147,10 @@ LengthInterpolationFunctions::composite); } -void CSSLengthListInterpolationType::apply( +void CSSLengthListInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { const InterpolableList& interpolableList = toInterpolableList(interpolableValue); const size_t length = interpolableList.length(); @@ -162,10 +162,10 @@ for (size_t i = 0; i < length; i++) { result[i] = LengthInterpolationFunctions::createLength( *interpolableList.get(i), nonInterpolableList.get(i), - environment.state().cssToLengthConversionData(), m_valueRange); + state.cssToLengthConversionData(), m_valueRange); } - LengthListPropertyFunctions::setLengthList( - cssProperty(), *environment.state().style(), std::move(result)); + LengthListPropertyFunctions::setLengthList(cssProperty(), *state.style(), + std::move(result)); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.h index 00077408..f548e54 100644 --- a/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSLengthListInterpolationType.h
@@ -21,9 +21,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp index 5b374f6d..4f4cd50 100644 --- a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp
@@ -88,16 +88,16 @@ return createNumberValue(underlyingNumber); } -void CSSNumberInterpolationType::apply( +void CSSNumberInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue*, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { double clampedNumber = NumberPropertyFunctions::clampNumber( cssProperty(), toInterpolableNumber(interpolableValue).value()); - if (!NumberPropertyFunctions::setNumber( - cssProperty(), *environment.state().style(), clampedNumber)) + if (!NumberPropertyFunctions::setNumber(cssProperty(), *state.style(), + clampedNumber)) StyleBuilder::applyProperty( - cssProperty(), environment.state(), + cssProperty(), state, *CSSPrimitiveValue::create(clampedNumber, CSSPrimitiveValue::UnitType::Number)); }
diff --git a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.h index 8667eff..fa9863c 100644 --- a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.h
@@ -16,9 +16,9 @@ InterpolationValue maybeConvertUnderlyingValue( const InterpolationEnvironment&) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue createNumberValue(double number) const;
diff --git a/third_party/WebKit/Source/core/animation/CSSOffsetRotateInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSOffsetRotateInterpolationType.cpp index f1d1d08..78aa125 100644 --- a/third_party/WebKit/Source/core/animation/CSSOffsetRotateInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSOffsetRotateInterpolationType.cpp
@@ -166,11 +166,11 @@ } } -void CSSOffsetRotateInterpolationType::apply( +void CSSOffsetRotateInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { - environment.state().style()->setOffsetRotation(StyleOffsetRotation( + StyleResolverState& state) const { + state.style()->setOffsetRotation(StyleOffsetRotation( toInterpolableNumber(interpolableValue).value(), toCSSOffsetRotationNonInterpolableValue(*nonInterpolableValue) .rotationType()));
diff --git a/third_party/WebKit/Source/core/animation/CSSOffsetRotateInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSOffsetRotateInterpolationType.h index 060b4bd..76411fd 100644 --- a/third_party/WebKit/Source/core/animation/CSSOffsetRotateInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSOffsetRotateInterpolationType.h
@@ -23,9 +23,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.cpp index ab39b4f..cfd1308 100644 --- a/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.cpp
@@ -100,14 +100,14 @@ CSSColorInterpolationType::createInterpolableColor(underlyingColor)); } -void CSSPaintInterpolationType::apply( +void CSSPaintInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableColor, const NonInterpolableValue*, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { PaintPropertyFunctions::setColor( - cssProperty(), *environment.state().style(), + cssProperty(), *state.style(), CSSColorInterpolationType::resolveInterpolableColor(interpolableColor, - environment.state())); + state)); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.h index 36a2036..2bad2aec 100644 --- a/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSPaintInterpolationType.h
@@ -16,9 +16,9 @@ InterpolationValue maybeConvertUnderlyingValue( const InterpolationEnvironment&) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.cpp index 03f7173..ca884dc 100644 --- a/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.cpp
@@ -13,20 +13,19 @@ namespace blink { -void CSSPathInterpolationType::apply( +void CSSPathInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { DCHECK_EQ(cssProperty(), CSSPropertyD); std::unique_ptr<SVGPathByteStream> pathByteStream = PathInterpolationFunctions::appliedValue(interpolableValue, nonInterpolableValue); if (pathByteStream->isEmpty()) { - environment.state().style()->setD(nullptr); + state.style()->setD(nullptr); return; } - environment.state().style()->setD( - StylePath::create(std::move(pathByteStream))); + state.style()->setD(StylePath::create(std::move(pathByteStream))); } void CSSPathInterpolationType::composite(
diff --git a/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.h index d98d8c74..480b09a 100644 --- a/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSPathInterpolationType.h
@@ -14,9 +14,9 @@ CSSPathInterpolationType(PropertyHandle property) : CSSInterpolationType(property) {} - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; void composite(UnderlyingValueOwner&, double underlyingFraction, const InterpolationValue&,
diff --git a/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.cpp index 2646025..fb0bbac 100644 --- a/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.cpp
@@ -206,15 +206,15 @@ underlyingNonInterpolableValue.composite(nonInterpolableValue, progress); } -void CSSRotateInterpolationType::apply( +void CSSRotateInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* untypedNonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { double progress = toInterpolableNumber(interpolableValue).value(); const CSSRotateNonInterpolableValue& nonInterpolableValue = toCSSRotateNonInterpolableValue(*untypedNonInterpolableValue); Rotation rotation = nonInterpolableValue.slerpedRotation(progress); - environment.state().style()->setRotate( + state.style()->setRotate( RotateTransformOperation::create(rotation, TransformOperation::Rotate3D)); }
diff --git a/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.h index 323efd6..35e96ae 100644 --- a/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSRotateInterpolationType.h
@@ -29,9 +29,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.cpp index c39cd17..a98f1f6 100644 --- a/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.cpp
@@ -214,12 +214,12 @@ } } -void CSSScaleInterpolationType::apply( +void CSSScaleInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue*, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { Scale scale(interpolableValue); - environment.state().style()->setScale(ScaleTransformOperation::create( + state.style()->setScale(ScaleTransformOperation::create( scale.array[0], scale.array[1], scale.array[2], TransformOperation::Scale3D)); }
diff --git a/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.h index 2d2400f..feefd9a 100644 --- a/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSScaleInterpolationType.h
@@ -22,9 +22,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertSingle(const PropertySpecificKeyframe&,
diff --git a/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.cpp index 7631a8d50..3318db7b 100644 --- a/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.cpp
@@ -157,14 +157,13 @@ return ShadowList::adopt(shadows); } -void CSSShadowListInterpolationType::apply( +void CSSShadowListInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { ShadowListPropertyFunctions::setShadowList( - cssProperty(), *environment.state().style(), - createShadowList(interpolableValue, nonInterpolableValue, - environment.state())); + cssProperty(), *state.style(), + createShadowList(interpolableValue, nonInterpolableValue, state)); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.h index 754ecd93..0835cad 100644 --- a/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSShadowListInterpolationType.h
@@ -22,9 +22,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue convertShadowList(const ShadowList*, double zoom) const;
diff --git a/third_party/WebKit/Source/core/animation/CSSSizeListInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSSizeListInterpolationType.cpp index c8f659a..bb37ea2 100644 --- a/third_party/WebKit/Source/core/animation/CSSSizeListInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSSizeListInterpolationType.cpp
@@ -172,10 +172,10 @@ SizeInterpolationFunctions::composite); } -void CSSSizeListInterpolationType::apply( +void CSSSizeListInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { const auto& interpolableList = toInterpolableList(interpolableValue); const auto& nonInterpolableList = toNonInterpolableList(*nonInterpolableValue); @@ -188,10 +188,10 @@ sizeList[i] = SizeInterpolationFunctions::createFillSize( *interpolableList.get(i * 2), nonInterpolableList.get(i * 2), *interpolableList.get(i * 2 + 1), nonInterpolableList.get(i * 2 + 1), - environment.state().cssToLengthConversionData()); + state.cssToLengthConversionData()); } - SizeListPropertyFunctions::setSizeList( - cssProperty(), *environment.state().style(), sizeList); + SizeListPropertyFunctions::setSizeList(cssProperty(), *state.style(), + sizeList); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSSizeListInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSSizeListInterpolationType.h index 3efd0d2..a695d6d 100644 --- a/third_party/WebKit/Source/core/animation/CSSSizeListInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSSizeListInterpolationType.h
@@ -20,9 +20,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.cpp index 731a736..661af64 100644 --- a/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.cpp
@@ -234,17 +234,17 @@ nonInterpolableValue.lengthNonInterpolableValue()); } -void CSSTextIndentInterpolationType::apply( +void CSSTextIndentInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { const CSSTextIndentNonInterpolableValue& cssTextIndentNonInterpolableValue = toCSSTextIndentNonInterpolableValue(*nonInterpolableValue); - ComputedStyle& style = *environment.state().style(); + ComputedStyle& style = *state.style(); style.setTextIndent(LengthInterpolationFunctions::createLength( interpolableValue, cssTextIndentNonInterpolableValue.lengthNonInterpolableValue(), - environment.state().cssToLengthConversionData(), ValueRangeAll)); + state.cssToLengthConversionData(), ValueRangeAll)); const IndentMode& mode = cssTextIndentNonInterpolableValue.mode(); style.setTextIndentLine(mode.line);
diff --git a/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.h index 086cd7e..c6ddb85 100644 --- a/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSTextIndentInterpolationType.h
@@ -25,9 +25,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.cpp index 625a971..03bf8eb 100644 --- a/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.cpp
@@ -253,14 +253,14 @@ underlyingNonInterpolableValue.composite(nonInterpolableValue, progress); } -void CSSTransformInterpolationType::apply( +void CSSTransformInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* untypedNonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { double progress = toInterpolableNumber(interpolableValue).value(); const CSSTransformNonInterpolableValue& nonInterpolableValue = toCSSTransformNonInterpolableValue(*untypedNonInterpolableValue); - environment.state().style()->setTransform( + state.style()->setTransform( nonInterpolableValue.getInterpolatedTransform(progress)); }
diff --git a/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.h index 8e38824..7601f6b 100644 --- a/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSTransformInterpolationType.h
@@ -29,9 +29,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.cpp index ea9504af..a1e9934 100644 --- a/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.cpp
@@ -144,13 +144,13 @@ environment.state().style()->effectiveZoom()); } -void CSSTranslateInterpolationType::apply( +void CSSTranslateInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue*, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { const InterpolableList& list = toInterpolableList(interpolableValue); const CSSToLengthConversionData& conversionData = - environment.state().cssToLengthConversionData(); + state.cssToLengthConversionData(); Length x = LengthInterpolationFunctions::createLength( *list.get(TranslateX), nullptr, conversionData, ValueRangeAll); Length y = LengthInterpolationFunctions::createLength( @@ -163,7 +163,7 @@ if (!x.isZero() || !y.isZero() || z != 0) result = TranslateTransformOperation::create( x, y, z, TransformOperation::Translate3D); - environment.state().style()->setTranslate(result.release()); + state.style()->setTranslate(result.release()); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.h index f050929..49a1ff4 100644 --- a/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSTranslateInterpolationType.h
@@ -18,9 +18,9 @@ InterpolationValue maybeConvertUnderlyingValue( const InterpolationEnvironment&) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue maybeConvertNeutral(const InterpolationValue& underlying,
diff --git a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.cpp index a1a00ba..9f15de8 100644 --- a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.cpp
@@ -49,12 +49,12 @@ toCSSPropertySpecificKeyframe(keyframe).value())); } -void CSSValueInterpolationType::apply( +void CSSValueInterpolationType::applyStandardPropertyValue( const InterpolableValue&, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { StyleBuilder::applyProperty( - cssProperty(), environment.state(), + cssProperty(), state, toCSSValueNonInterpolableValue(nonInterpolableValue)->cssValue()); }
diff --git a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h index 4a1674c1..e70ed9d 100644 --- a/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSValueInterpolationType.h
@@ -66,9 +66,9 @@ underlyingValueOwner.set(*this, value); } - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp index 0526288d..d2dd496b 100644 --- a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp
@@ -177,17 +177,17 @@ underlyingValueOwner.set(*this, value); } -void CSSVisibilityInterpolationType::apply( +void CSSVisibilityInterpolationType::applyStandardPropertyValue( const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, - InterpolationEnvironment& environment) const { + StyleResolverState& state) const { // Visibility interpolation has been deferred to application time here due to // its non-linear behaviour. double fraction = toInterpolableNumber(interpolableValue).value(); EVisibility visibility = toCSSVisibilityNonInterpolableValue(nonInterpolableValue) ->visibility(fraction); - environment.state().style()->setVisibility(visibility); + state.style()->setVisibility(visibility); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.h b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.h index ec8f64b..8fcab504 100644 --- a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.h +++ b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.h
@@ -26,9 +26,9 @@ double underlyingFraction, const InterpolationValue&, double interpolationFraction) const final; - void apply(const InterpolableValue&, - const NonInterpolableValue*, - InterpolationEnvironment&) const final; + void applyStandardPropertyValue(const InterpolableValue&, + const NonInterpolableValue*, + StyleResolverState&) const final; private: InterpolationValue createVisibilityValue(EVisibility) const;
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp index 61d0947..6cb11d8 100644 --- a/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp +++ b/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
@@ -347,10 +347,21 @@ return false; if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { - // TODO(wkorman): Consider effect node for opacity. + // We query paint property tree state below to determine whether the + // animation is compositable. There is a known lifecycle violation where an + // animation can be cancelled during style update. See + // CompositorAnimations::cancelAnimationOnCompositor and + // http://crbug.com/676456. When this is fixed we would like to enable + // the DCHECK below. + // DCHECK(document().lifecycle().state() >= + // DocumentLifecycle::PrePaintClean); + const ObjectPaintProperties* paintProperties = + element.layoutObject()->paintProperties(); const TransformPaintPropertyNode* transformNode = - element.layoutObject()->paintProperties()->transform(); - return transformNode && transformNode->hasDirectCompositingReasons(); + paintProperties->transform(); + const EffectPaintPropertyNode* effectNode = paintProperties->effect(); + return (transformNode && transformNode->hasDirectCompositingReasons()) || + (effectNode && effectNode->hasDirectCompositingReasons()); } return element.layoutObject() &&
diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp index 6e6df1d..40110221 100644 --- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp +++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
@@ -1254,6 +1254,25 @@ EXPECT_TRUE(element->elementAnimations()->animations().isEmpty()); } +namespace { + +void updateDummyTransformNode(ObjectPaintProperties& properties, + CompositingReasons reasons) { + properties.updateTransform(TransformPaintPropertyNode::root(), + TransformationMatrix(), FloatPoint3D(), false, 0, + reasons); +} + +void updateDummyEffectNode(ObjectPaintProperties& properties, + CompositingReasons reasons) { + properties.updateEffect( + EffectPaintPropertyNode::root(), TransformPaintPropertyNode::root(), + ClipPaintPropertyNode::root(), CompositorFilterOperations(), 1.0, + SkBlendMode::kSrcOver, reasons); +} + +} // namespace + TEST_F(AnimationCompositorAnimationsTest, canStartAnimationOnCompositorTransformSPv2) { Persistent<Element> element = m_document->createElement("shared"); @@ -1266,15 +1285,11 @@ // Add a transform with a compositing reason, which should allow starting // animation. - properties.updateTransform(TransformPaintPropertyNode::root(), - TransformationMatrix(), FloatPoint3D(), false, 0, - CompositingReasonActiveAnimation); + updateDummyTransformNode(properties, CompositingReasonActiveAnimation); EXPECT_TRUE(CompositorAnimations::canStartAnimationOnCompositor(*element)); // Setting to CompositingReasonNone should produce false. - properties.updateTransform(TransformPaintPropertyNode::root(), - TransformationMatrix(), FloatPoint3D(), false, 0, - CompositingReasonNone); + updateDummyTransformNode(properties, CompositingReasonNone); EXPECT_FALSE(CompositorAnimations::canStartAnimationOnCompositor(*element)); // Clearing the transform node entirely should also produce false. @@ -1285,4 +1300,31 @@ LayoutObjectProxy::dispose(layoutObject); } +TEST_F(AnimationCompositorAnimationsTest, + canStartAnimationOnCompositorEffectSPv2) { + Persistent<Element> element = m_document->createElement("shared"); + LayoutObjectProxy* layoutObject = LayoutObjectProxy::create(element.get()); + element->setLayoutObject(layoutObject); + + ScopedSlimmingPaintV2ForTest enableSPv2(true); + auto& properties = + layoutObject->getMutableForPainting().ensurePaintProperties(); + + // Add an effect with a compositing reason, which should allow starting + // animation. + updateDummyEffectNode(properties, CompositingReasonActiveAnimation); + EXPECT_TRUE(CompositorAnimations::canStartAnimationOnCompositor(*element)); + + // Setting to CompositingReasonNone should produce false. + updateDummyEffectNode(properties, CompositingReasonNone); + EXPECT_FALSE(CompositorAnimations::canStartAnimationOnCompositor(*element)); + + // Clearing the effect node entirely should also produce false. + properties.clearEffect(); + EXPECT_FALSE(CompositorAnimations::canStartAnimationOnCompositor(*element)); + + element->setLayoutObject(nullptr); + LayoutObjectProxy::dispose(layoutObject); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/CSSProperty.cpp b/third_party/WebKit/Source/core/css/CSSProperty.cpp index 69452b0b..7df3a339 100644 --- a/third_party/WebKit/Source/core/css/CSSProperty.cpp +++ b/third_party/WebKit/Source/core/css/CSSProperty.cpp
@@ -54,13 +54,13 @@ LogicalBoxSide logicalSide, const StylePropertyShorthand& shorthand) { if (direction == TextDirection::Ltr) { - if (writingMode == TopToBottomWritingMode) { + if (isHorizontalWritingMode(writingMode)) { // The common case. The logical and physical box sides match. // Left = Start, Right = End, Before = Top, After = Bottom return shorthand.properties()[logicalSide]; } - if (writingMode == LeftToRightWritingMode) { + if (isFlippedLinesWritingMode(writingMode)) { // Start = Top, End = Bottom, Before = Left, After = Right. switch (logicalSide) { case StartSide: @@ -87,7 +87,7 @@ } } - if (writingMode == TopToBottomWritingMode) { + if (isHorizontalWritingMode(writingMode)) { // Start = Right, End = Left, Before = Top, After = Bottom switch (logicalSide) { case StartSide: @@ -101,7 +101,7 @@ } } - if (writingMode == LeftToRightWritingMode) { + if (isFlippedLinesWritingMode(writingMode)) { // Start = Bottom, End = Top, Before = Left, After = Right switch (logicalSide) { case StartSide:
diff --git a/third_party/WebKit/Source/core/dom/Fullscreen.cpp b/third_party/WebKit/Source/core/dom/Fullscreen.cpp index 40cc448..33ed40d 100644 --- a/third_party/WebKit/Source/core/dom/Fullscreen.cpp +++ b/third_party/WebKit/Source/core/dom/Fullscreen.cpp
@@ -34,6 +34,7 @@ #include "core/dom/ElementTraversal.h" #include "core/dom/StyleEngine.h" #include "core/events/Event.h" +#include "core/frame/FrameView.h" #include "core/frame/HostsUsingFeatures.h" #include "core/frame/LocalFrame.h" #include "core/frame/Settings.h" @@ -894,6 +895,14 @@ // https://crbug.com/668758 frame->eventHandler().scheduleHoverStateUpdate(); frame->chromeClient().fullscreenElementChanged(fromElement, toElement); + + if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && + !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { + // Fullscreen status affects scroll paint properties through + // FrameView::userInputScrollable(). + if (FrameView* frameView = frame->view()) + frameView->setNeedsPaintPropertyUpdate(); + } } // TODO(foolip): This should not call updateStyleAndLayoutTree.
diff --git a/third_party/WebKit/Source/core/editing/FrameCaret.cpp b/third_party/WebKit/Source/core/editing/FrameCaret.cpp index 1a65d87..7efa385 100644 --- a/third_party/WebKit/Source/core/editing/FrameCaret.cpp +++ b/third_party/WebKit/Source/core/editing/FrameCaret.cpp
@@ -29,11 +29,12 @@ #include "core/editing/Editor.h" #include "core/editing/SelectionEditor.h" #include "core/editing/commands/CompositeEditCommand.h" +#include "core/frame/FrameView.h" #include "core/frame/LocalFrame.h" #include "core/frame/Settings.h" #include "core/html/TextControlElement.h" #include "core/layout/LayoutTheme.h" -#include "core/layout/api/LayoutViewItem.h" +#include "core/layout/api/LayoutPartItem.h" #include "core/page/Page.h" #include "core/paint/PaintLayer.h" #include "public/platform/WebTraceLocation.h" @@ -142,6 +143,13 @@ if (Page* page = m_frame->page()) page->animator().scheduleVisualUpdate(m_frame->localFrameRoot()); + + // Ensure the frame will be checked for paint invalidation during + // PrePaintTreeWalk. + if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) { + if (auto layoutItem = m_frame->ownerLayoutItem()) + layoutItem.setMayNeedPaintInvalidation(); + } } bool FrameCaret::caretPositionIsValidForDocument(
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp index 08a44f70..9c5cfa2 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.cpp +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -657,10 +657,6 @@ updateScrollbars(); ScrollableArea::contentsResized(); - if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && - !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) - setNeedsPaintPropertyUpdate(); - Page* page = frame().page(); if (!page) return; @@ -4019,6 +4015,9 @@ if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) return; + if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) + setNeedsPaintPropertyUpdate(); + // Avoid drawing two sets of scrollbars when visual viewport is enabled. if (visualViewportSuppliesScrollbars()) { m_scrollbarManager.setHasHorizontalScrollbar(false);
diff --git a/third_party/WebKit/Source/core/html/HTMLElement.idl b/third_party/WebKit/Source/core/html/HTMLElement.idl index cbf6d871..37a0f7f7 100644 --- a/third_party/WebKit/Source/core/html/HTMLElement.idl +++ b/third_party/WebKit/Source/core/html/HTMLElement.idl
@@ -61,8 +61,8 @@ [RuntimeEnabled=CSSTypedOM] readonly attribute StylePropertyMap styleMap; // Non-standard APIs - [TreatNullAs=NullString, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementInnerText] attribute DOMString innerText; - [TreatNullAs=NullString, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementOuterText] attribute DOMString outerText; + [TreatNullAs=NullString, CEReactions, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementInnerText] attribute DOMString innerText; + [TreatNullAs=NullString, CEReactions, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementOuterText] attribute DOMString outerText; [CEReactions, Reflect, TreatNullAs=NullString, MeasureAs=PrefixedHTMLElementDropzone] attribute DOMString webkitdropzone; };
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp index fb3c6cb..66b2663d 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -5073,8 +5073,8 @@ // We are putting ourselves into our parent's coordinate space. If there is a // flipped block mismatch in a particular axis, then we have to flip the rect // along that axis. - if (style()->getWritingMode() == RightToLeftWritingMode || - parentStyle.getWritingMode() == RightToLeftWritingMode) + if (isFlippedBlocksWritingMode(style()->getWritingMode()) || + isFlippedBlocksWritingMode(parentStyle.getWritingMode())) rect.setX(size().width() - rect.maxX()); return rect; @@ -5129,8 +5129,8 @@ // We are putting ourselves into our parent's coordinate space. If there is a // flipped block mismatch in a particular axis, then we have to flip the rect // along that axis. - if (style()->getWritingMode() == RightToLeftWritingMode || - parentStyle.getWritingMode() == RightToLeftWritingMode) + if (isFlippedBlocksWritingMode(style()->getWritingMode()) || + isFlippedBlocksWritingMode(parentStyle.getWritingMode())) rect.setX(size().width() - rect.maxX()); return rect;
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp index fc8c8951..07b85d0 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutFlexibleBox.cpp
@@ -270,29 +270,29 @@ if (flexDirection == FlowRow) { if (textDirection == TextDirection::Rtl) { - if (writingMode == TopToBottomWritingMode) + if (blink::isHorizontalWritingMode(writingMode)) size.expand(adjustmentWidth, 0); else size.expand(0, adjustmentHeight); } - if (writingMode == RightToLeftWritingMode) + if (isFlippedBlocksWritingMode(writingMode)) size.expand(adjustmentWidth, 0); } else if (flexDirection == FlowRowReverse) { if (textDirection == TextDirection::Ltr) { - if (writingMode == TopToBottomWritingMode) + if (blink::isHorizontalWritingMode(writingMode)) size.expand(adjustmentWidth, 0); else size.expand(0, adjustmentHeight); } - if (writingMode == RightToLeftWritingMode) + if (isFlippedBlocksWritingMode(writingMode)) size.expand(adjustmentWidth, 0); } else if (flexDirection == FlowColumn) { - if (writingMode == RightToLeftWritingMode) + if (isFlippedBlocksWritingMode(writingMode)) size.expand(adjustmentWidth, 0); } else { - if (writingMode == TopToBottomWritingMode) + if (blink::isHorizontalWritingMode(writingMode)) size.expand(0, adjustmentHeight); - else if (writingMode == LeftToRightWritingMode) + else if (isFlippedLinesWritingMode(writingMode)) size.expand(adjustmentWidth, 0); } return size; @@ -459,9 +459,10 @@ } bool LayoutFlexibleBox::isLeftToRightFlow() const { - if (isColumnFlow()) - return style()->getWritingMode() == TopToBottomWritingMode || - style()->getWritingMode() == LeftToRightWritingMode; + if (isColumnFlow()) { + return blink::isHorizontalWritingMode(style()->getWritingMode()) || + isFlippedLinesWritingMode(style()->getWritingMode()); + } return style()->isLeftToRightDirection() ^ (style()->flexDirection() == FlowRowReverse); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h index d1b4b140..6115e81 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.h +++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -1719,6 +1719,8 @@ friend class PaintPropertyTreeBuilder; FRIEND_TEST_ALL_PREFIXES(AnimationCompositorAnimationsTest, canStartAnimationOnCompositorTransformSPv2); + FRIEND_TEST_ALL_PREFIXES(AnimationCompositorAnimationsTest, + canStartAnimationOnCompositorEffectSPv2); // The following two functions can be called from PaintPropertyTreeBuilder // only.
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp index 31c3bfb..43b90080 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableCell.cpp
@@ -335,7 +335,7 @@ LayoutUnit LayoutTableCell::paddingTop() const { LayoutUnit result = computedCSSPaddingTop(); if (isHorizontalWritingMode()) - result += (style()->getWritingMode() == TopToBottomWritingMode + result += (blink::isHorizontalWritingMode(style()->getWritingMode()) ? intrinsicPaddingBefore() : intrinsicPaddingAfter()); // TODO(leviw): The floor call should be removed when Table is sub-pixel @@ -346,7 +346,7 @@ LayoutUnit LayoutTableCell::paddingBottom() const { LayoutUnit result = computedCSSPaddingBottom(); if (isHorizontalWritingMode()) - result += (style()->getWritingMode() == TopToBottomWritingMode + result += (blink::isHorizontalWritingMode(style()->getWritingMode()) ? intrinsicPaddingAfter() : intrinsicPaddingBefore()); // TODO(leviw): The floor call should be removed when Table is sub-pixel @@ -357,7 +357,7 @@ LayoutUnit LayoutTableCell::paddingLeft() const { LayoutUnit result = computedCSSPaddingLeft(); if (!isHorizontalWritingMode()) - result += (style()->getWritingMode() == LeftToRightWritingMode + result += (isFlippedLinesWritingMode(style()->getWritingMode()) ? intrinsicPaddingBefore() : intrinsicPaddingAfter()); // TODO(leviw): The floor call should be removed when Table is sub-pixel @@ -368,7 +368,7 @@ LayoutUnit LayoutTableCell::paddingRight() const { LayoutUnit result = computedCSSPaddingRight(); if (!isHorizontalWritingMode()) - result += (style()->getWritingMode() == LeftToRightWritingMode + result += (isFlippedLinesWritingMode(style()->getWritingMode()) ? intrinsicPaddingAfter() : intrinsicPaddingBefore()); // TODO(leviw): The floor call should be removed when Table is sub-pixel
diff --git a/third_party/WebKit/Source/core/layout/LayoutVTTCue.cpp b/third_party/WebKit/Source/core/layout/LayoutVTTCue.cpp index 891c8ff..d0984f1 100644 --- a/third_party/WebKit/Source/core/layout/LayoutVTTCue.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutVTTCue.cpp
@@ -85,7 +85,7 @@ WritingMode writingMode = m_cueBox.style()->getWritingMode(); // 8. Vertical Growing Left: Add one to line then negate it. - if (writingMode == RightToLeftWritingMode) + if (isFlippedBlocksWritingMode(writingMode)) linePosition = -(linePosition + 1); // 9. Let position be the result of multiplying step and line offset. @@ -93,7 +93,7 @@ // 10. Vertical Growing Left: Decrease position by the width of the // bounding box of the boxes in boxes, then increase position by step. - if (writingMode == RightToLeftWritingMode) { + if (isFlippedBlocksWritingMode(writingMode)) { position -= m_cueBox.size().width(); position += step; }
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp index 9587807..f285365d 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.cpp
@@ -178,6 +178,19 @@ return style.shouldCompositeForCurrentAnimations(); } +bool CompositingReasonFinder::requiresCompositingForEffectAnimation( + const ComputedStyle& style) { + if (style.subtreeWillChangeContents()) { + return style.isRunningOpacityAnimationOnCompositor() || + style.isRunningFilterAnimationOnCompositor() || + style.isRunningBackdropFilterAnimationOnCompositor(); + } + + return style.hasCurrentOpacityAnimation() || + style.hasCurrentFilterAnimation() || + style.hasCurrentBackdropFilterAnimation(); +} + bool CompositingReasonFinder::requiresCompositingForTransformAnimation( const ComputedStyle& style) { return style.subtreeWillChangeContents()
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.h b/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.h index b2afffc..61b8b56 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.h +++ b/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinder.h
@@ -33,6 +33,7 @@ bool hasOverflowScrollTrigger() const; bool requiresCompositingForScrollableFrame() const; static bool requiresCompositingForAnimation(const ComputedStyle&); + static bool requiresCompositingForEffectAnimation(const ComputedStyle&); static bool requiresCompositingForTransformAnimation(const ComputedStyle&); static bool requiresCompositingForTransform(const LayoutObject&);
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinderTest.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinderTest.cpp index 0945dd3..49f8ffe7 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinderTest.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositingReasonFinderTest.cpp
@@ -211,4 +211,64 @@ *style)); } +TEST_F(CompositingReasonFinderTest, RequiresCompositingForEffectAnimation) { + RefPtr<ComputedStyle> style = ComputedStyle::create(); + + style->setSubtreeWillChangeContents(false); + + // In the interest of brevity, for each side of subtreeWillChangeContents() + // code path we only check that any one of the effect related animation flags + // being set produces true, rather than every permutation. + + style->setHasCurrentOpacityAnimation(false); + style->setHasCurrentFilterAnimation(false); + style->setHasCurrentBackdropFilterAnimation(false); + EXPECT_FALSE( + CompositingReasonFinder::requiresCompositingForEffectAnimation(*style)); + + style->setHasCurrentOpacityAnimation(true); + style->setHasCurrentFilterAnimation(false); + style->setHasCurrentBackdropFilterAnimation(false); + EXPECT_TRUE( + CompositingReasonFinder::requiresCompositingForEffectAnimation(*style)); + + style->setHasCurrentOpacityAnimation(false); + style->setHasCurrentFilterAnimation(true); + style->setHasCurrentBackdropFilterAnimation(false); + EXPECT_TRUE( + CompositingReasonFinder::requiresCompositingForEffectAnimation(*style)); + + style->setHasCurrentOpacityAnimation(false); + style->setHasCurrentFilterAnimation(false); + style->setHasCurrentBackdropFilterAnimation(true); + EXPECT_TRUE( + CompositingReasonFinder::requiresCompositingForEffectAnimation(*style)); + + // Check the other side of subtreeWillChangeContents. + style->setSubtreeWillChangeContents(true); + style->setHasCurrentOpacityAnimation(false); + style->setHasCurrentFilterAnimation(false); + style->setHasCurrentBackdropFilterAnimation(false); + EXPECT_FALSE( + CompositingReasonFinder::requiresCompositingForEffectAnimation(*style)); + + style->setIsRunningOpacityAnimationOnCompositor(true); + style->setIsRunningFilterAnimationOnCompositor(false); + style->setIsRunningBackdropFilterAnimationOnCompositor(false); + EXPECT_TRUE( + CompositingReasonFinder::requiresCompositingForEffectAnimation(*style)); + + style->setIsRunningOpacityAnimationOnCompositor(false); + style->setIsRunningFilterAnimationOnCompositor(true); + style->setIsRunningBackdropFilterAnimationOnCompositor(false); + EXPECT_TRUE( + CompositingReasonFinder::requiresCompositingForEffectAnimation(*style)); + + style->setIsRunningOpacityAnimationOnCompositor(false); + style->setIsRunningFilterAnimationOnCompositor(false); + style->setIsRunningBackdropFilterAnimationOnCompositor(true); + EXPECT_TRUE( + CompositingReasonFinder::requiresCompositingForEffectAnimation(*style)); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp index b2f4792..8abb550 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -468,11 +468,17 @@ // We should generate a special clip node to represent this expansion. } + CompositingReasons compositingReasons = + CompositingReasonFinder::requiresCompositingForEffectAnimation( + object.styleRef()); + if (compositingReasons != CompositingReasonNone) + effectNodeNeeded = true; + if (effectNodeNeeded) { auto& properties = object.getMutableForPainting().ensurePaintProperties(); context.forceSubtreeUpdate |= properties.updateEffect( context.currentEffect, context.current.transform, outputClip, - std::move(filter), opacity, blendMode); + std::move(filter), opacity, blendMode, compositingReasons); } else { if (auto* properties = object.getMutableForPainting().paintProperties()) context.forceSubtreeUpdate |= properties->clearEffect();
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp index 4e72e74..e4d02a0 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -414,30 +414,44 @@ EXPECT_TRUE(properties->transform()->hasDirectCompositingReasons()); } +namespace { + +const char* kSimpleOpacityExampleHTML = + "<style>" + "div {" + " width: 100px;" + " height: 100px;" + " background-color: red;" + " animation-name: example;" + " animation-duration: 4s;" + "}" + "@keyframes example {" + " from { opacity: 0.0;}" + " to { opacity: 1.0;}" + "}" + "</style>" + "<div id='target'></div>"; + +} // namespace + TEST_P(PaintPropertyTreeBuilderTest, OpacityAnimationDoesNotCreateTransformNode) { - setBodyInnerHTML( - "<style>" - "div {" - " width: 100px;" - " height: 100px;" - " background-color: red;" - " animation-name: example;" - " animation-duration: 4s;" - "}" - "@keyframes example {" - " from { opacity: 0.0;}" - " to { opacity: 1.0;}" - "}" - "</style>" - "<div id='target'></div>"); - + setBodyInnerHTML(kSimpleOpacityExampleHTML); Element* target = document().getElementById("target"); const ObjectPaintProperties* properties = target->layoutObject()->paintProperties(); EXPECT_EQ(nullptr, properties->transform()); } +TEST_P(PaintPropertyTreeBuilderTest, + EffectNodeWithActiveAnimationHasDirectCompositingReason) { + setBodyInnerHTML(kSimpleOpacityExampleHTML); + Element* target = document().getElementById("target"); + const ObjectPaintProperties* properties = + target->layoutObject()->paintProperties(); + EXPECT_TRUE(properties->effect()->hasDirectCompositingReasons()); +} + TEST_P(PaintPropertyTreeBuilderTest, WillChangeTransform) { setBodyInnerHTML( "<style> body { margin: 0 } </style>"
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp index 460fa435..726bee4 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
@@ -468,4 +468,34 @@ EXPECT_EQ(nullptr, properties->transform()); } +TEST_P(PaintPropertyTreeUpdateTest, + EffectNodeWithAnimationLosesNodeWhenAnimationRemoved) { + setBodyInnerHTML( + "<style>" + "div {" + " width: 100px;" + " height: 100px;" + " background-color: red;" + "} " + ".animate {" + " animation-name: test;" + " animation-duration: 4s;" + "}" + "@keyframes test {" + " from { opacity: 0.0;}" + " to { opacity: 1.0;}" + "}" + "</style>" + "<div id='target' class='animate'></div>"); + Element* target = document().getElementById("target"); + const ObjectPaintProperties* properties = + target->layoutObject()->paintProperties(); + EXPECT_TRUE(properties->effect()->hasDirectCompositingReasons()); + + // Removing the animation should remove the effect node. + target->removeAttribute(HTMLNames::classAttr); + document().view()->updateAllLifecyclePhases(); + EXPECT_EQ(nullptr, properties->effect()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js index 606c1ef..a1fbf21 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/BreakpointManager.js
@@ -56,6 +56,7 @@ this._workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this._projectRemoved, this); this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this); this._workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, this._uiSourceCodeRemoved, this); + this._debuggerWorkspaceBinding.addEventListener(Bindings.DebuggerWorkspaceBinding.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this); targetManager.observeTargets(this, SDK.Target.Capability.JS); } @@ -155,10 +156,6 @@ _uiSourceCodeAdded(event) { var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); this._restoreBreakpoints(uiSourceCode); - if (uiSourceCode.contentType().hasScripts()) { - uiSourceCode.addEventListener( - Workspace.UISourceCode.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this); - } } /** @@ -193,8 +190,6 @@ if (breakpoints[i].enabled()) this._provisionalBreakpoints.set(uiSourceCode.url(), breakpoints[i]); } - uiSourceCode.removeEventListener( - Workspace.UISourceCode.Events.SourceMappingChanged, this._uiSourceCodeMappingChanged, this); this._breakpointsForPrimaryUISourceCode.remove(uiSourceCode); }
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js index b17e718..6aea107d 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js
@@ -62,7 +62,8 @@ this._eventListeners = [ workspace.addEventListener( Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this), - debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this) + debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this), + debuggerModel.addEventListener(SDK.DebuggerModel.Events.SourceMapURLAdded, this._sourceMapURLAdded.bind(this)) ]; } @@ -150,12 +151,8 @@ * @param {!SDK.Script} script */ addScript(script) { - if (!script.sourceMapURL) { - script.addEventListener(SDK.Script.Events.SourceMapURLAdded, this._sourceMapURLAdded.bind(this)); - return; - } - - this._processScript(script); + if (script.sourceMapURL) + this._processScript(script); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js index 1f9c3bca..cecb966 100644 --- a/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js +++ b/third_party/WebKit/Source/devtools/front_end/bindings/DebuggerWorkspaceBinding.js
@@ -5,12 +5,13 @@ * @implements {SDK.TargetManager.Observer} * @unrestricted */ -Bindings.DebuggerWorkspaceBinding = class { +Bindings.DebuggerWorkspaceBinding = class extends Common.Object { /** * @param {!SDK.TargetManager} targetManager * @param {!Workspace.Workspace} workspace */ constructor(targetManager, workspace) { + super(); this._workspace = workspace; // FIXME: Migrate from _targetToData to _debuggerModelToData. @@ -337,6 +338,7 @@ */ constructor(debuggerModel, debuggerWorkspaceBinding) { this._debuggerModel = debuggerModel; + this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; /** @type {!Map.<string, !Bindings.DebuggerWorkspaceBinding.ScriptInfo>} */ this.scriptDataMap = new Map(); @@ -395,7 +397,7 @@ else this._uiSourceCodeToSourceMapping.remove(uiSourceCode); - uiSourceCode.dispatchEventToListeners(Workspace.UISourceCode.Events.SourceMappingChanged, { + this._debuggerWorkspaceBinding.dispatchEventToListeners(Bindings.DebuggerWorkspaceBinding.Events.SourceMappingChanged, { uiSourceCode: uiSourceCode, target: this._debuggerModel.target(), isIdentity: sourceMapping ? sourceMapping.isIdentity() : false @@ -440,6 +442,12 @@ } }; +/** @enum {symbol} */ +Bindings.DebuggerWorkspaceBinding.Events = { + SourceMappingChanged: Symbol('SourceMappingChanged'), +}; + + /** * @unrestricted */
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js index e5802ee..6593e49 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -59,6 +59,9 @@ /** @type {!Map<string, string>} */ this._fileURLToNodeJSPath = new Map(); this.enableDebugger(); + + /** @type {!Map<string, string>} */ + this._stringMap = new Map(); } /** @@ -319,6 +322,7 @@ _reset() { this._scripts = {}; this._scriptsBySourceURL.clear(); + this._stringMap.clear(); } /** @@ -484,10 +488,13 @@ if (this.target().isNodeJS() && sourceURL && sourceURL.startsWith('/')) { var nodeJSPath = sourceURL; sourceURL = Common.ParsedURL.platformPathToURL(nodeJSPath); + sourceURL = this._internString(sourceURL); this._fileURLToNodeJSPath.set(sourceURL, nodeJSPath); + } else { + sourceURL = this._internString(sourceURL); } var script = new SDK.Script( - this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, + this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, this._internString(hash), isContentScript, isLiveEdit, sourceMapURL, hasSourceURL); this._registerScript(script); if (!hasSyntaxError) @@ -791,6 +798,16 @@ this.enableDebugger(fulfill); } } + + /** + * @param {string} string + * @return {string} string + */ + _internString(string) { + if (!this._stringMap.has(string)) + this._stringMap.set(string, string); + return this._stringMap.get(string); + } }; /** @typedef {{location: ?SDK.DebuggerModel.Location, functionName: string}} */ @@ -817,7 +834,8 @@ FailedToParseScriptSource: Symbol('FailedToParseScriptSource'), GlobalObjectCleared: Symbol('GlobalObjectCleared'), CallFrameSelected: Symbol('CallFrameSelected'), - ConsoleCommandEvaluatedInSelectedCallFrame: Symbol('ConsoleCommandEvaluatedInSelectedCallFrame') + ConsoleCommandEvaluatedInSelectedCallFrame: Symbol('ConsoleCommandEvaluatedInSelectedCallFrame'), + SourceMapURLAdded: Symbol('SourceMapURLAdded') }; /** @enum {string} */
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/Script.js b/third_party/WebKit/Source/devtools/front_end/sdk/Script.js index 882aba8d..e71f869 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/Script.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/Script.js
@@ -22,6 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /** * @implements {Common.ContentProvider} * @unrestricted @@ -289,7 +290,7 @@ if (this.sourceMapURL) return; this.sourceMapURL = sourceMapURL; - this.dispatchEventToListeners(SDK.Script.Events.SourceMapURLAdded, this); + this.debuggerModel.dispatchEventToListeners(SDK.DebuggerModel.Events.SourceMapURLAdded, this); } /** @@ -332,10 +333,4 @@ } }; -/** @enum {symbol} */ -SDK.Script.Events = { - ScriptEdited: Symbol('ScriptEdited'), - SourceMapURLAdded: Symbol('SourceMapURLAdded') -}; - SDK.Script.sourceURLRegex = /^[\040\t]*\/\/[@#] sourceURL=\s*(\S*?)\s*$/m;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js index cadf734..817a396 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -80,6 +80,8 @@ /** @type {!Map.<number, !Element>} */ this._valueWidgets = new Map(); this.onBindingChanged(); + Bindings.debuggerWorkspaceBinding.addEventListener( + Bindings.DebuggerWorkspaceBinding.Events.SourceMappingChanged, this._onSourceMappingChanged, this); } /** @@ -1031,22 +1033,17 @@ } _updateDebuggerSourceCode() { - if (this._debuggerSourceCode) { - this._debuggerSourceCode.removeEventListener( - Workspace.UISourceCode.Events.SourceMappingChanged, this._onSourceMappingChanged, this); - } - var binding = Persistence.persistence.binding(this.uiSourceCode()); this._debuggerSourceCode = binding ? binding.network : this.uiSourceCode(); - this._debuggerSourceCode.addEventListener( - Workspace.UISourceCode.Events.SourceMappingChanged, this._onSourceMappingChanged, this); } /** * @param {!Common.Event} event */ _onSourceMappingChanged(event) { - var data = /** @type {{target: !SDK.Target}} */ (event.data); + var data = /** @type {{target: !SDK.Target, uiSourceCode: !Workspace.UISourceCode}} */ (event.data); + if (this._debuggerSourceCode !== data.uiSourceCode) + return; this._updateScriptFile(data.target); this._updateLinesWithoutMappingHighlight(); } @@ -1296,6 +1293,8 @@ * @override */ dispose() { + Bindings.debuggerWorkspaceBinding.removeEventListener( + Bindings.DebuggerWorkspaceBinding.Events.SourceMappingChanged, this._onSourceMappingChanged, this); this._breakpointManager.removeEventListener( Bindings.BreakpointManager.Events.BreakpointAdded, this._breakpointAdded, this); this._breakpointManager.removeEventListener( @@ -1306,10 +1305,6 @@ Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this); this.uiSourceCode().removeEventListener( Workspace.UISourceCode.Events.TitleChanged, this._showBlackboxInfobarIfNeeded, this); - if (this._debuggerSourceCode) { - this._debuggerSourceCode.removeEventListener( - Workspace.UISourceCode.Events.SourceMappingChanged, this._onSourceMappingChanged, this); - } Common.moduleSetting('skipStackFramesPattern').removeChangeListener(this._showBlackboxInfobarIfNeeded, this); Common.moduleSetting('skipContentScripts').removeChangeListener(this._showBlackboxInfobarIfNeeded, this);
diff --git a/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js b/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js index eb206eec..d92525dc 100644 --- a/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js +++ b/third_party/WebKit/Source/devtools/front_end/workspace/UISourceCode.js
@@ -620,7 +620,6 @@ WorkingCopyChanged: Symbol('WorkingCopyChanged'), WorkingCopyCommitted: Symbol('WorkingCopyCommitted'), TitleChanged: Symbol('TitleChanged'), - SourceMappingChanged: Symbol('SourceMappingChanged'), MessageAdded: Symbol('MessageAdded'), MessageRemoved: Symbol('MessageRemoved'), LineDecorationAdded: Symbol('LineDecorationAdded'),
diff --git a/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h index aec961f..cebd0ea 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/EffectPaintPropertyNode.h
@@ -35,18 +35,22 @@ PassRefPtr<const ClipPaintPropertyNode> outputClip, CompositorFilterOperations filter, float opacity, - SkBlendMode blendMode) { + SkBlendMode blendMode, + CompositingReasons directCompositingReasons = CompositingReasonNone) { return adoptRef(new EffectPaintPropertyNode( std::move(parent), std::move(localTransformSpace), - std::move(outputClip), std::move(filter), opacity, blendMode)); + std::move(outputClip), std::move(filter), opacity, blendMode, + directCompositingReasons)); } - void update(PassRefPtr<const EffectPaintPropertyNode> parent, - PassRefPtr<const TransformPaintPropertyNode> localTransformSpace, - PassRefPtr<const ClipPaintPropertyNode> outputClip, - CompositorFilterOperations filter, - float opacity, - SkBlendMode blendMode) { + void update( + PassRefPtr<const EffectPaintPropertyNode> parent, + PassRefPtr<const TransformPaintPropertyNode> localTransformSpace, + PassRefPtr<const ClipPaintPropertyNode> outputClip, + CompositorFilterOperations filter, + float opacity, + SkBlendMode blendMode, + CompositingReasons directCompositingReasons = CompositingReasonNone) { DCHECK(!isRoot()); DCHECK(parent != this); m_parent = parent; @@ -55,6 +59,7 @@ m_filter = std::move(filter); m_opacity = opacity; m_blendMode = blendMode; + m_directCompositingReasons = directCompositingReasons; } const TransformPaintPropertyNode* localTransformSpace() const { @@ -76,9 +81,9 @@ // The clone function is used by FindPropertiesNeedingUpdate.h for recording // an effect node before it has been updated, to later detect changes. PassRefPtr<EffectPaintPropertyNode> clone() const { - return adoptRef(new EffectPaintPropertyNode(m_parent, m_localTransformSpace, - m_outputClip, m_filter, - m_opacity, m_blendMode)); + return adoptRef(new EffectPaintPropertyNode( + m_parent, m_localTransformSpace, m_outputClip, m_filter, m_opacity, + m_blendMode, m_directCompositingReasons)); } // The equality operator is used by FindPropertiesNeedingUpdate.h for checking @@ -95,6 +100,10 @@ String toString() const; + bool hasDirectCompositingReasons() const { + return m_directCompositingReasons != CompositingReasonNone; + } + private: EffectPaintPropertyNode( PassRefPtr<const EffectPaintPropertyNode> parent, @@ -102,13 +111,15 @@ PassRefPtr<const ClipPaintPropertyNode> outputClip, CompositorFilterOperations filter, float opacity, - SkBlendMode blendMode) + SkBlendMode blendMode, + CompositingReasons directCompositingReasons) : m_parent(parent), m_localTransformSpace(localTransformSpace), m_outputClip(outputClip), m_filter(std::move(filter)), m_opacity(opacity), - m_blendMode(blendMode) {} + m_blendMode(blendMode), + m_directCompositingReasons(directCompositingReasons) {} RefPtr<const EffectPaintPropertyNode> m_parent; // The local transform space serves two purposes: @@ -135,6 +146,8 @@ // be removed in favor of a stable ID once cc::LayerImpl no longer owns // RenderSurfaceImpl. mutable scoped_refptr<cc::Layer> m_dummyLayer; + + CompositingReasons m_directCompositingReasons; }; // Redeclared here to avoid ODR issues.
diff --git a/third_party/WebKit/Source/web/ContextMenuClientImpl.cpp b/third_party/WebKit/Source/web/ContextMenuClientImpl.cpp index ebc21fa..71adf55 100644 --- a/third_party/WebKit/Source/web/ContextMenuClientImpl.cpp +++ b/third_party/WebKit/Source/web/ContextMenuClientImpl.cpp
@@ -329,7 +329,7 @@ data.dictionarySuggestions = suggestions; } else if (m_webView->spellCheckClient()) { int misspelledOffset, misspelledLength; - m_webView->spellCheckClient()->spellCheck( + m_webView->spellCheckClient()->checkSpelling( data.misspelledWord, misspelledOffset, misspelledLength, &data.dictionarySuggestions); }
diff --git a/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp b/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp index 22d7e27..25a18d4c 100644 --- a/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp +++ b/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp
@@ -119,8 +119,8 @@ // Check to see if the provided text is spelled correctly. if (m_webView->spellCheckClient()) { - m_webView->spellCheckClient()->spellCheck(text, spellLocation, spellLength, - nullptr); + m_webView->spellCheckClient()->checkSpelling(text, spellLocation, + spellLength, nullptr); } else { spellLocation = 0; spellLength = 0;
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit.py index f87cb43c..065c4c4 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit.py
@@ -4,6 +4,9 @@ from webkitpy.common.memoized import memoized from webkitpy.common.webkit_finder import WebKitFinder +from webkitpy.w3c.deps_updater import DepsUpdater + +CHROMIUM_WPT_DIR = 'third_party/WebKit/LayoutTests/imported/wpt/' class ChromiumCommit(object): @@ -61,16 +64,37 @@ 'git', 'show', '--format=%B', '--no-patch', self.sha ]) + def filtered_changed_files(self): + """Makes a patch with just changes in files in the WPT dir for a given commit.""" + changed_files = self.host.executive.run_command([ + 'git', 'diff-tree', '--name-only', '--no-commit-id', '-r', self.sha, + '--', self.absolute_chromium_wpt_dir() + ]).splitlines() + + blacklist = [ + 'MANIFEST.json', + self.host.filesystem.join('resources', 'testharnessreport.js'), + ] + qualified_blacklist = [CHROMIUM_WPT_DIR + f for f in blacklist] + return [f for f in changed_files if f not in qualified_blacklist and not DepsUpdater.is_baseline(f)] + def format_patch(self): - """Makes a patch with just changes in files in the WPT for a given commit.""" - # TODO(jeffcarp): exclude expectations files - # TODO(jeffcarp): exclude manifest files + """Makes a patch with only exportable changes.""" + filtered_files = self.filtered_changed_files() + + if not filtered_files: + return '' + return self.host.executive.run_command([ - 'git', 'format-patch', '-1', '--stdout', - self.sha, self.absolute_chromium_wpt_dir() - ]) + 'git', 'format-patch', '-1', '--stdout', self.sha, '--' + ] + filtered_files, cwd=self.absolute_chromium_dir()) @memoized def absolute_chromium_wpt_dir(self): finder = WebKitFinder(self.host.filesystem) return finder.path_from_webkit_base('LayoutTests', 'imported', 'wpt') + + @memoized + def absolute_chromium_dir(self): + finder = WebKitFinder(self.host.filesystem) + return finder.chromium_base()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit_unittest.py index 20fd78e..2304b452 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit_unittest.py
@@ -6,6 +6,8 @@ from webkitpy.common.host_mock import MockHost from webkitpy.common.system.executive_mock import MockExecutive2 from webkitpy.w3c.chromium_commit import ChromiumCommit +from webkitpy.w3c.test_exporter import CHROMIUM_WPT_DIR +from webkitpy.w3c.test_exporter_unittest import mock_command_exec class ChromiumCommitTest(unittest.TestCase): @@ -24,3 +26,24 @@ self.assertEqual(chromium_commit.position, 'refs/heads/master@{#789}') self.assertEqual(chromium_commit.sha, 'deadbeefcafe') + + def test_filtered_changed_files_blacklist(self): + host = MockHost() + + fake_files = ['file1', 'MANIFEST.json', 'file3'] + qualified_fake_files = [CHROMIUM_WPT_DIR + f for f in fake_files] + + host.executive = mock_command_exec({ + 'diff-tree': '\n'.join(qualified_fake_files), + 'crrev-parse': 'fake rev', + }) + + position_footer = 'Cr-Commit-Position: refs/heads/master@{#789}' + chromium_commit = ChromiumCommit(host, position=position_footer) + + files = chromium_commit.filtered_changed_files() + + expected_files = ['file1', 'file3'] + qualified_expected_files = [CHROMIUM_WPT_DIR + f for f in expected_files] + + self.assertEqual(files, qualified_expected_files)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_exporter_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_exporter_unittest.py index 16ef1b9..9d5640d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_exporter_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_exporter_unittest.py
@@ -18,7 +18,6 @@ return MockExecutive2(run_command_fn=run_fn) - class TestExporterTest(unittest.TestCase): def setUp(self):
diff --git a/third_party/WebKit/public/web/WebSpellCheckClient.h b/third_party/WebKit/public/web/WebSpellCheckClient.h index d0945d8..aa60af6 100644 --- a/third_party/WebKit/public/web/WebSpellCheckClient.h +++ b/third_party/WebKit/public/web/WebSpellCheckClient.h
@@ -47,10 +47,10 @@ // will indicates its length. Otherwise, if there was not a spelling // error, then upon return misspelledLength is 0. If optional_suggestions // is given, then it will be filled with suggested words (not a cheap step). - virtual void spellCheck(const WebString& text, - int& misspelledOffset, - int& misspelledLength, - WebVector<WebString>* optionalSuggestions) {} + virtual void checkSpelling(const WebString& text, + int& misspelledOffset, + int& misspelledLength, + WebVector<WebString>* optionalSuggestions) {} // Requests asynchronous spelling and grammar checking, whose result should be // returned by passed completion object.
diff --git a/third_party/closure_linter/AUTHORS b/third_party/closure_linter/AUTHORS deleted file mode 100644 index 2f72bd6..0000000 --- a/third_party/closure_linter/AUTHORS +++ /dev/null
@@ -1,6 +0,0 @@ -# This is a list of contributors to the Closure Linter. - -# Names should be added to this file like so: -# Name or Organization <email address> - -Google Inc.
diff --git a/third_party/closure_linter/LICENSE b/third_party/closure_linter/LICENSE deleted file mode 100644 index d9a10c0..0000000 --- a/third_party/closure_linter/LICENSE +++ /dev/null
@@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS
diff --git a/third_party/closure_linter/OWNERS b/third_party/closure_linter/OWNERS deleted file mode 100644 index 7eae7d6c..0000000 --- a/third_party/closure_linter/OWNERS +++ /dev/null
@@ -1,3 +0,0 @@ -dbeam@chromium.org -fukino@chromium.org -tbreisacher@chromium.org
diff --git a/third_party/closure_linter/README b/third_party/closure_linter/README deleted file mode 100644 index 3755ae8..0000000 --- a/third_party/closure_linter/README +++ /dev/null
@@ -1,9 +0,0 @@ -This repository contains the Closure Linter - a style checker for JavaScript. - -To install the application, run - python ./setup.py install - -After installing, you get two helper applications installed into /usr/local/bin: - - gjslint - runs the linter and checks for errors - fixjsstyle - tries to fix errors automatically
diff --git a/third_party/closure_linter/README.chromium b/third_party/closure_linter/README.chromium deleted file mode 100644 index cf0d6e86..0000000 --- a/third_party/closure_linter/README.chromium +++ /dev/null
@@ -1,16 +0,0 @@ -Name: closure-linter -URL: http://code.google.com/p/closure-linter/ -Version: 2.3.14 -Date: 12 Jun 2014 -Revision: 16 -License: Apache 2.0 -License File: NOT_SHIPPED -Security Critical: no - -Description: - The Closure Linter enforces the guidelines set by the Google JavaScript Style - Guide. The linter handles style issues so that you can focus on the code. - -Local modifications: - Removed closure_linter/testdata/ - Added OWNERS file
diff --git a/third_party/closure_linter/closure_linter/__init__.py b/third_party/closure_linter/closure_linter/__init__.py deleted file mode 100755 index 1798c8c..0000000 --- a/third_party/closure_linter/closure_linter/__init__.py +++ /dev/null
@@ -1,16 +0,0 @@ -#!/usr/bin/env python -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Package indicator for gjslint."""
diff --git a/third_party/closure_linter/closure_linter/aliaspass.py b/third_party/closure_linter/closure_linter/aliaspass.py deleted file mode 100644 index bb37bfa..0000000 --- a/third_party/closure_linter/closure_linter/aliaspass.py +++ /dev/null
@@ -1,248 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Pass that scans for goog.scope aliases and lint/usage errors.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = ('nnaze@google.com (Nathan Naze)') - -from closure_linter import ecmametadatapass -from closure_linter import errors -from closure_linter import javascripttokens -from closure_linter import scopeutil -from closure_linter import tokenutil -from closure_linter.common import error - - -# TODO(nnaze): Create a Pass interface and move this class, EcmaMetaDataPass, -# and related classes onto it. - - -def _GetAliasForIdentifier(identifier, alias_map): - """Returns the aliased_symbol name for an identifier. - - Example usage: - >>> alias_map = {'MyClass': 'goog.foo.MyClass'} - >>> _GetAliasForIdentifier('MyClass.prototype.action', alias_map) - 'goog.foo.MyClass.prototype.action' - - >>> _GetAliasForIdentifier('MyClass.prototype.action', {}) - None - - Args: - identifier: The identifier. - alias_map: A dictionary mapping a symbol to an alias. - - Returns: - The aliased symbol name or None if not found. - """ - ns = identifier.split('.', 1)[0] - aliased_symbol = alias_map.get(ns) - if aliased_symbol: - return aliased_symbol + identifier[len(ns):] - - -def _SetTypeAlias(js_type, alias_map): - """Updates the alias for identifiers in a type. - - Args: - js_type: A typeannotation.TypeAnnotation instance. - alias_map: A dictionary mapping a symbol to an alias. - """ - aliased_symbol = _GetAliasForIdentifier(js_type.identifier, alias_map) - if aliased_symbol: - js_type.alias = aliased_symbol - for sub_type in js_type.IterTypes(): - _SetTypeAlias(sub_type, alias_map) - - -class AliasPass(object): - """Pass to identify goog.scope() usages. - - Identifies goog.scope() usages and finds lint/usage errors. Notes any - aliases of symbols in Closurized namespaces (that is, reassignments - such as "var MyClass = goog.foo.MyClass;") and annotates identifiers - when they're using an alias (so they may be expanded to the full symbol - later -- that "MyClass.prototype.action" refers to - "goog.foo.MyClass.prototype.action" when expanded.). - """ - - def __init__(self, closurized_namespaces=None, error_handler=None): - """Creates a new pass. - - Args: - closurized_namespaces: A set of Closurized namespaces (e.g. 'goog'). - error_handler: An error handler to report lint errors to. - """ - - self._error_handler = error_handler - - # If we have namespaces, freeze the set. - if closurized_namespaces: - closurized_namespaces = frozenset(closurized_namespaces) - - self._closurized_namespaces = closurized_namespaces - - def Process(self, start_token): - """Runs the pass on a token stream. - - Args: - start_token: The first token in the stream. - """ - - if start_token is None: - return - - # TODO(nnaze): Add more goog.scope usage checks. - self._CheckGoogScopeCalls(start_token) - - # If we have closurized namespaces, identify aliased identifiers. - if self._closurized_namespaces: - context = start_token.metadata.context - root_context = context.GetRoot() - self._ProcessRootContext(root_context) - - def _CheckGoogScopeCalls(self, start_token): - """Check goog.scope calls for lint/usage errors.""" - - def IsScopeToken(token): - return (token.type is javascripttokens.JavaScriptTokenType.IDENTIFIER and - token.string == 'goog.scope') - - # Find all the goog.scope tokens in the file - scope_tokens = [t for t in start_token if IsScopeToken(t)] - - for token in scope_tokens: - scope_context = token.metadata.context - - if not (scope_context.type == ecmametadatapass.EcmaContext.STATEMENT and - scope_context.parent.type == ecmametadatapass.EcmaContext.ROOT): - self._MaybeReportError( - error.Error(errors.INVALID_USE_OF_GOOG_SCOPE, - 'goog.scope call not in global scope', token)) - - # There should be only one goog.scope reference. Register errors for - # every instance after the first. - for token in scope_tokens[1:]: - self._MaybeReportError( - error.Error(errors.EXTRA_GOOG_SCOPE_USAGE, - 'More than one goog.scope call in file.', token)) - - def _MaybeReportError(self, err): - """Report an error to the handler (if registered).""" - if self._error_handler: - self._error_handler.HandleError(err) - - @classmethod - def _YieldAllContexts(cls, context): - """Yields all contexts that are contained by the given context.""" - yield context - for child_context in context.children: - for descendent_child in cls._YieldAllContexts(child_context): - yield descendent_child - - @staticmethod - def _IsTokenInParentBlock(token, parent_block): - """Determines whether the given token is contained by the given block. - - Args: - token: A token - parent_block: An EcmaContext. - - Returns: - Whether the token is in a context that is or is a child of the given - parent_block context. - """ - context = token.metadata.context - - while context: - if context is parent_block: - return True - context = context.parent - - return False - - def _ProcessRootContext(self, root_context): - """Processes all goog.scope blocks under the root context.""" - - assert root_context.type is ecmametadatapass.EcmaContext.ROOT - - # Process aliases in statements in the root scope for goog.module-style - # aliases. - global_alias_map = {} - for context in root_context.children: - if context.type == ecmametadatapass.EcmaContext.STATEMENT: - for statement_child in context.children: - if statement_child.type == ecmametadatapass.EcmaContext.VAR: - match = scopeutil.MatchModuleAlias(statement_child) - if match: - # goog.require aliases cannot use further aliases, the symbol is - # the second part of match, directly. - symbol = match[1] - if scopeutil.IsInClosurizedNamespace(symbol, - self._closurized_namespaces): - global_alias_map[match[0]] = symbol - - # Process each block to find aliases. - for context in root_context.children: - self._ProcessBlock(context, global_alias_map) - - def _ProcessBlock(self, context, global_alias_map): - """Scans a goog.scope block to find aliases and mark alias tokens.""" - alias_map = global_alias_map.copy() - - # Iterate over every token in the context. Each token points to one - # context, but multiple tokens may point to the same context. We only want - # to check each context once, so keep track of those we've seen. - seen_contexts = set() - token = context.start_token - while token and self._IsTokenInParentBlock(token, context): - token_context = token.metadata.context if token.metadata else None - - # Check to see if this token is an alias. - if token_context and token_context not in seen_contexts: - seen_contexts.add(token_context) - - # If this is a alias statement in the goog.scope block. - if (token_context.type == ecmametadatapass.EcmaContext.VAR and - scopeutil.IsGoogScopeBlock(token_context.parent.parent)): - match = scopeutil.MatchAlias(token_context) - - # If this is an alias, remember it in the map. - if match: - alias, symbol = match - symbol = _GetAliasForIdentifier(symbol, alias_map) or symbol - if scopeutil.IsInClosurizedNamespace(symbol, - self._closurized_namespaces): - alias_map[alias] = symbol - - # If this token is an identifier that matches an alias, - # mark the token as an alias to the original symbol. - if (token.type is javascripttokens.JavaScriptTokenType.SIMPLE_LVALUE or - token.type is javascripttokens.JavaScriptTokenType.IDENTIFIER): - identifier = tokenutil.GetIdentifierForToken(token) - if identifier: - aliased_symbol = _GetAliasForIdentifier(identifier, alias_map) - if aliased_symbol: - token.metadata.aliased_symbol = aliased_symbol - - elif token.type == javascripttokens.JavaScriptTokenType.DOC_FLAG: - flag = token.attached_object - if flag and flag.HasType() and flag.jstype: - _SetTypeAlias(flag.jstype, alias_map) - - token = token.next # Get next token
diff --git a/third_party/closure_linter/closure_linter/aliaspass_test.py b/third_party/closure_linter/closure_linter/aliaspass_test.py deleted file mode 100644 index 7042e53..0000000 --- a/third_party/closure_linter/closure_linter/aliaspass_test.py +++ /dev/null
@@ -1,191 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Unit tests for the aliaspass module.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = ('nnaze@google.com (Nathan Naze)') - -import unittest as googletest - -from closure_linter import aliaspass -from closure_linter import errors -from closure_linter import javascriptstatetracker -from closure_linter import testutil -from closure_linter.common import erroraccumulator - - -def _GetTokenByLineAndString(start_token, string, line_number): - for token in start_token: - if token.line_number == line_number and token.string == string: - return token - - -class AliasPassTest(googletest.TestCase): - - def testInvalidGoogScopeCall(self): - start_token = testutil.TokenizeSourceAndRunEcmaPass(_TEST_SCOPE_SCRIPT) - - error_accumulator = erroraccumulator.ErrorAccumulator() - alias_pass = aliaspass.AliasPass( - error_handler=error_accumulator) - alias_pass.Process(start_token) - - alias_errors = error_accumulator.GetErrors() - self.assertEquals(1, len(alias_errors)) - - alias_error = alias_errors[0] - - self.assertEquals(errors.INVALID_USE_OF_GOOG_SCOPE, alias_error.code) - self.assertEquals('goog.scope', alias_error.token.string) - - def testAliasedIdentifiers(self): - start_token = testutil.TokenizeSourceAndRunEcmaPass(_TEST_ALIAS_SCRIPT) - alias_pass = aliaspass.AliasPass(set(['goog', 'myproject'])) - alias_pass.Process(start_token) - - alias_token = _GetTokenByLineAndString(start_token, 'Event', 4) - self.assertTrue(alias_token.metadata.is_alias_definition) - - my_class_token = _GetTokenByLineAndString(start_token, 'myClass', 9) - self.assertIsNone(my_class_token.metadata.aliased_symbol) - - component_token = _GetTokenByLineAndString(start_token, 'Component', 17) - self.assertEquals('goog.ui.Component', - component_token.metadata.aliased_symbol) - - event_token = _GetTokenByLineAndString(start_token, 'Event.Something', 17) - self.assertEquals('goog.events.Event.Something', - event_token.metadata.aliased_symbol) - - non_closurized_token = _GetTokenByLineAndString( - start_token, 'NonClosurizedClass', 18) - self.assertIsNone(non_closurized_token.metadata.aliased_symbol) - - long_start_token = _GetTokenByLineAndString(start_token, 'Event', 24) - self.assertEquals('goog.events.Event.MultilineIdentifier.someMethod', - long_start_token.metadata.aliased_symbol) - - def testAliasedDoctypes(self): - """Tests that aliases are correctly expanded within type annotations.""" - start_token = testutil.TokenizeSourceAndRunEcmaPass(_TEST_ALIAS_SCRIPT) - tracker = javascriptstatetracker.JavaScriptStateTracker() - tracker.DocFlagPass(start_token, error_handler=None) - - alias_pass = aliaspass.AliasPass(set(['goog', 'myproject'])) - alias_pass.Process(start_token) - - flag_token = _GetTokenByLineAndString(start_token, '@type', 22) - self.assertEquals( - 'goog.events.Event.<goog.ui.Component,Array<myproject.foo.MyClass>>', - repr(flag_token.attached_object.jstype)) - - def testModuleAlias(self): - start_token = testutil.TokenizeSourceAndRunEcmaPass(""" -goog.module('goog.test'); -var Alias = goog.require('goog.Alias'); -Alias.use(); -""") - alias_pass = aliaspass.AliasPass(set(['goog'])) - alias_pass.Process(start_token) - alias_token = _GetTokenByLineAndString(start_token, 'Alias', 3) - self.assertTrue(alias_token.metadata.is_alias_definition) - - def testMultipleGoogScopeCalls(self): - start_token = testutil.TokenizeSourceAndRunEcmaPass( - _TEST_MULTIPLE_SCOPE_SCRIPT) - - error_accumulator = erroraccumulator.ErrorAccumulator() - - alias_pass = aliaspass.AliasPass( - set(['goog', 'myproject']), - error_handler=error_accumulator) - alias_pass.Process(start_token) - - alias_errors = error_accumulator.GetErrors() - - self.assertEquals(3, len(alias_errors)) - - error = alias_errors[0] - self.assertEquals(errors.INVALID_USE_OF_GOOG_SCOPE, error.code) - self.assertEquals(7, error.token.line_number) - - error = alias_errors[1] - self.assertEquals(errors.EXTRA_GOOG_SCOPE_USAGE, error.code) - self.assertEquals(7, error.token.line_number) - - error = alias_errors[2] - self.assertEquals(errors.EXTRA_GOOG_SCOPE_USAGE, error.code) - self.assertEquals(11, error.token.line_number) - - -_TEST_ALIAS_SCRIPT = """ -goog.scope(function() { -var events = goog.events; // scope alias -var Event = events. - Event; // nested multiline scope alias - -// This should not be registered as an aliased identifier because -// it appears before the alias. -var myClass = new MyClass(); - -var Component = goog.ui.Component; // scope alias -var MyClass = myproject.foo.MyClass; // scope alias - -// Scope alias of non-Closurized namespace. -var NonClosurizedClass = aaa.bbb.NonClosurizedClass; - -var component = new Component(Event.Something); -var nonClosurized = NonClosurizedClass(); - -/** - * A created namespace with a really long identifier. - * @type {events.Event.<Component,Array<MyClass>} - */ -Event. - MultilineIdentifier. - someMethod = function() {}; -}); -""" - -_TEST_SCOPE_SCRIPT = """ -function foo () { - // This goog.scope call is invalid. - goog.scope(function() { - - }); -} -""" - -_TEST_MULTIPLE_SCOPE_SCRIPT = """ -goog.scope(function() { - // do nothing -}); - -function foo() { - var test = goog.scope; // We should not see goog.scope mentioned. -} - -// This goog.scope invalid. There can be only one. -goog.scope(function() { - -}); -""" - - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/checker.py b/third_party/closure_linter/closure_linter/checker.py deleted file mode 100755 index 1c98417..0000000 --- a/third_party/closure_linter/closure_linter/checker.py +++ /dev/null
@@ -1,108 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Core methods for checking JS files for common style guide violations.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -import gflags as flags - -from closure_linter import aliaspass -from closure_linter import checkerbase -from closure_linter import closurizednamespacesinfo -from closure_linter import javascriptlintrules - - -flags.DEFINE_list('closurized_namespaces', '', - 'Namespace prefixes, used for testing of' - 'goog.provide/require') -flags.DEFINE_list('ignored_extra_namespaces', '', - 'Fully qualified namespaces that should be not be reported ' - 'as extra by the linter.') - - -class JavaScriptStyleChecker(checkerbase.CheckerBase): - """Checker that applies JavaScriptLintRules.""" - - def __init__(self, state_tracker, error_handler): - """Initialize an JavaScriptStyleChecker object. - - Args: - state_tracker: State tracker. - error_handler: Error handler to pass all errors to. - """ - self._namespaces_info = None - self._alias_pass = None - if flags.FLAGS.closurized_namespaces: - self._namespaces_info = ( - closurizednamespacesinfo.ClosurizedNamespacesInfo( - flags.FLAGS.closurized_namespaces, - flags.FLAGS.ignored_extra_namespaces)) - - self._alias_pass = aliaspass.AliasPass( - flags.FLAGS.closurized_namespaces, error_handler) - - checkerbase.CheckerBase.__init__( - self, - error_handler=error_handler, - lint_rules=javascriptlintrules.JavaScriptLintRules( - self._namespaces_info), - state_tracker=state_tracker) - - def Check(self, start_token, limited_doc_checks=False, is_html=False, - stop_token=None): - """Checks a token stream for lint warnings/errors. - - Adds a separate pass for computing dependency information based on - goog.require and goog.provide statements prior to the main linting pass. - - Args: - start_token: The first token in the token stream. - limited_doc_checks: Whether to perform limited checks. - is_html: Whether this token stream is HTML. - stop_token: If given, checks should stop at this token. - """ - self._lint_rules.Initialize(self, limited_doc_checks, is_html) - - self._state_tracker.DocFlagPass(start_token, self._error_handler) - - if self._alias_pass: - self._alias_pass.Process(start_token) - - # To maximize the amount of errors that get reported before a parse error - # is displayed, don't run the dependency pass if a parse error exists. - if self._namespaces_info: - self._namespaces_info.Reset() - self._ExecutePass(start_token, self._DependencyPass, stop_token) - - self._ExecutePass(start_token, self._LintPass, stop_token) - - # If we have a stop_token, we didn't end up reading the whole file and, - # thus, don't call Finalize to do end-of-file checks. - if not stop_token: - self._lint_rules.Finalize(self._state_tracker) - - def _DependencyPass(self, token): - """Processes an individual token for dependency information. - - Used to encapsulate the logic needed to process an individual token so that - it can be passed to _ExecutePass. - - Args: - token: The token to process. - """ - self._namespaces_info.ProcessToken(token, self._state_tracker)
diff --git a/third_party/closure_linter/closure_linter/checkerbase.py b/third_party/closure_linter/closure_linter/checkerbase.py deleted file mode 100755 index 6679ded..0000000 --- a/third_party/closure_linter/closure_linter/checkerbase.py +++ /dev/null
@@ -1,192 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Base classes for writing checkers that operate on tokens.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)', - 'jacobr@google.com (Jacob Richman)') - -from closure_linter import errorrules -from closure_linter.common import error - - -class LintRulesBase(object): - """Base class for all classes defining the lint rules for a language.""" - - def __init__(self): - self.__checker = None - - def Initialize(self, checker, limited_doc_checks, is_html): - """Initializes to prepare to check a file. - - Args: - checker: Class to report errors to. - limited_doc_checks: Whether doc checking is relaxed for this file. - is_html: Whether the file is an HTML file with extracted contents. - """ - self.__checker = checker - self._limited_doc_checks = limited_doc_checks - self._is_html = is_html - - def _HandleError(self, code, message, token, position=None, - fix_data=None): - """Call the HandleError function for the checker we are associated with.""" - if errorrules.ShouldReportError(code): - self.__checker.HandleError(code, message, token, position, fix_data) - - def _SetLimitedDocChecks(self, limited_doc_checks): - """Sets whether doc checking is relaxed for this file. - - Args: - limited_doc_checks: Whether doc checking is relaxed for this file. - """ - self._limited_doc_checks = limited_doc_checks - - def CheckToken(self, token, parser_state): - """Checks a token, given the current parser_state, for warnings and errors. - - Args: - token: The current token under consideration. - parser_state: Object that indicates the parser state in the page. - - Raises: - TypeError: If not overridden. - """ - raise TypeError('Abstract method CheckToken not implemented') - - def Finalize(self, parser_state): - """Perform all checks that need to occur after all lines are processed. - - Args: - parser_state: State of the parser after parsing all tokens - - Raises: - TypeError: If not overridden. - """ - raise TypeError('Abstract method Finalize not implemented') - - -class CheckerBase(object): - """This class handles checking a LintRules object against a file.""" - - def __init__(self, error_handler, lint_rules, state_tracker): - """Initialize a checker object. - - Args: - error_handler: Object that handles errors. - lint_rules: LintRules object defining lint errors given a token - and state_tracker object. - state_tracker: Object that tracks the current state in the token stream. - - """ - self._error_handler = error_handler - self._lint_rules = lint_rules - self._state_tracker = state_tracker - - self._has_errors = False - - def HandleError(self, code, message, token, position=None, - fix_data=None): - """Prints out the given error message including a line number. - - Args: - code: The error code. - message: The error to print. - token: The token where the error occurred, or None if it was a file-wide - issue. - position: The position of the error, defaults to None. - fix_data: Metadata used for fixing the error. - """ - self._has_errors = True - self._error_handler.HandleError( - error.Error(code, message, token, position, fix_data)) - - def HasErrors(self): - """Returns true if the style checker has found any errors. - - Returns: - True if the style checker has found any errors. - """ - return self._has_errors - - def Check(self, start_token, limited_doc_checks=False, is_html=False, - stop_token=None): - """Checks a token stream, reporting errors to the error reporter. - - Args: - start_token: First token in token stream. - limited_doc_checks: Whether doc checking is relaxed for this file. - is_html: Whether the file being checked is an HTML file with extracted - contents. - stop_token: If given, check should stop at this token. - """ - - self._lint_rules.Initialize(self, limited_doc_checks, is_html) - self._ExecutePass(start_token, self._LintPass, stop_token=stop_token) - self._lint_rules.Finalize(self._state_tracker) - - def _LintPass(self, token): - """Checks an individual token for lint warnings/errors. - - Used to encapsulate the logic needed to check an individual token so that it - can be passed to _ExecutePass. - - Args: - token: The token to check. - """ - self._lint_rules.CheckToken(token, self._state_tracker) - - def _ExecutePass(self, token, pass_function, stop_token=None): - """Calls the given function for every token in the given token stream. - - As each token is passed to the given function, state is kept up to date and, - depending on the error_trace flag, errors are either caught and reported, or - allowed to bubble up so developers can see the full stack trace. If a parse - error is specified, the pass will proceed as normal until the token causing - the parse error is reached. - - Args: - token: The first token in the token stream. - pass_function: The function to call for each token in the token stream. - stop_token: The last token to check (if given). - - Raises: - Exception: If any error occurred while calling the given function. - """ - - self._state_tracker.Reset() - while token: - # When we are looking at a token and decided to delete the whole line, we - # will delete all of them in the "HandleToken()" below. So the current - # token and subsequent ones may already be deleted here. The way we - # delete a token does not wipe out the previous and next pointers of the - # deleted token. So we need to check the token itself to make sure it is - # not deleted. - if not token.is_deleted: - # End the pass at the stop token - if stop_token and token is stop_token: - return - - self._state_tracker.HandleToken( - token, self._state_tracker.GetLastNonSpaceToken()) - pass_function(token) - self._state_tracker.HandleAfterToken(token) - - token = token.next
diff --git a/third_party/closure_linter/closure_linter/closurizednamespacesinfo.py b/third_party/closure_linter/closure_linter/closurizednamespacesinfo.py deleted file mode 100755 index 18b5a2a..0000000 --- a/third_party/closure_linter/closure_linter/closurizednamespacesinfo.py +++ /dev/null
@@ -1,586 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Logic for computing dependency information for closurized JavaScript files. - -Closurized JavaScript files express dependencies using goog.require and -goog.provide statements. In order for the linter to detect when a statement is -missing or unnecessary, all identifiers in the JavaScript file must first be -processed to determine if they constitute the creation or usage of a dependency. -""" - - - -import re - -from closure_linter import javascripttokens -from closure_linter import tokenutil - -# pylint: disable=g-bad-name -TokenType = javascripttokens.JavaScriptTokenType - -DEFAULT_EXTRA_NAMESPACES = [ - 'goog.testing.asserts', - 'goog.testing.jsunit', -] - - -class UsedNamespace(object): - """A type for information about a used namespace.""" - - def __init__(self, namespace, identifier, token, alias_definition): - """Initializes the instance. - - Args: - namespace: the namespace of an identifier used in the file - identifier: the complete identifier - token: the token that uses the namespace - alias_definition: a boolean stating whether the namespace is only to used - for an alias definition and should not be required. - """ - self.namespace = namespace - self.identifier = identifier - self.token = token - self.alias_definition = alias_definition - - def GetLine(self): - return self.token.line_number - - def __repr__(self): - return 'UsedNamespace(%s)' % ', '.join( - ['%s=%s' % (k, repr(v)) for k, v in self.__dict__.iteritems()]) - - -class ClosurizedNamespacesInfo(object): - """Dependency information for closurized JavaScript files. - - Processes token streams for dependency creation or usage and provides logic - for determining if a given require or provide statement is unnecessary or if - there are missing require or provide statements. - """ - - def __init__(self, closurized_namespaces, ignored_extra_namespaces): - """Initializes an instance the ClosurizedNamespacesInfo class. - - Args: - closurized_namespaces: A list of namespace prefixes that should be - processed for dependency information. Non-matching namespaces are - ignored. - ignored_extra_namespaces: A list of namespaces that should not be reported - as extra regardless of whether they are actually used. - """ - self._closurized_namespaces = closurized_namespaces - self._ignored_extra_namespaces = (ignored_extra_namespaces + - DEFAULT_EXTRA_NAMESPACES) - self.Reset() - - def Reset(self): - """Resets the internal state to prepare for processing a new file.""" - - # A list of goog.provide tokens in the order they appeared in the file. - self._provide_tokens = [] - - # A list of goog.require tokens in the order they appeared in the file. - self._require_tokens = [] - - # Namespaces that are already goog.provided. - self._provided_namespaces = [] - - # Namespaces that are already goog.required. - self._required_namespaces = [] - - # Note that created_namespaces and used_namespaces contain both namespaces - # and identifiers because there are many existing cases where a method or - # constant is provided directly instead of its namespace. Ideally, these - # two lists would only have to contain namespaces. - - # A list of tuples where the first element is the namespace of an identifier - # created in the file, the second is the identifier itself and the third is - # the line number where it's created. - self._created_namespaces = [] - - # A list of UsedNamespace instances. - self._used_namespaces = [] - - # A list of seemingly-unnecessary namespaces that are goog.required() and - # annotated with @suppress {extraRequire}. - self._suppressed_requires = [] - - # A list of goog.provide tokens which are duplicates. - self._duplicate_provide_tokens = [] - - # A list of goog.require tokens which are duplicates. - self._duplicate_require_tokens = [] - - # Whether this file is in a goog.scope. Someday, we may add support - # for checking scopified namespaces, but for now let's just fail - # in a more reasonable way. - self._scopified_file = False - - # TODO(user): Handle the case where there are 2 different requires - # that can satisfy the same dependency, but only one is necessary. - - def GetProvidedNamespaces(self): - """Returns the namespaces which are already provided by this file. - - Returns: - A list of strings where each string is a 'namespace' corresponding to an - existing goog.provide statement in the file being checked. - """ - return set(self._provided_namespaces) - - def GetRequiredNamespaces(self): - """Returns the namespaces which are already required by this file. - - Returns: - A list of strings where each string is a 'namespace' corresponding to an - existing goog.require statement in the file being checked. - """ - return set(self._required_namespaces) - - def IsExtraProvide(self, token): - """Returns whether the given goog.provide token is unnecessary. - - Args: - token: A goog.provide token. - - Returns: - True if the given token corresponds to an unnecessary goog.provide - statement, otherwise False. - """ - namespace = tokenutil.GetStringAfterToken(token) - - if self.GetClosurizedNamespace(namespace) is None: - return False - - if token in self._duplicate_provide_tokens: - return True - - # TODO(user): There's probably a faster way to compute this. - for created_namespace, created_identifier, _ in self._created_namespaces: - if namespace == created_namespace or namespace == created_identifier: - return False - - return True - - def IsExtraRequire(self, token): - """Returns whether the given goog.require token is unnecessary. - - Args: - token: A goog.require token. - - Returns: - True if the given token corresponds to an unnecessary goog.require - statement, otherwise False. - """ - namespace = tokenutil.GetStringAfterToken(token) - - if self.GetClosurizedNamespace(namespace) is None: - return False - - if namespace in self._ignored_extra_namespaces: - return False - - if token in self._duplicate_require_tokens: - return True - - if namespace in self._suppressed_requires: - return False - - # If the namespace contains a component that is initial caps, then that - # must be the last component of the namespace. - parts = namespace.split('.') - if len(parts) > 1 and parts[-2][0].isupper(): - return True - - # TODO(user): There's probably a faster way to compute this. - for ns in self._used_namespaces: - if (not ns.alias_definition and ( - namespace == ns.namespace or namespace == ns.identifier)): - return False - - return True - - def GetMissingProvides(self): - """Returns the dict of missing provided namespaces for the current file. - - Returns: - Returns a dictionary of key as string and value as integer where each - string(key) is a namespace that should be provided by this file, but is - not and integer(value) is first line number where it's defined. - """ - missing_provides = dict() - for namespace, identifier, line_number in self._created_namespaces: - if (not self._IsPrivateIdentifier(identifier) and - namespace not in self._provided_namespaces and - identifier not in self._provided_namespaces and - namespace not in self._required_namespaces and - namespace not in missing_provides): - missing_provides[namespace] = line_number - - return missing_provides - - def GetMissingRequires(self): - """Returns the dict of missing required namespaces for the current file. - - For each non-private identifier used in the file, find either a - goog.require, goog.provide or a created identifier that satisfies it. - goog.require statements can satisfy the identifier by requiring either the - namespace of the identifier or the identifier itself. goog.provide - statements can satisfy the identifier by providing the namespace of the - identifier. A created identifier can only satisfy the used identifier if - it matches it exactly (necessary since things can be defined on a - namespace in more than one file). Note that provided namespaces should be - a subset of created namespaces, but we check both because in some cases we - can't always detect the creation of the namespace. - - Returns: - Returns a dictionary of key as string and value integer where each - string(key) is a namespace that should be required by this file, but is - not and integer(value) is first line number where it's used. - """ - external_dependencies = set(self._required_namespaces) - - # Assume goog namespace is always available. - external_dependencies.add('goog') - # goog.module is treated as a builtin, too (for goog.module.get). - external_dependencies.add('goog.module') - - created_identifiers = set() - for unused_namespace, identifier, unused_line_number in ( - self._created_namespaces): - created_identifiers.add(identifier) - - missing_requires = dict() - illegal_alias_statements = dict() - - def ShouldRequireNamespace(namespace, identifier): - """Checks if a namespace would normally be required.""" - return ( - not self._IsPrivateIdentifier(identifier) and - namespace not in external_dependencies and - namespace not in self._provided_namespaces and - identifier not in external_dependencies and - identifier not in created_identifiers and - namespace not in missing_requires) - - # First check all the used identifiers where we know that their namespace - # needs to be provided (unless they are optional). - for ns in self._used_namespaces: - namespace = ns.namespace - identifier = ns.identifier - if (not ns.alias_definition and - ShouldRequireNamespace(namespace, identifier)): - missing_requires[namespace] = ns.GetLine() - - # Now that all required namespaces are known, we can check if the alias - # definitions (that are likely being used for typeannotations that don't - # need explicit goog.require statements) are already covered. If not - # the user shouldn't use the alias. - for ns in self._used_namespaces: - if (not ns.alias_definition or - not ShouldRequireNamespace(ns.namespace, ns.identifier)): - continue - if self._FindNamespace(ns.identifier, self._provided_namespaces, - created_identifiers, external_dependencies, - missing_requires): - continue - namespace = ns.identifier.rsplit('.', 1)[0] - illegal_alias_statements[namespace] = ns.token - - return missing_requires, illegal_alias_statements - - def _FindNamespace(self, identifier, *namespaces_list): - """Finds the namespace of an identifier given a list of other namespaces. - - Args: - identifier: An identifier whose parent needs to be defined. - e.g. for goog.bar.foo we search something that provides - goog.bar. - *namespaces_list: var args of iterables of namespace identifiers - Returns: - The namespace that the given identifier is part of or None. - """ - identifier = identifier.rsplit('.', 1)[0] - identifier_prefix = identifier + '.' - for namespaces in namespaces_list: - for namespace in namespaces: - if namespace == identifier or namespace.startswith(identifier_prefix): - return namespace - return None - - def _IsPrivateIdentifier(self, identifier): - """Returns whether the given identifier is private.""" - pieces = identifier.split('.') - for piece in pieces: - if piece.endswith('_'): - return True - return False - - def IsFirstProvide(self, token): - """Returns whether token is the first provide token.""" - return self._provide_tokens and token == self._provide_tokens[0] - - def IsFirstRequire(self, token): - """Returns whether token is the first require token.""" - return self._require_tokens and token == self._require_tokens[0] - - def IsLastProvide(self, token): - """Returns whether token is the last provide token.""" - return self._provide_tokens and token == self._provide_tokens[-1] - - def IsLastRequire(self, token): - """Returns whether token is the last require token.""" - return self._require_tokens and token == self._require_tokens[-1] - - def ProcessToken(self, token, state_tracker): - """Processes the given token for dependency information. - - Args: - token: The token to process. - state_tracker: The JavaScript state tracker. - """ - - # Note that this method is in the critical path for the linter and has been - # optimized for performance in the following ways: - # - Tokens are checked by type first to minimize the number of function - # calls necessary to determine if action needs to be taken for the token. - # - The most common tokens types are checked for first. - # - The number of function calls has been minimized (thus the length of this - # function. - - if token.type == TokenType.IDENTIFIER: - # TODO(user): Consider saving the whole identifier in metadata. - whole_identifier_string = tokenutil.GetIdentifierForToken(token) - if whole_identifier_string is None: - # We only want to process the identifier one time. If the whole string - # identifier is None, that means this token was part of a multi-token - # identifier, but it was not the first token of the identifier. - return - - # In the odd case that a goog.require is encountered inside a function, - # just ignore it (e.g. dynamic loading in test runners). - if token.string == 'goog.require' and not state_tracker.InFunction(): - self._require_tokens.append(token) - namespace = tokenutil.GetStringAfterToken(token) - if namespace in self._required_namespaces: - self._duplicate_require_tokens.append(token) - else: - self._required_namespaces.append(namespace) - - # If there is a suppression for the require, add a usage for it so it - # gets treated as a regular goog.require (i.e. still gets sorted). - if self._HasSuppression(state_tracker, 'extraRequire'): - self._suppressed_requires.append(namespace) - self._AddUsedNamespace(state_tracker, namespace, token) - - elif token.string == 'goog.provide': - self._provide_tokens.append(token) - namespace = tokenutil.GetStringAfterToken(token) - if namespace in self._provided_namespaces: - self._duplicate_provide_tokens.append(token) - else: - self._provided_namespaces.append(namespace) - - # If there is a suppression for the provide, add a creation for it so it - # gets treated as a regular goog.provide (i.e. still gets sorted). - if self._HasSuppression(state_tracker, 'extraProvide'): - self._AddCreatedNamespace(state_tracker, namespace, token.line_number) - - elif token.string == 'goog.scope': - self._scopified_file = True - - elif token.string == 'goog.setTestOnly': - - # Since the message is optional, we don't want to scan to later lines. - for t in tokenutil.GetAllTokensInSameLine(token): - if t.type == TokenType.STRING_TEXT: - message = t.string - - if re.match(r'^\w+(\.\w+)+$', message): - # This looks like a namespace. If it's a Closurized namespace, - # consider it created. - base_namespace = message.split('.', 1)[0] - if base_namespace in self._closurized_namespaces: - self._AddCreatedNamespace(state_tracker, message, - token.line_number) - - break - else: - jsdoc = state_tracker.GetDocComment() - if token.metadata and token.metadata.aliased_symbol: - whole_identifier_string = token.metadata.aliased_symbol - elif (token.string == 'goog.module.get' and - not self._HasSuppression(state_tracker, 'extraRequire')): - # Cannot use _AddUsedNamespace as this is not an identifier, but - # already the entire namespace that's required. - namespace = tokenutil.GetStringAfterToken(token) - namespace = UsedNamespace(namespace, namespace, token, - alias_definition=False) - self._used_namespaces.append(namespace) - if jsdoc and jsdoc.HasFlag('typedef'): - self._AddCreatedNamespace(state_tracker, whole_identifier_string, - token.line_number, - namespace=self.GetClosurizedNamespace( - whole_identifier_string)) - else: - is_alias_definition = (token.metadata and - token.metadata.is_alias_definition) - self._AddUsedNamespace(state_tracker, whole_identifier_string, - token, is_alias_definition) - - elif token.type == TokenType.SIMPLE_LVALUE: - identifier = token.values['identifier'] - start_token = tokenutil.GetIdentifierStart(token) - if start_token and start_token != token: - # Multi-line identifier being assigned. Get the whole identifier. - identifier = tokenutil.GetIdentifierForToken(start_token) - else: - start_token = token - # If an alias is defined on the start_token, use it instead. - if (start_token and - start_token.metadata and - start_token.metadata.aliased_symbol and - not start_token.metadata.is_alias_definition): - identifier = start_token.metadata.aliased_symbol - - if identifier: - namespace = self.GetClosurizedNamespace(identifier) - if state_tracker.InFunction(): - self._AddUsedNamespace(state_tracker, identifier, token) - elif namespace and namespace != 'goog': - self._AddCreatedNamespace(state_tracker, identifier, - token.line_number, namespace=namespace) - - elif token.type == TokenType.DOC_FLAG: - flag = token.attached_object - flag_type = flag.flag_type - if flag and flag.HasType() and flag.jstype: - is_interface = state_tracker.GetDocComment().HasFlag('interface') - if flag_type == 'implements' or (flag_type == 'extends' - and is_interface): - identifier = flag.jstype.alias or flag.jstype.identifier - self._AddUsedNamespace(state_tracker, identifier, token) - # Since we process doctypes only for implements and extends, the - # type is a simple one and we don't need any iteration for subtypes. - - def _AddCreatedNamespace(self, state_tracker, identifier, line_number, - namespace=None): - """Adds the namespace of an identifier to the list of created namespaces. - - If the identifier is annotated with a 'missingProvide' suppression, it is - not added. - - Args: - state_tracker: The JavaScriptStateTracker instance. - identifier: The identifier to add. - line_number: Line number where namespace is created. - namespace: The namespace of the identifier or None if the identifier is - also the namespace. - """ - if not namespace: - namespace = identifier - - if self._HasSuppression(state_tracker, 'missingProvide'): - return - - self._created_namespaces.append([namespace, identifier, line_number]) - - def _AddUsedNamespace(self, state_tracker, identifier, token, - is_alias_definition=False): - """Adds the namespace of an identifier to the list of used namespaces. - - If the identifier is annotated with a 'missingRequire' suppression, it is - not added. - - Args: - state_tracker: The JavaScriptStateTracker instance. - identifier: An identifier which has been used. - token: The token in which the namespace is used. - is_alias_definition: If the used namespace is part of an alias_definition. - Aliased symbols need their parent namespace to be available, if it is - not yet required through another symbol, an error will be thrown. - """ - if self._HasSuppression(state_tracker, 'missingRequire'): - return - - identifier = self._GetUsedIdentifier(identifier) - namespace = self.GetClosurizedNamespace(identifier) - # b/5362203 If its a variable in scope then its not a required namespace. - if namespace and not state_tracker.IsVariableInScope(namespace): - namespace = UsedNamespace(namespace, identifier, token, - is_alias_definition) - self._used_namespaces.append(namespace) - - def _HasSuppression(self, state_tracker, suppression): - jsdoc = state_tracker.GetDocComment() - return jsdoc and suppression in jsdoc.suppressions - - def _GetUsedIdentifier(self, identifier): - """Strips apply/call/inherit calls from the identifier.""" - for suffix in ('.apply', '.call', '.inherit'): - if identifier.endswith(suffix): - return identifier[:-len(suffix)] - return identifier - - def GetClosurizedNamespace(self, identifier): - """Given an identifier, returns the namespace that identifier is from. - - Args: - identifier: The identifier to extract a namespace from. - - Returns: - The namespace the given identifier resides in, or None if one could not - be found. - """ - if identifier.startswith('goog.global'): - # Ignore goog.global, since it is, by definition, global. - return None - - parts = identifier.split('.') - for namespace in self._closurized_namespaces: - if not identifier.startswith(namespace + '.'): - continue - - # The namespace for a class is the shortest prefix ending in a class - # name, which starts with a capital letter but is not a capitalized word. - # - # We ultimately do not want to allow requiring or providing of inner - # classes/enums. Instead, a file should provide only the top-level class - # and users should require only that. - namespace = [] - for part in parts: - if part == 'prototype' or part.isupper(): - return '.'.join(namespace) - namespace.append(part) - if part[0].isupper(): - return '.'.join(namespace) - - # At this point, we know there's no class or enum, so the namespace is - # just the identifier with the last part removed. With the exception of - # apply, inherits, and call, which should also be stripped. - if parts[-1] in ('apply', 'inherits', 'call'): - parts.pop() - parts.pop() - - # If the last part ends with an underscore, it is a private variable, - # method, or enum. The namespace is whatever is before it. - if parts and parts[-1].endswith('_'): - parts.pop() - - return '.'.join(parts) - - return None
diff --git a/third_party/closure_linter/closure_linter/closurizednamespacesinfo_test.py b/third_party/closure_linter/closure_linter/closurizednamespacesinfo_test.py deleted file mode 100755 index 7aeae219..0000000 --- a/third_party/closure_linter/closure_linter/closurizednamespacesinfo_test.py +++ /dev/null
@@ -1,873 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Unit tests for ClosurizedNamespacesInfo.""" - - - -import unittest as googletest -from closure_linter import aliaspass -from closure_linter import closurizednamespacesinfo -from closure_linter import ecmametadatapass -from closure_linter import javascriptstatetracker -from closure_linter import javascripttokens -from closure_linter import testutil -from closure_linter import tokenutil - -# pylint: disable=g-bad-name -TokenType = javascripttokens.JavaScriptTokenType - - -def _ToLineDict(illegal_alias_stmts): - """Replaces tokens with the respective line number.""" - return {k: v.line_number for k, v in illegal_alias_stmts.iteritems()} - - -class ClosurizedNamespacesInfoTest(googletest.TestCase): - """Tests for ClosurizedNamespacesInfo.""" - - _test_cases = { - 'goog.global.anything': None, - 'package.CONSTANT': 'package', - 'package.methodName': 'package', - 'package.subpackage.methodName': 'package.subpackage', - 'package.subpackage.methodName.apply': 'package.subpackage', - 'package.ClassName.something': 'package.ClassName', - 'package.ClassName.Enum.VALUE.methodName': 'package.ClassName', - 'package.ClassName.CONSTANT': 'package.ClassName', - 'package.namespace.CONSTANT.methodName': 'package.namespace', - 'package.ClassName.inherits': 'package.ClassName', - 'package.ClassName.apply': 'package.ClassName', - 'package.ClassName.methodName.apply': 'package.ClassName', - 'package.ClassName.methodName.call': 'package.ClassName', - 'package.ClassName.prototype.methodName': 'package.ClassName', - 'package.ClassName.privateMethod_': 'package.ClassName', - 'package.className.privateProperty_': 'package.className', - 'package.className.privateProperty_.methodName': 'package.className', - 'package.ClassName.PrivateEnum_': 'package.ClassName', - 'package.ClassName.prototype.methodName.apply': 'package.ClassName', - 'package.ClassName.property.subProperty': 'package.ClassName', - 'package.className.prototype.something.somethingElse': 'package.className' - } - - def testGetClosurizedNamespace(self): - """Tests that the correct namespace is returned for various identifiers.""" - namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo( - closurized_namespaces=['package'], ignored_extra_namespaces=[]) - for identifier, expected_namespace in self._test_cases.items(): - actual_namespace = namespaces_info.GetClosurizedNamespace(identifier) - self.assertEqual( - expected_namespace, - actual_namespace, - 'expected namespace "' + str(expected_namespace) + - '" for identifier "' + str(identifier) + '" but was "' + - str(actual_namespace) + '"') - - def testIgnoredExtraNamespaces(self): - """Tests that ignored_extra_namespaces are ignored.""" - token = self._GetRequireTokens('package.Something') - namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo( - closurized_namespaces=['package'], - ignored_extra_namespaces=['package.Something']) - - self.assertFalse(namespaces_info.IsExtraRequire(token), - 'Should be valid since it is in ignored namespaces.') - - namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo( - ['package'], []) - - self.assertTrue(namespaces_info.IsExtraRequire(token), - 'Should be invalid since it is not in ignored namespaces.') - - def testIsExtraProvide_created(self): - """Tests that provides for created namespaces are not extra.""" - input_lines = [ - 'goog.provide(\'package.Foo\');', - 'package.Foo = function() {};' - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertFalse(namespaces_info.IsExtraProvide(token), - 'Should not be extra since it is created.') - - def testIsExtraProvide_createdIdentifier(self): - """Tests that provides for created identifiers are not extra.""" - input_lines = [ - 'goog.provide(\'package.Foo.methodName\');', - 'package.Foo.methodName = function() {};' - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertFalse(namespaces_info.IsExtraProvide(token), - 'Should not be extra since it is created.') - - def testIsExtraProvide_notCreated(self): - """Tests that provides for non-created namespaces are extra.""" - input_lines = ['goog.provide(\'package.Foo\');'] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertTrue(namespaces_info.IsExtraProvide(token), - 'Should be extra since it is not created.') - - def testIsExtraProvide_notCreatedMultipartClosurizedNamespace(self): - """Tests that provides for non-created namespaces are extra.""" - input_lines = ['goog.provide(\'multi.part.namespace.Foo\');'] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['multi.part']) - - self.assertTrue(namespaces_info.IsExtraProvide(token), - 'Should be extra since it is not created.') - - def testIsExtraProvide_duplicate(self): - """Tests that providing a namespace twice makes the second one extra.""" - input_lines = [ - 'goog.provide(\'package.Foo\');', - 'goog.provide(\'package.Foo\');', - 'package.Foo = function() {};' - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - # Advance to the second goog.provide token. - token = tokenutil.Search(token.next, TokenType.IDENTIFIER) - - self.assertTrue(namespaces_info.IsExtraProvide(token), - 'Should be extra since it is already provided.') - - def testIsExtraProvide_notClosurized(self): - """Tests that provides of non-closurized namespaces are not extra.""" - input_lines = ['goog.provide(\'notclosurized.Foo\');'] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertFalse(namespaces_info.IsExtraProvide(token), - 'Should not be extra since it is not closurized.') - - def testIsExtraRequire_used(self): - """Tests that requires for used namespaces are not extra.""" - input_lines = [ - 'goog.require(\'package.Foo\');', - 'var x = package.Foo.methodName();' - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertFalse(namespaces_info.IsExtraRequire(token), - 'Should not be extra since it is used.') - - def testIsExtraRequire_usedIdentifier(self): - """Tests that requires for used methods on classes are extra.""" - input_lines = [ - 'goog.require(\'package.Foo.methodName\');', - 'var x = package.Foo.methodName();' - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertTrue(namespaces_info.IsExtraRequire(token), - 'Should require the package, not the method specifically.') - - def testIsExtraRequire_notUsed(self): - """Tests that requires for unused namespaces are extra.""" - input_lines = ['goog.require(\'package.Foo\');'] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertTrue(namespaces_info.IsExtraRequire(token), - 'Should be extra since it is not used.') - - def testIsExtraRequire_notUsedMultiPartClosurizedNamespace(self): - """Tests unused require with multi-part closurized namespaces.""" - - input_lines = ['goog.require(\'multi.part.namespace.Foo\');'] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['multi.part']) - - self.assertTrue(namespaces_info.IsExtraRequire(token), - 'Should be extra since it is not used.') - - def testIsExtraRequire_notClosurized(self): - """Tests that requires of non-closurized namespaces are not extra.""" - input_lines = ['goog.require(\'notclosurized.Foo\');'] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertFalse(namespaces_info.IsExtraRequire(token), - 'Should not be extra since it is not closurized.') - - def testIsExtraRequire_objectOnClass(self): - """Tests that requiring an object on a class is extra.""" - input_lines = [ - 'goog.require(\'package.Foo.Enum\');', - 'var x = package.Foo.Enum.VALUE1;', - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertTrue(namespaces_info.IsExtraRequire(token), - 'The whole class, not the object, should be required.'); - - def testIsExtraRequire_constantOnClass(self): - """Tests that requiring a constant on a class is extra.""" - input_lines = [ - 'goog.require(\'package.Foo.CONSTANT\');', - 'var x = package.Foo.CONSTANT', - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertTrue(namespaces_info.IsExtraRequire(token), - 'The class, not the constant, should be required.'); - - def testIsExtraRequire_constantNotOnClass(self): - """Tests that requiring a constant not on a class is OK.""" - input_lines = [ - 'goog.require(\'package.subpackage.CONSTANT\');', - 'var x = package.subpackage.CONSTANT', - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertFalse(namespaces_info.IsExtraRequire(token), - 'Constants can be required except on classes.'); - - def testIsExtraRequire_methodNotOnClass(self): - """Tests that requiring a method not on a class is OK.""" - input_lines = [ - 'goog.require(\'package.subpackage.method\');', - 'var x = package.subpackage.method()', - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - - self.assertFalse(namespaces_info.IsExtraRequire(token), - 'Methods can be required except on classes.'); - - def testIsExtraRequire_defaults(self): - """Tests that there are no warnings about extra requires for test utils""" - input_lines = ['goog.require(\'goog.testing.jsunit\');'] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['goog']) - - self.assertFalse(namespaces_info.IsExtraRequire(token), - 'Should not be extra since it is for testing.') - - def testGetMissingProvides_provided(self): - """Tests that provided functions don't cause a missing provide.""" - input_lines = [ - 'goog.provide(\'package.Foo\');', - 'package.Foo = function() {};' - ] - - namespaces_info = self._GetNamespacesInfoForScript( - input_lines, ['package']) - - self.assertEquals(0, len(namespaces_info.GetMissingProvides())) - - def testGetMissingProvides_providedIdentifier(self): - """Tests that provided identifiers don't cause a missing provide.""" - input_lines = [ - 'goog.provide(\'package.Foo.methodName\');', - 'package.Foo.methodName = function() {};' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - self.assertEquals(0, len(namespaces_info.GetMissingProvides())) - - def testGetMissingProvides_providedParentIdentifier(self): - """Tests that provided identifiers on a class don't cause a missing provide - on objects attached to that class.""" - input_lines = [ - 'goog.provide(\'package.foo.ClassName\');', - 'package.foo.ClassName.methodName = function() {};', - 'package.foo.ClassName.ObjectName = 1;', - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - self.assertEquals(0, len(namespaces_info.GetMissingProvides())) - - def testGetMissingProvides_unprovided(self): - """Tests that unprovided functions cause a missing provide.""" - input_lines = ['package.Foo = function() {};'] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - - missing_provides = namespaces_info.GetMissingProvides() - self.assertEquals(1, len(missing_provides)) - missing_provide = missing_provides.popitem() - self.assertEquals('package.Foo', missing_provide[0]) - self.assertEquals(1, missing_provide[1]) - - def testGetMissingProvides_privatefunction(self): - """Tests that unprovided private functions don't cause a missing provide.""" - input_lines = ['package.Foo_ = function() {};'] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - self.assertEquals(0, len(namespaces_info.GetMissingProvides())) - - def testGetMissingProvides_required(self): - """Tests that required namespaces don't cause a missing provide.""" - input_lines = [ - 'goog.require(\'package.Foo\');', - 'package.Foo.methodName = function() {};' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - self.assertEquals(0, len(namespaces_info.GetMissingProvides())) - - def testGetMissingRequires_required(self): - """Tests that required namespaces don't cause a missing require.""" - input_lines = [ - 'goog.require(\'package.Foo\');', - 'package.Foo();' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(0, len(missing_requires)) - - def testGetMissingRequires_requiredIdentifier(self): - """Tests that required namespaces satisfy identifiers on that namespace.""" - input_lines = [ - 'goog.require(\'package.Foo\');', - 'package.Foo.methodName();' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(0, len(missing_requires)) - - def testGetMissingRequires_requiredNamespace(self): - """Tests that required namespaces satisfy the namespace.""" - input_lines = [ - 'goog.require(\'package.soy.fooTemplate\');', - 'render(package.soy.fooTemplate);' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(0, len(missing_requires)) - - def testGetMissingRequires_requiredParentClass(self): - """Tests that requiring a parent class of an object is sufficient to prevent - a missing require on that object.""" - input_lines = [ - 'goog.require(\'package.Foo\');', - 'package.Foo.methodName();', - 'package.Foo.methodName(package.Foo.ObjectName);' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(0, len(missing_requires)) - - def testGetMissingRequires_unrequired(self): - """Tests that unrequired namespaces cause a missing require.""" - input_lines = ['package.Foo();'] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(1, len(missing_requires)) - missing_req = missing_requires.popitem() - self.assertEquals('package.Foo', missing_req[0]) - self.assertEquals(1, missing_req[1]) - - def testGetMissingRequires_provided(self): - """Tests that provided namespaces satisfy identifiers on that namespace.""" - input_lines = [ - 'goog.provide(\'package.Foo\');', - 'package.Foo.methodName();' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(0, len(missing_requires)) - - def testGetMissingRequires_created(self): - """Tests that created namespaces do not satisfy usage of an identifier.""" - input_lines = [ - 'package.Foo = function();', - 'package.Foo.methodName();', - 'package.Foo.anotherMethodName1();', - 'package.Foo.anotherMethodName2();' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(1, len(missing_requires)) - missing_require = missing_requires.popitem() - self.assertEquals('package.Foo', missing_require[0]) - # Make sure line number of first occurrence is reported - self.assertEquals(2, missing_require[1]) - - def testGetMissingRequires_createdIdentifier(self): - """Tests that created identifiers satisfy usage of the identifier.""" - input_lines = [ - 'package.Foo.methodName = function();', - 'package.Foo.methodName();' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(0, len(missing_requires)) - - def testGetMissingRequires_implements(self): - """Tests that a parametrized type requires the correct identifier.""" - input_lines = [ - '/** @constructor @implements {package.Bar<T>} */', - 'package.Foo = function();', - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertItemsEqual({'package.Bar': 1}, missing_requires) - - def testGetMissingRequires_objectOnClass(self): - """Tests that we should require a class, not the object on the class.""" - input_lines = [ - 'goog.require(\'package.Foo.Enum\');', - 'var x = package.Foo.Enum.VALUE1;', - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['package']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(1, len(missing_requires), - 'The whole class, not the object, should be required.') - - def testGetMissingRequires_variableWithSameName(self): - """Tests that we should not goog.require variables and parameters. - - b/5362203 Variables in scope are not missing namespaces. - """ - input_lines = [ - 'goog.provide(\'Foo\');', - 'Foo.A = function();', - 'Foo.A.prototype.method = function(ab) {', - ' if (ab) {', - ' var docs;', - ' var lvalue = new Obj();', - ' // Variable in scope hence not goog.require here.', - ' docs.foo.abc = 1;', - ' lvalue.next();', - ' }', - ' // Since js is function scope this should also not goog.require.', - ' docs.foo.func();', - ' // Its not a variable in scope hence goog.require.', - ' dummy.xyz.reset();', - ' return this.method2();', - '};', - 'Foo.A.prototype.method1 = function(docs, abcd, xyz) {', - ' // Parameter hence not goog.require.', - ' docs.nodes.length = 2;', - ' lvalue.abc.reset();', - '};' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['Foo', - 'docs', - 'lvalue', - 'dummy']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals(2, len(missing_requires)) - self.assertItemsEqual( - {'dummy.xyz': 14, - 'lvalue.abc': 20}, missing_requires) - - def testIsFirstProvide(self): - """Tests operation of the isFirstProvide method.""" - input_lines = [ - 'goog.provide(\'package.Foo\');', - 'package.Foo.methodName();' - ] - - token, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - input_lines, ['package']) - self.assertTrue(namespaces_info.IsFirstProvide(token)) - - def testGetWholeIdentifierString(self): - """Tests that created identifiers satisfy usage of the identifier.""" - input_lines = [ - 'package.Foo.', - ' veryLong.', - ' identifier;' - ] - - token = testutil.TokenizeSource(input_lines) - - self.assertEquals('package.Foo.veryLong.identifier', - tokenutil.GetIdentifierForToken(token)) - - self.assertEquals(None, - tokenutil.GetIdentifierForToken(token.next)) - - def testScopified(self): - """Tests that a goog.scope call is noticed.""" - input_lines = [ - 'goog.scope(function() {', - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - self.assertTrue(namespaces_info._scopified_file) - - def testScope_unusedAlias(self): - """Tests that an unused alias symbol is illegal.""" - input_lines = [ - 'goog.scope(function() {', - 'var Event = goog.events.Event;', - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, missing_requires) - self.assertEquals({'goog.events': 2}, _ToLineDict(illegal_alias_stmts)) - - def testScope_usedMultilevelAlias(self): - """Tests that an used alias symbol in a deep namespace is ok.""" - input_lines = [ - 'goog.require(\'goog.Events\');', - 'goog.scope(function() {', - 'var Event = goog.Events.DeepNamespace.Event;', - 'Event();', - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, missing_requires) - self.assertEquals({}, illegal_alias_stmts) - - def testScope_usedAlias(self): - """Tests that aliased symbols result in correct requires.""" - input_lines = [ - 'goog.scope(function() {', - 'var Event = goog.events.Event;', - 'var dom = goog.dom;', - 'Event(dom.classes.get);', - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, illegal_alias_stmts) - self.assertEquals({'goog.dom.classes': 4, 'goog.events.Event': 4}, - missing_requires) - - def testModule_alias(self): - """Tests that goog.module style aliases are supported.""" - input_lines = [ - 'goog.module(\'test.module\');', - 'var Unused = goog.require(\'goog.Unused\');', - 'var AliasedClass = goog.require(\'goog.AliasedClass\');', - 'var x = new AliasedClass();', - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - namespaceToken = self._GetRequireTokens('goog.AliasedClass') - self.assertFalse(namespaces_info.IsExtraRequire(namespaceToken), - 'AliasedClass should be marked as used') - unusedToken = self._GetRequireTokens('goog.Unused') - self.assertTrue(namespaces_info.IsExtraRequire(unusedToken), - 'Unused should be marked as not used') - - def testModule_aliasInScope(self): - """Tests that goog.module style aliases are supported.""" - input_lines = [ - 'goog.module(\'test.module\');', - 'var AliasedClass = goog.require(\'goog.AliasedClass\');', - 'goog.scope(function() {', - 'var x = new AliasedClass();', - '});', - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - namespaceToken = self._GetRequireTokens('goog.AliasedClass') - self.assertFalse(namespaces_info.IsExtraRequire(namespaceToken), - 'AliasedClass should be marked as used') - - def testModule_getAlwaysProvided(self): - """Tests that goog.module.get is recognized as a built-in.""" - input_lines = [ - 'goog.provide(\'test.MyClass\');', - 'goog.require(\'goog.someModule\');', - 'goog.scope(function() {', - 'var someModule = goog.module.get(\'goog.someModule\');', - 'test.MyClass = function() {};', - '});', - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - self.assertEquals({}, namespaces_info.GetMissingRequires()[0]) - - def testModule_requireForGet(self): - """Tests that goog.module.get needs a goog.require call.""" - input_lines = [ - 'goog.provide(\'test.MyClass\');', - 'function foo() {', - ' var someModule = goog.module.get(\'goog.someModule\');', - ' someModule.doSth();', - '}', - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - self.assertEquals({'goog.someModule': 3}, - namespaces_info.GetMissingRequires()[0]) - - def testScope_usedTypeAlias(self): - """Tests aliased symbols in type annotations.""" - input_lines = [ - 'goog.scope(function() {', - 'var Event = goog.events.Event;', - '/** @type {Event} */;', - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, missing_requires) - self.assertEquals({'goog.events': 2}, _ToLineDict(illegal_alias_stmts)) - - def testScope_partialAlias_typeOnly(self): - """Tests a partial alias only used in type annotations. - - In this example, some goog.events namespace would need to be required - so that evaluating goog.events.bar doesn't throw an error. - """ - input_lines = [ - 'goog.scope(function() {', - 'var bar = goog.events.bar;', - '/** @type {bar.Foo} */;', - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, missing_requires) - self.assertEquals({'goog.events': 2}, _ToLineDict(illegal_alias_stmts)) - - def testScope_partialAlias(self): - """Tests a partial alias in conjunction with a type annotation. - - In this example, the partial alias is already defined by another type, - therefore the doc-only type doesn't need to be required. - """ - input_lines = [ - 'goog.scope(function() {', - 'var bar = goog.events.bar;', - '/** @type {bar.Event} */;', - 'bar.EventType();' - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({'goog.events.bar.EventType': 4}, missing_requires) - self.assertEquals({}, illegal_alias_stmts) - - def testScope_partialAliasRequires(self): - """Tests partial aliases with correct requires.""" - input_lines = [ - 'goog.require(\'goog.events.bar.EventType\');', - 'goog.scope(function() {', - 'var bar = goog.events.bar;', - '/** @type {bar.Event} */;', - 'bar.EventType();' - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, missing_requires) - self.assertEquals({}, illegal_alias_stmts) - - def testScope_partialAliasRequiresBoth(self): - """Tests partial aliases with correct requires.""" - input_lines = [ - 'goog.require(\'goog.events.bar.Event\');', - 'goog.require(\'goog.events.bar.EventType\');', - 'goog.scope(function() {', - 'var bar = goog.events.bar;', - '/** @type {bar.Event} */;', - 'bar.EventType();' - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, missing_requires) - self.assertEquals({}, illegal_alias_stmts) - event_token = self._GetRequireTokens('goog.events.bar.Event') - self.assertTrue(namespaces_info.IsExtraRequire(event_token)) - - def testScope_partialAliasNoSubtypeRequires(self): - """Tests that partial aliases don't yield subtype requires (regression).""" - input_lines = [ - 'goog.provide(\'goog.events.Foo\');', - 'goog.scope(function() {', - 'goog.events.Foo = {};', - 'var Foo = goog.events.Foo;' - 'Foo.CssName_ = {};' - 'var CssName_ = Foo.CssName_;' - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, _ = namespaces_info.GetMissingRequires() - self.assertEquals({}, missing_requires) - - def testScope_aliasNamespace(self): - """Tests that an unused alias namespace is not required when available. - - In the example goog.events.Bar is not required, because the namespace - goog.events is already defined because goog.events.Foo is required. - """ - input_lines = [ - 'goog.require(\'goog.events.Foo\');', - 'goog.scope(function() {', - 'var Bar = goog.events.Bar;', - '/** @type {Bar} */;', - 'goog.events.Foo;', - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, missing_requires) - self.assertEquals({}, illegal_alias_stmts) - - def testScope_aliasNamespaceIllegal(self): - """Tests that an unused alias namespace is not required when available.""" - input_lines = [ - 'goog.scope(function() {', - 'var Bar = goog.events.Bar;', - '/** @type {Bar} */;', - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_requires, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, missing_requires) - self.assertEquals({'goog.events': 2}, _ToLineDict(illegal_alias_stmts)) - - def testScope_provides(self): - """Tests that aliased symbols result in correct provides.""" - input_lines = [ - 'goog.scope(function() {', - 'goog.bar = {};', - 'var bar = goog.bar;', - 'bar.Foo = {};', - '});' - ] - - namespaces_info = self._GetNamespacesInfoForScript(input_lines, ['goog']) - missing_provides = namespaces_info.GetMissingProvides() - self.assertEquals({'goog.bar.Foo': 4}, missing_provides) - _, illegal_alias_stmts = namespaces_info.GetMissingRequires() - self.assertEquals({}, illegal_alias_stmts) - - def testSetTestOnlyNamespaces(self): - """Tests that a namespace in setTestOnly makes it a valid provide.""" - namespaces_info = self._GetNamespacesInfoForScript([ - 'goog.setTestOnly(\'goog.foo.barTest\');' - ], ['goog']) - - token = self._GetProvideTokens('goog.foo.barTest') - self.assertFalse(namespaces_info.IsExtraProvide(token)) - - token = self._GetProvideTokens('goog.foo.bazTest') - self.assertTrue(namespaces_info.IsExtraProvide(token)) - - def testSetTestOnlyComment(self): - """Ensure a comment in setTestOnly does not cause a created namespace.""" - namespaces_info = self._GetNamespacesInfoForScript([ - 'goog.setTestOnly(\'this is a comment\');' - ], ['goog']) - - self.assertEquals( - [], namespaces_info._created_namespaces, - 'A comment in setTestOnly should not modify created namespaces.') - - def _GetNamespacesInfoForScript(self, script, closurized_namespaces=None): - _, namespaces_info = self._GetStartTokenAndNamespacesInfoForScript( - script, closurized_namespaces) - - return namespaces_info - - def _GetStartTokenAndNamespacesInfoForScript( - self, script, closurized_namespaces): - - token = testutil.TokenizeSource(script) - return token, self._GetInitializedNamespacesInfo( - token, closurized_namespaces, []) - - def _GetInitializedNamespacesInfo(self, token, closurized_namespaces, - ignored_extra_namespaces): - """Returns a namespaces info initialized with the given token stream.""" - namespaces_info = closurizednamespacesinfo.ClosurizedNamespacesInfo( - closurized_namespaces=closurized_namespaces, - ignored_extra_namespaces=ignored_extra_namespaces) - state_tracker = javascriptstatetracker.JavaScriptStateTracker() - - ecma_pass = ecmametadatapass.EcmaMetaDataPass() - ecma_pass.Process(token) - - state_tracker.DocFlagPass(token, error_handler=None) - - alias_pass = aliaspass.AliasPass(closurized_namespaces) - alias_pass.Process(token) - - while token: - state_tracker.HandleToken(token, state_tracker.GetLastNonSpaceToken()) - namespaces_info.ProcessToken(token, state_tracker) - state_tracker.HandleAfterToken(token) - token = token.next - - return namespaces_info - - def _GetProvideTokens(self, namespace): - """Returns a list of tokens for a goog.require of the given namespace.""" - line_text = 'goog.require(\'' + namespace + '\');\n' - return testutil.TokenizeSource([line_text]) - - def _GetRequireTokens(self, namespace): - """Returns a list of tokens for a goog.require of the given namespace.""" - line_text = 'goog.require(\'' + namespace + '\');\n' - return testutil.TokenizeSource([line_text]) - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/common/__init__.py b/third_party/closure_linter/closure_linter/common/__init__.py deleted file mode 100755 index 5793043..0000000 --- a/third_party/closure_linter/closure_linter/common/__init__.py +++ /dev/null
@@ -1,16 +0,0 @@ -#!/usr/bin/env python -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Package indicator for gjslint.common."""
diff --git a/third_party/closure_linter/closure_linter/common/error.py b/third_party/closure_linter/closure_linter/common/error.py deleted file mode 100755 index 4209c23..0000000 --- a/third_party/closure_linter/closure_linter/common/error.py +++ /dev/null
@@ -1,65 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Error object commonly used in linters.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - - -class Error(object): - """Object representing a style error.""" - - def __init__(self, code, message, token=None, position=None, fix_data=None): - """Initialize the error object. - - Args: - code: The numeric error code. - message: The error message string. - token: The tokens.Token where the error occurred. - position: The position of the error within the token. - fix_data: Data to be used in autofixing. Codes with fix_data are: - GOOG_REQUIRES_NOT_ALPHABETIZED - List of string value tokens that are - class names in goog.requires calls. - """ - self.code = code - self.message = message - self.token = token - self.position = position - if token: - self.start_index = token.start_index - else: - self.start_index = 0 - self.fix_data = fix_data - if self.position: - self.start_index += self.position.start - - def Compare(a, b): - """Compare two error objects, by source code order. - - Args: - a: First error object. - b: Second error object. - - Returns: - A Negative/0/Positive number when a is before/the same as/after b. - """ - line_diff = a.token.line_number - b.token.line_number - if line_diff: - return line_diff - - return a.start_index - b.start_index - Compare = staticmethod(Compare)
diff --git a/third_party/closure_linter/closure_linter/common/erroraccumulator.py b/third_party/closure_linter/closure_linter/common/erroraccumulator.py deleted file mode 100755 index 55844ba..0000000 --- a/third_party/closure_linter/closure_linter/common/erroraccumulator.py +++ /dev/null
@@ -1,46 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Linter error handler class that accumulates an array of errors.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - - -from closure_linter.common import errorhandler - - -class ErrorAccumulator(errorhandler.ErrorHandler): - """Error handler object that accumulates errors in a list.""" - - def __init__(self): - self._errors = [] - - def HandleError(self, error): - """Append the error to the list. - - Args: - error: The error object - """ - self._errors.append(error) - - def GetErrors(self): - """Returns the accumulated errors. - - Returns: - A sequence of errors. - """ - return self._errors
diff --git a/third_party/closure_linter/closure_linter/common/errorhandler.py b/third_party/closure_linter/closure_linter/common/errorhandler.py deleted file mode 100755 index 764d54d..0000000 --- a/third_party/closure_linter/closure_linter/common/errorhandler.py +++ /dev/null
@@ -1,61 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Interface for a linter error handler. - -Error handlers aggregate a set of errors from multiple files and can optionally -perform some action based on the reported errors, for example, logging the error -or automatically fixing it. -""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - - -class ErrorHandler(object): - """Error handler interface.""" - - def __init__(self): - if self.__class__ == ErrorHandler: - raise NotImplementedError('class ErrorHandler is abstract') - - def HandleFile(self, filename, first_token): - """Notifies this ErrorHandler that subsequent errors are in filename. - - Args: - filename: The file being linted. - first_token: The first token of the file. - """ - - def HandleError(self, error): - """Append the error to the list. - - Args: - error: The error object - """ - - def FinishFile(self): - """Finishes handling the current file. - - Should be called after all errors in a file have been handled. - """ - - def GetErrors(self): - """Returns the accumulated errors. - - Returns: - A sequence of errors. - """
diff --git a/third_party/closure_linter/closure_linter/common/erroroutput.py b/third_party/closure_linter/closure_linter/common/erroroutput.py deleted file mode 100644 index 149738b..0000000 --- a/third_party/closure_linter/closure_linter/common/erroroutput.py +++ /dev/null
@@ -1,52 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Utility functions to format errors.""" - - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)', - 'nnaze@google.com (Nathan Naze)') - - -def GetUnixErrorOutput(filename, error, new_error=False): - """Get a output line for an error in UNIX format.""" - - line = '' - - if error.token: - line = '%d' % error.token.line_number - - error_code = '%04d' % error.code - if new_error: - error_code = 'New Error ' + error_code - return '%s:%s:(%s) %s' % (filename, line, error_code, error.message) - - -def GetErrorOutput(error, new_error=False): - """Get a output line for an error in regular format.""" - - line = '' - if error.token: - line = 'Line %d, ' % error.token.line_number - - code = 'E:%04d' % error.code - - error_message = error.message - if new_error: - error_message = 'New Error ' + error_message - - return '%s%s: %s' % (line, code, error.message)
diff --git a/third_party/closure_linter/closure_linter/common/filetestcase.py b/third_party/closure_linter/closure_linter/common/filetestcase.py deleted file mode 100755 index 7cd83cd1..0000000 --- a/third_party/closure_linter/closure_linter/common/filetestcase.py +++ /dev/null
@@ -1,115 +0,0 @@ -#!/usr/bin/env python -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Test case that runs a checker on a file, matching errors against annotations. - -Runs the given checker on the given file, accumulating all errors. The list -of errors is then matched against those annotated in the file. Based heavily -on devtools/javascript/gpylint/full_test.py. -""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -import re - -import gflags as flags -import unittest as googletest -from closure_linter.common import erroraccumulator - - -class AnnotatedFileTestCase(googletest.TestCase): - """Test case to run a linter against a single file.""" - - # Matches an all caps letters + underscores error identifer - _MESSAGE = {'msg': '[A-Z][A-Z_]+'} - # Matches a //, followed by an optional line number with a +/-, followed by a - # list of message IDs. Used to extract expected messages from testdata files. - # TODO(robbyw): Generalize to use different commenting patterns. - _EXPECTED_RE = re.compile(r'\s*//\s*(?:(?P<line>[+-]?[0-9]+):)?' - r'\s*(?P<msgs>%(msg)s(?:,\s*%(msg)s)*)' % _MESSAGE) - - def __init__(self, filename, lint_callable, converter): - """Create a single file lint test case. - - Args: - filename: Filename to test. - lint_callable: Callable that lints a file. This is usually runner.Run(). - converter: Function taking an error string and returning an error code. - """ - - googletest.TestCase.__init__(self, 'runTest') - self._filename = filename - self._messages = [] - self._lint_callable = lint_callable - self._converter = converter - - def setUp(self): - flags.FLAGS.dot_on_next_line = True - - def tearDown(self): - flags.FLAGS.dot_on_next_line = False - - def shortDescription(self): - """Provides a description for the test.""" - return 'Run linter on %s' % self._filename - - def runTest(self): - """Runs the test.""" - try: - filename = self._filename - stream = open(filename) - except IOError as ex: - raise IOError('Could not find testdata resource for %s: %s' % - (self._filename, ex)) - - expected = self._GetExpectedMessages(stream) - got = self._ProcessFileAndGetMessages(filename) - self.assertEqual(expected, got) - - def _GetExpectedMessages(self, stream): - """Parse a file and get a sorted list of expected messages.""" - messages = [] - for i, line in enumerate(stream): - match = self._EXPECTED_RE.search(line) - if match: - line = match.group('line') - msg_ids = match.group('msgs') - if line is None: - line = i + 1 - elif line.startswith('+') or line.startswith('-'): - line = i + 1 + int(line) - else: - line = int(line) - for msg_id in msg_ids.split(','): - # Ignore a spurious message from the license preamble. - if msg_id != 'WITHOUT': - messages.append((line, self._converter(msg_id.strip()))) - stream.seek(0) - messages.sort() - return messages - - def _ProcessFileAndGetMessages(self, filename): - """Trap gjslint's output parse it to get messages added.""" - error_accumulator = erroraccumulator.ErrorAccumulator() - self._lint_callable(filename, error_accumulator) - - errors = error_accumulator.GetErrors() - - # Convert to expected tuple format. - - error_msgs = [(error.token.line_number, error.code) for error in errors] - error_msgs.sort() - return error_msgs
diff --git a/third_party/closure_linter/closure_linter/common/htmlutil.py b/third_party/closure_linter/closure_linter/common/htmlutil.py deleted file mode 100755 index 26d44c59..0000000 --- a/third_party/closure_linter/closure_linter/common/htmlutil.py +++ /dev/null
@@ -1,170 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Utilities for dealing with HTML.""" - -__author__ = ('robbyw@google.com (Robert Walker)') - -import cStringIO -import formatter -import htmllib -import HTMLParser -import re - - -class ScriptExtractor(htmllib.HTMLParser): - """Subclass of HTMLParser that extracts script contents from an HTML file. - - Also inserts appropriate blank lines so that line numbers in the extracted - code match the line numbers in the original HTML. - """ - - def __init__(self): - """Initialize a ScriptExtractor.""" - htmllib.HTMLParser.__init__(self, formatter.NullFormatter()) - self._in_script = False - self._text = '' - - def start_script(self, attrs): - """Internal handler for the start of a script tag. - - Args: - attrs: The attributes of the script tag, as a list of tuples. - """ - for attribute in attrs: - if attribute[0].lower() == 'src': - # Skip script tags with a src specified. - return - self._in_script = True - - def end_script(self): - """Internal handler for the end of a script tag.""" - self._in_script = False - - def handle_data(self, data): - """Internal handler for character data. - - Args: - data: The character data from the HTML file. - """ - if self._in_script: - # If the last line contains whitespace only, i.e. is just there to - # properly align a </script> tag, strip the whitespace. - if data.rstrip(' \t') != data.rstrip(' \t\n\r\f'): - data = data.rstrip(' \t') - self._text += data - else: - self._AppendNewlines(data) - - def handle_comment(self, data): - """Internal handler for HTML comments. - - Args: - data: The text of the comment. - """ - self._AppendNewlines(data) - - def _AppendNewlines(self, data): - """Count the number of newlines in the given string and append them. - - This ensures line numbers are correct for reported errors. - - Args: - data: The data to count newlines in. - """ - # We append 'x' to both sides of the string to ensure that splitlines - # gives us an accurate count. - for i in xrange(len(('x' + data + 'x').splitlines()) - 1): - self._text += '\n' - - def GetScriptLines(self): - """Return the extracted script lines. - - Returns: - The extracted script lines as a list of strings. - """ - return self._text.splitlines() - - -def GetScriptLines(f): - """Extract script tag contents from the given HTML file. - - Args: - f: The HTML file. - - Returns: - Lines in the HTML file that are from script tags. - """ - extractor = ScriptExtractor() - - # The HTML parser chokes on text like Array.<!string>, so we patch - # that bug by replacing the < with < - escaping all text inside script - # tags would be better but it's a bit of a catch 22. - contents = f.read() - contents = re.sub(r'<([^\s\w/])', - lambda x: '<%s' % x.group(1), - contents) - - extractor.feed(contents) - extractor.close() - return extractor.GetScriptLines() - - -def StripTags(str): - """Returns the string with HTML tags stripped. - - Args: - str: An html string. - - Returns: - The html string with all tags stripped. If there was a parse error, returns - the text successfully parsed so far. - """ - # Brute force approach to stripping as much HTML as possible. If there is a - # parsing error, don't strip text before parse error position, and continue - # trying from there. - final_text = '' - finished = False - while not finished: - try: - strip = _HtmlStripper() - strip.feed(str) - strip.close() - str = strip.get_output() - final_text += str - finished = True - except HTMLParser.HTMLParseError, e: - final_text += str[:e.offset] - str = str[e.offset + 1:] - - return final_text - - -class _HtmlStripper(HTMLParser.HTMLParser): - """Simple class to strip tags from HTML. - - Does so by doing nothing when encountering tags, and appending character data - to a buffer when that is encountered. - """ - def __init__(self): - self.reset() - self.__output = cStringIO.StringIO() - - def handle_data(self, d): - self.__output.write(d) - - def get_output(self): - return self.__output.getvalue()
diff --git a/third_party/closure_linter/closure_linter/common/lintrunner.py b/third_party/closure_linter/closure_linter/common/lintrunner.py deleted file mode 100755 index 07842c7b..0000000 --- a/third_party/closure_linter/closure_linter/common/lintrunner.py +++ /dev/null
@@ -1,39 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Interface for a lint running wrapper.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - - -class LintRunner(object): - """Interface for a lint running wrapper.""" - - def __init__(self): - if self.__class__ == LintRunner: - raise NotImplementedError('class LintRunner is abstract') - - def Run(self, filenames, error_handler): - """Run a linter on the given filenames. - - Args: - filenames: The filenames to check - error_handler: An ErrorHandler object - - Returns: - The error handler, which may have been used to collect error info. - """
diff --git a/third_party/closure_linter/closure_linter/common/matcher.py b/third_party/closure_linter/closure_linter/common/matcher.py deleted file mode 100755 index 9b4402c..0000000 --- a/third_party/closure_linter/closure_linter/common/matcher.py +++ /dev/null
@@ -1,60 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Regular expression based JavaScript matcher classes.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -from closure_linter.common import position -from closure_linter.common import tokens - -# Shorthand -Token = tokens.Token -Position = position.Position - - -class Matcher(object): - """A token matcher. - - Specifies a pattern to match, the type of token it represents, what mode the - token changes to, and what mode the token applies to. - - Modes allow more advanced grammars to be incorporated, and are also necessary - to tokenize line by line. We can have different patterns apply to different - modes - i.e. looking for documentation while in comment mode. - - Attributes: - regex: The regular expression representing this matcher. - type: The type of token indicated by a successful match. - result_mode: The mode to move to after a successful match. - """ - - def __init__(self, regex, token_type, result_mode=None, line_start=False): - """Create a new matcher template. - - Args: - regex: The regular expression to match. - token_type: The type of token a successful match indicates. - result_mode: What mode to change to after a successful match. Defaults to - None, which means to not change the current mode. - line_start: Whether this matcher should only match string at the start - of a line. - """ - self.regex = regex - self.type = token_type - self.result_mode = result_mode - self.line_start = line_start
diff --git a/third_party/closure_linter/closure_linter/common/position.py b/third_party/closure_linter/closure_linter/common/position.py deleted file mode 100755 index cebf17ef3..0000000 --- a/third_party/closure_linter/closure_linter/common/position.py +++ /dev/null
@@ -1,126 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Classes to represent positions within strings.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - - -class Position(object): - """Object representing a segment of a string. - - Attributes: - start: The index in to the string where the segment starts. - length: The length of the string segment. - """ - - def __init__(self, start, length): - """Initialize the position object. - - Args: - start: The start index. - length: The number of characters to include. - """ - self.start = start - self.length = length - - def Get(self, string): - """Returns this range of the given string. - - Args: - string: The string to slice. - - Returns: - The string within the range specified by this object. - """ - return string[self.start:self.start + self.length] - - def Set(self, target, source): - """Sets this range within the target string to the source string. - - Args: - target: The target string. - source: The source string. - - Returns: - The resulting string - """ - return target[:self.start] + source + target[self.start + self.length:] - - def AtEnd(string): - """Create a Position representing the end of the given string. - - Args: - string: The string to represent the end of. - - Returns: - The created Position object. - """ - return Position(len(string), 0) - AtEnd = staticmethod(AtEnd) - - def IsAtEnd(self, string): - """Returns whether this position is at the end of the given string. - - Args: - string: The string to test for the end of. - - Returns: - Whether this position is at the end of the given string. - """ - return self.start == len(string) and self.length == 0 - - def AtBeginning(): - """Create a Position representing the beginning of any string. - - Returns: - The created Position object. - """ - return Position(0, 0) - AtBeginning = staticmethod(AtBeginning) - - def IsAtBeginning(self): - """Returns whether this position is at the beginning of any string. - - Returns: - Whether this position is at the beginning of any string. - """ - return self.start == 0 and self.length == 0 - - def All(string): - """Create a Position representing the entire string. - - Args: - string: The string to represent the entirety of. - - Returns: - The created Position object. - """ - return Position(0, len(string)) - All = staticmethod(All) - - def Index(index): - """Returns a Position object for the specified index. - - Args: - index: The index to select, inclusively. - - Returns: - The created Position object. - """ - return Position(index, 1) - Index = staticmethod(Index)
diff --git a/third_party/closure_linter/closure_linter/common/simplefileflags.py b/third_party/closure_linter/closure_linter/common/simplefileflags.py deleted file mode 100755 index 3402bef3..0000000 --- a/third_party/closure_linter/closure_linter/common/simplefileflags.py +++ /dev/null
@@ -1,190 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Determines the list of files to be checked from command line arguments.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -import glob -import os -import re - -import gflags as flags - - -FLAGS = flags.FLAGS - -flags.DEFINE_multistring( - 'recurse', - None, - 'Recurse in to the subdirectories of the given path', - short_name='r') -flags.DEFINE_list( - 'exclude_directories', - ('_demos'), - 'Exclude the specified directories (only applicable along with -r or ' - '--presubmit)', - short_name='e') -flags.DEFINE_list( - 'exclude_files', - ('deps.js'), - 'Exclude the specified files', - short_name='x') - - -def MatchesSuffixes(filename, suffixes): - """Returns whether the given filename matches one of the given suffixes. - - Args: - filename: Filename to check. - suffixes: Sequence of suffixes to check. - - Returns: - Whether the given filename matches one of the given suffixes. - """ - suffix = filename[filename.rfind('.'):] - return suffix in suffixes - - -def _GetUserSpecifiedFiles(argv, suffixes): - """Returns files to be linted, specified directly on the command line. - - Can handle the '*' wildcard in filenames, but no other wildcards. - - Args: - argv: Sequence of command line arguments. The second and following arguments - are assumed to be files that should be linted. - suffixes: Expected suffixes for the file type being checked. - - Returns: - A sequence of files to be linted. - """ - files = argv[1:] or [] - all_files = [] - lint_files = [] - - # Perform any necessary globs. - for f in files: - if f.find('*') != -1: - for result in glob.glob(f): - all_files.append(result) - else: - all_files.append(f) - - for f in all_files: - if MatchesSuffixes(f, suffixes): - lint_files.append(f) - return lint_files - - -def _GetRecursiveFiles(suffixes): - """Returns files to be checked specified by the --recurse flag. - - Args: - suffixes: Expected suffixes for the file type being checked. - - Returns: - A list of files to be checked. - """ - lint_files = [] - # Perform any request recursion - if FLAGS.recurse: - for start in FLAGS.recurse: - for root, subdirs, files in os.walk(start): - for f in files: - if MatchesSuffixes(f, suffixes): - lint_files.append(os.path.join(root, f)) - return lint_files - - -def GetAllSpecifiedFiles(argv, suffixes): - """Returns all files specified by the user on the commandline. - - Args: - argv: Sequence of command line arguments. The second and following arguments - are assumed to be files that should be linted. - suffixes: Expected suffixes for the file type - - Returns: - A list of all files specified directly or indirectly (via flags) on the - command line by the user. - """ - files = _GetUserSpecifiedFiles(argv, suffixes) - - if FLAGS.recurse: - files += _GetRecursiveFiles(suffixes) - - return FilterFiles(files) - - -def FilterFiles(files): - """Filters the list of files to be linted be removing any excluded files. - - Filters out files excluded using --exclude_files and --exclude_directories. - - Args: - files: Sequence of files that needs filtering. - - Returns: - Filtered list of files to be linted. - """ - num_files = len(files) - - ignore_dirs_regexs = [] - for ignore in FLAGS.exclude_directories: - ignore_dirs_regexs.append(re.compile(r'(^|[\\/])%s[\\/]' % ignore)) - - result_files = [] - for f in files: - add_file = True - for exclude in FLAGS.exclude_files: - if f.endswith('/' + exclude) or f == exclude: - add_file = False - break - for ignore in ignore_dirs_regexs: - if ignore.search(f): - # Break out of ignore loop so we don't add to - # filtered files. - add_file = False - break - if add_file: - # Convert everything to absolute paths so we can easily remove duplicates - # using a set. - result_files.append(os.path.abspath(f)) - - skipped = num_files - len(result_files) - if skipped: - print 'Skipping %d file(s).' % skipped - - return set(result_files) - - -def GetFileList(argv, file_type, suffixes): - """Parse the flags and return the list of files to check. - - Args: - argv: Sequence of command line arguments. - suffixes: Sequence of acceptable suffixes for the file type. - - Returns: - The list of files to check. - """ - return sorted(GetAllSpecifiedFiles(argv, suffixes)) - - -def IsEmptyArgumentList(argv): - return not (len(argv[1:]) or FLAGS.recurse)
diff --git a/third_party/closure_linter/closure_linter/common/tokenizer.py b/third_party/closure_linter/closure_linter/common/tokenizer.py deleted file mode 100755 index 9420ea3..0000000 --- a/third_party/closure_linter/closure_linter/common/tokenizer.py +++ /dev/null
@@ -1,185 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Regular expression based lexer.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -from closure_linter.common import tokens - -# Shorthand -Type = tokens.TokenType - - -class Tokenizer(object): - """General purpose tokenizer. - - Attributes: - mode: The latest mode of the tokenizer. This allows patterns to distinguish - if they are mid-comment, mid-parameter list, etc. - matchers: Dictionary of modes to sequences of matchers that define the - patterns to check at any given time. - default_types: Dictionary of modes to types, defining what type to give - non-matched text when in the given mode. Defaults to Type.NORMAL. - """ - - def __init__(self, starting_mode, matchers, default_types): - """Initialize the tokenizer. - - Args: - starting_mode: Mode to start in. - matchers: Dictionary of modes to sequences of matchers that defines the - patterns to check at any given time. - default_types: Dictionary of modes to types, defining what type to give - non-matched text when in the given mode. Defaults to Type.NORMAL. - """ - self.__starting_mode = starting_mode - self.matchers = matchers - self.default_types = default_types - - def TokenizeFile(self, file): - """Tokenizes the given file. - - Args: - file: An iterable that yields one line of the file at a time. - - Returns: - The first token in the file - """ - # The current mode. - self.mode = self.__starting_mode - # The first token in the stream. - self.__first_token = None - # The last token added to the token stream. - self.__last_token = None - # The current line number. - self.__line_number = 0 - - for line in file: - self.__line_number += 1 - self.__TokenizeLine(line) - - return self.__first_token - - def _CreateToken(self, string, token_type, line, line_number, values=None): - """Creates a new Token object (or subclass). - - Args: - string: The string of input the token represents. - token_type: The type of token. - line: The text of the line this token is in. - line_number: The line number of the token. - values: A dict of named values within the token. For instance, a - function declaration may have a value called 'name' which captures the - name of the function. - - Returns: - The newly created Token object. - """ - return tokens.Token(string, token_type, line, line_number, values, - line_number) - - def __TokenizeLine(self, line): - """Tokenizes the given line. - - Args: - line: The contents of the line. - """ - string = line.rstrip('\n\r\f') - line_number = self.__line_number - self.__start_index = 0 - - if not string: - self.__AddToken(self._CreateToken('', Type.BLANK_LINE, line, line_number)) - return - - normal_token = '' - index = 0 - while index < len(string): - for matcher in self.matchers[self.mode]: - if matcher.line_start and index > 0: - continue - - match = matcher.regex.match(string, index) - - if match: - if normal_token: - self.__AddToken( - self.__CreateNormalToken(self.mode, normal_token, line, - line_number)) - normal_token = '' - - # Add the match. - self.__AddToken(self._CreateToken(match.group(), matcher.type, line, - line_number, match.groupdict())) - - # Change the mode to the correct one for after this match. - self.mode = matcher.result_mode or self.mode - - # Shorten the string to be matched. - index = match.end() - - break - - else: - # If the for loop finishes naturally (i.e. no matches) we just add the - # first character to the string of consecutive non match characters. - # These will constitute a NORMAL token. - if string: - normal_token += string[index:index + 1] - index += 1 - - if normal_token: - self.__AddToken( - self.__CreateNormalToken(self.mode, normal_token, line, line_number)) - - def __CreateNormalToken(self, mode, string, line, line_number): - """Creates a normal token. - - Args: - mode: The current mode. - string: The string to tokenize. - line: The line of text. - line_number: The line number within the file. - - Returns: - A Token object, of the default type for the current mode. - """ - type = Type.NORMAL - if mode in self.default_types: - type = self.default_types[mode] - return self._CreateToken(string, type, line, line_number) - - def __AddToken(self, token): - """Add the given token to the token stream. - - Args: - token: The token to add. - """ - # Store the first token, or point the previous token to this one. - if not self.__first_token: - self.__first_token = token - else: - self.__last_token.next = token - - # Establish the doubly linked list - token.previous = self.__last_token - self.__last_token = token - - # Compute the character indices - token.start_index = self.__start_index - self.__start_index += token.length
diff --git a/third_party/closure_linter/closure_linter/common/tokens.py b/third_party/closure_linter/closure_linter/common/tokens.py deleted file mode 100755 index 4703998..0000000 --- a/third_party/closure_linter/closure_linter/common/tokens.py +++ /dev/null
@@ -1,145 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Classes to represent tokens and positions within them.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - - -class TokenType(object): - """Token types common to all languages.""" - NORMAL = 'normal' - WHITESPACE = 'whitespace' - BLANK_LINE = 'blank line' - - -class Token(object): - """Token class for intelligent text splitting. - - The token class represents a string of characters and an identifying type. - - Attributes: - type: The type of token. - string: The characters the token comprises. - length: The length of the token. - line: The text of the line the token is found in. - line_number: The number of the line the token is found in. - values: Dictionary of values returned from the tokens regex match. - previous: The token before this one. - next: The token after this one. - start_index: The character index in the line where this token starts. - attached_object: Object containing more information about this token. - metadata: Object containing metadata about this token. Must be added by - a separate metadata pass. - """ - - def __init__(self, string, token_type, line, line_number, values=None, - orig_line_number=None): - """Creates a new Token object. - - Args: - string: The string of input the token contains. - token_type: The type of token. - line: The text of the line this token is in. - line_number: The line number of the token. - values: A dict of named values within the token. For instance, a - function declaration may have a value called 'name' which captures the - name of the function. - orig_line_number: The line number of the original file this token comes - from. This should be only set during the tokenization process. For newly - created error fix tokens after that, it should be None. - """ - self.type = token_type - self.string = string - self.length = len(string) - self.line = line - self.line_number = line_number - self.orig_line_number = orig_line_number - self.values = values - self.is_deleted = False - - # These parts can only be computed when the file is fully tokenized - self.previous = None - self.next = None - self.start_index = None - - # This part is set in statetracker.py - # TODO(robbyw): Wrap this in to metadata - self.attached_object = None - - # This part is set in *metadatapass.py - self.metadata = None - - def IsFirstInLine(self): - """Tests if this token is the first token in its line. - - Returns: - Whether the token is the first token in its line. - """ - return not self.previous or self.previous.line_number != self.line_number - - def IsLastInLine(self): - """Tests if this token is the last token in its line. - - Returns: - Whether the token is the last token in its line. - """ - return not self.next or self.next.line_number != self.line_number - - def IsType(self, token_type): - """Tests if this token is of the given type. - - Args: - token_type: The type to test for. - - Returns: - True if the type of this token matches the type passed in. - """ - return self.type == token_type - - def IsAnyType(self, *token_types): - """Tests if this token is any of the given types. - - Args: - token_types: The types to check. Also accepts a single array. - - Returns: - True if the type of this token is any of the types passed in. - """ - if not isinstance(token_types[0], basestring): - return self.type in token_types[0] - else: - return self.type in token_types - - def __repr__(self): - return '<Token: %s, "%s", %r, %d, %r>' % (self.type, self.string, - self.values, self.line_number, - self.metadata) - - def __iter__(self): - """Returns a token iterator.""" - node = self - while node: - yield node - node = node.next - - def __reversed__(self): - """Returns a reverse-direction token iterator.""" - node = self - while node: - yield node - node = node.previous
diff --git a/third_party/closure_linter/closure_linter/common/tokens_test.py b/third_party/closure_linter/closure_linter/common/tokens_test.py deleted file mode 100644 index 01ec89d0..0000000 --- a/third_party/closure_linter/closure_linter/common/tokens_test.py +++ /dev/null
@@ -1,113 +0,0 @@ -#!/usr/bin/env python -# Copyright 2011 The Closure Linter Authors. All Rights Reserved. -# -# 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. - - -__author__ = 'nnaze@google.com (Nathan Naze)' - -import unittest as googletest -from closure_linter.common import tokens - - -def _CreateDummyToken(): - return tokens.Token('foo', None, 1, 1) - - -def _CreateDummyTokens(count): - dummy_tokens = [] - for _ in xrange(count): - dummy_tokens.append(_CreateDummyToken()) - return dummy_tokens - - -def _SetTokensAsNeighbors(neighbor_tokens): - for i in xrange(len(neighbor_tokens)): - prev_index = i - 1 - next_index = i + 1 - - if prev_index >= 0: - neighbor_tokens[i].previous = neighbor_tokens[prev_index] - - if next_index < len(neighbor_tokens): - neighbor_tokens[i].next = neighbor_tokens[next_index] - - -class TokensTest(googletest.TestCase): - - def testIsFirstInLine(self): - - # First token in file (has no previous). - self.assertTrue(_CreateDummyToken().IsFirstInLine()) - - a, b = _CreateDummyTokens(2) - _SetTokensAsNeighbors([a, b]) - - # Tokens on same line - a.line_number = 30 - b.line_number = 30 - - self.assertFalse(b.IsFirstInLine()) - - # Tokens on different lines - b.line_number = 31 - self.assertTrue(b.IsFirstInLine()) - - def testIsLastInLine(self): - # Last token in file (has no next). - self.assertTrue(_CreateDummyToken().IsLastInLine()) - - a, b = _CreateDummyTokens(2) - _SetTokensAsNeighbors([a, b]) - - # Tokens on same line - a.line_number = 30 - b.line_number = 30 - self.assertFalse(a.IsLastInLine()) - - b.line_number = 31 - self.assertTrue(a.IsLastInLine()) - - def testIsType(self): - a = tokens.Token('foo', 'fakeType1', 1, 1) - self.assertTrue(a.IsType('fakeType1')) - self.assertFalse(a.IsType('fakeType2')) - - def testIsAnyType(self): - a = tokens.Token('foo', 'fakeType1', 1, 1) - self.assertTrue(a.IsAnyType(['fakeType1', 'fakeType2'])) - self.assertFalse(a.IsAnyType(['fakeType3', 'fakeType4'])) - - def testRepr(self): - a = tokens.Token('foo', 'fakeType1', 1, 1) - self.assertEquals('<Token: fakeType1, "foo", None, 1, None>', str(a)) - - def testIter(self): - dummy_tokens = _CreateDummyTokens(5) - _SetTokensAsNeighbors(dummy_tokens) - a, b, c, d, e = dummy_tokens - - i = iter(a) - self.assertListEqual([a, b, c, d, e], list(i)) - - def testReverseIter(self): - dummy_tokens = _CreateDummyTokens(5) - _SetTokensAsNeighbors(dummy_tokens) - a, b, c, d, e = dummy_tokens - - ri = reversed(e) - self.assertListEqual([e, d, c, b, a], list(ri)) - - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/ecmalintrules.py b/third_party/closure_linter/closure_linter/ecmalintrules.py deleted file mode 100755 index 80331c25..0000000 --- a/third_party/closure_linter/closure_linter/ecmalintrules.py +++ /dev/null
@@ -1,865 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Core methods for checking EcmaScript files for common style guide violations. -""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)', - 'jacobr@google.com (Jacob Richman)') - -import re - -import gflags as flags - -from closure_linter import checkerbase -from closure_linter import ecmametadatapass -from closure_linter import error_check -from closure_linter import errorrules -from closure_linter import errors -from closure_linter import indentation -from closure_linter import javascripttokenizer -from closure_linter import javascripttokens -from closure_linter import statetracker -from closure_linter import tokenutil -from closure_linter.common import error -from closure_linter.common import position - - -FLAGS = flags.FLAGS -flags.DEFINE_list('custom_jsdoc_tags', '', 'Extra jsdoc tags to allow') -# TODO(user): When flipping this to True, remove logic from unit tests -# that overrides this flag. -flags.DEFINE_boolean('dot_on_next_line', False, 'Require dots to be' - 'placed on the next line for wrapped expressions') - -flags.DEFINE_boolean('check_trailing_comma', False, 'Check trailing commas' - ' (ES3, not needed from ES5 onwards)') - -# TODO(robbyw): Check for extra parens on return statements -# TODO(robbyw): Check for 0px in strings -# TODO(robbyw): Ensure inline jsDoc is in {} -# TODO(robbyw): Check for valid JS types in parameter docs - -# Shorthand -Context = ecmametadatapass.EcmaContext -Error = error.Error -Modes = javascripttokenizer.JavaScriptModes -Position = position.Position -Rule = error_check.Rule -Type = javascripttokens.JavaScriptTokenType - - -class EcmaScriptLintRules(checkerbase.LintRulesBase): - """EmcaScript lint style checking rules. - - Can be used to find common style errors in JavaScript, ActionScript and other - Ecma like scripting languages. Style checkers for Ecma scripting languages - should inherit from this style checker. - Please do not add any state to EcmaScriptLintRules or to any subclasses. - - All state should be added to the StateTracker subclass used for a particular - language. - """ - - # It will be initialized in constructor so the flags are initialized. - max_line_length = -1 - - # Static constants. - MISSING_PARAMETER_SPACE = re.compile(r',\S') - - EXTRA_SPACE = re.compile(r'(\(\s|\s\))') - - ENDS_WITH_SPACE = re.compile(r'\s$') - - ILLEGAL_TAB = re.compile(r'\t') - - # Regex used to split up complex types to check for invalid use of ? and |. - TYPE_SPLIT = re.compile(r'[,<>()]') - - # Regex for form of author lines after the @author tag. - AUTHOR_SPEC = re.compile(r'(\s*)[^\s]+@[^(\s]+(\s*)\(.+\)') - - # Acceptable tokens to remove for line too long testing. - LONG_LINE_IGNORE = frozenset( - ['*', '//', '@see'] + - ['@%s' % tag for tag in statetracker.DocFlag.HAS_TYPE]) - - JSDOC_FLAGS_DESCRIPTION_NOT_REQUIRED = frozenset([ - '@fileoverview', '@param', '@return', '@returns']) - - def __init__(self): - """Initialize this lint rule object.""" - checkerbase.LintRulesBase.__init__(self) - if EcmaScriptLintRules.max_line_length == -1: - EcmaScriptLintRules.max_line_length = errorrules.GetMaxLineLength() - - def Initialize(self, checker, limited_doc_checks, is_html): - """Initialize this lint rule object before parsing a new file.""" - checkerbase.LintRulesBase.Initialize(self, checker, limited_doc_checks, - is_html) - self._indentation = indentation.IndentationRules() - - def HandleMissingParameterDoc(self, token, param_name): - """Handle errors associated with a parameter missing a @param tag.""" - raise TypeError('Abstract method HandleMissingParameterDoc not implemented') - - def _CheckLineLength(self, last_token, state): - """Checks whether the line is too long. - - Args: - last_token: The last token in the line. - state: parser_state object that indicates the current state in the page - """ - # Start from the last token so that we have the flag object attached to - # and DOC_FLAG tokens. - line_number = last_token.line_number - token = last_token - - # Build a representation of the string where spaces indicate potential - # line-break locations. - line = [] - while token and token.line_number == line_number: - if state.IsTypeToken(token): - line.insert(0, 'x' * len(token.string)) - elif token.type in (Type.IDENTIFIER, Type.OPERATOR): - # Dots are acceptable places to wrap (may be tokenized as identifiers). - line.insert(0, token.string.replace('.', ' ')) - else: - line.insert(0, token.string) - token = token.previous - - line = ''.join(line) - line = line.rstrip('\n\r\f') - try: - length = len(unicode(line, 'utf-8')) - except (LookupError, UnicodeDecodeError): - # Unknown encoding. The line length may be wrong, as was originally the - # case for utf-8 (see bug 1735846). For now just accept the default - # length, but as we find problems we can either add test for other - # possible encodings or return without an error to protect against - # false positives at the cost of more false negatives. - length = len(line) - - if length > EcmaScriptLintRules.max_line_length: - - # If the line matches one of the exceptions, then it's ok. - for long_line_regexp in self.GetLongLineExceptions(): - if long_line_regexp.match(last_token.line): - return - - # If the line consists of only one "word", or multiple words but all - # except one are ignoreable, then it's ok. - parts = set(line.split()) - - # We allow two "words" (type and name) when the line contains @param - max_parts = 1 - if '@param' in parts: - max_parts = 2 - - # Custom tags like @requires may have url like descriptions, so ignore - # the tag, similar to how we handle @see. - custom_tags = set(['@%s' % f for f in FLAGS.custom_jsdoc_tags]) - if (len(parts.difference(self.LONG_LINE_IGNORE | custom_tags)) - > max_parts): - self._HandleError( - errors.LINE_TOO_LONG, - 'Line too long (%d characters).' % len(line), last_token) - - def _CheckJsDocType(self, token, js_type): - """Checks the given type for style errors. - - Args: - token: The DOC_FLAG token for the flag whose type to check. - js_type: The flag's typeannotation.TypeAnnotation instance. - """ - if not js_type: return - - if js_type.type_group and len(js_type.sub_types) == 2: - identifiers = [t.identifier for t in js_type.sub_types] - if 'null' in identifiers: - # Don't warn if the identifier is a template type (e.g. {TYPE|null}. - if not identifiers[0].isupper() and not identifiers[1].isupper(): - self._HandleError( - errors.JSDOC_PREFER_QUESTION_TO_PIPE_NULL, - 'Prefer "?Type" to "Type|null": "%s"' % js_type, token) - - # TODO(user): We should report an error for wrong usage of '?' and '|' - # e.g. {?number|string|null} etc. - - for sub_type in js_type.IterTypes(): - self._CheckJsDocType(token, sub_type) - - def _CheckForMissingSpaceBeforeToken(self, token): - """Checks for a missing space at the beginning of a token. - - Reports a MISSING_SPACE error if the token does not begin with a space or - the previous token doesn't end with a space and the previous token is on the - same line as the token. - - Args: - token: The token being checked - """ - # TODO(user): Check if too many spaces? - if (len(token.string) == len(token.string.lstrip()) and - token.previous and token.line_number == token.previous.line_number and - len(token.previous.string) - len(token.previous.string.rstrip()) == 0): - self._HandleError( - errors.MISSING_SPACE, - 'Missing space before "%s"' % token.string, - token, - position=Position.AtBeginning()) - - def _CheckOperator(self, token): - """Checks an operator for spacing and line style. - - Args: - token: The operator token. - """ - last_code = token.metadata.last_code - - if not self._ExpectSpaceBeforeOperator(token): - if (token.previous and token.previous.type == Type.WHITESPACE and - last_code and last_code.type in (Type.NORMAL, Type.IDENTIFIER) and - last_code.line_number == token.line_number): - self._HandleError( - errors.EXTRA_SPACE, 'Extra space before "%s"' % token.string, - token.previous, position=Position.All(token.previous.string)) - - elif (token.previous and - not token.previous.IsComment() and - not tokenutil.IsDot(token) and - token.previous.type in Type.EXPRESSION_ENDER_TYPES): - self._HandleError(errors.MISSING_SPACE, - 'Missing space before "%s"' % token.string, token, - position=Position.AtBeginning()) - - # Check wrapping of operators. - next_code = tokenutil.GetNextCodeToken(token) - - is_dot = tokenutil.IsDot(token) - wrapped_before = last_code and last_code.line_number != token.line_number - wrapped_after = next_code and next_code.line_number != token.line_number - - if FLAGS.dot_on_next_line and is_dot and wrapped_after: - self._HandleError( - errors.LINE_ENDS_WITH_DOT, - '"." must go on the following line', - token) - if (not is_dot and wrapped_before and - not token.metadata.IsUnaryOperator()): - self._HandleError( - errors.LINE_STARTS_WITH_OPERATOR, - 'Binary operator must go on previous line "%s"' % token.string, - token) - - def _IsLabel(self, token): - # A ':' token is considered part of a label if it occurs in a case - # statement, a plain label, or an object literal, i.e. is not part of a - # ternary. - - return (token.string == ':' and - token.metadata.context.type in (Context.LITERAL_ELEMENT, - Context.CASE_BLOCK, - Context.STATEMENT)) - - def _ExpectSpaceBeforeOperator(self, token): - """Returns whether a space should appear before the given operator token. - - Args: - token: The operator token. - - Returns: - Whether there should be a space before the token. - """ - if token.string == ',' or token.metadata.IsUnaryPostOperator(): - return False - - if tokenutil.IsDot(token): - return False - - # Colons should appear in labels, object literals, the case of a switch - # statement, and ternary operator. Only want a space in the case of the - # ternary operator. - if self._IsLabel(token): - return False - - if token.metadata.IsUnaryOperator() and token.IsFirstInLine(): - return False - - return True - - def CheckToken(self, token, state): - """Checks a token, given the current parser_state, for warnings and errors. - - Args: - token: The current token under consideration - state: parser_state object that indicates the current state in the page - """ - # Store some convenience variables - first_in_line = token.IsFirstInLine() - last_in_line = token.IsLastInLine() - last_non_space_token = state.GetLastNonSpaceToken() - - token_type = token.type - - # Process the line change. - if not self._is_html and error_check.ShouldCheck(Rule.INDENTATION): - # TODO(robbyw): Support checking indentation in HTML files. - indentation_errors = self._indentation.CheckToken(token, state) - for indentation_error in indentation_errors: - self._HandleError(*indentation_error) - - if last_in_line: - self._CheckLineLength(token, state) - - if token_type == Type.PARAMETERS: - # Find missing spaces in parameter lists. - if self.MISSING_PARAMETER_SPACE.search(token.string): - fix_data = ', '.join([s.strip() for s in token.string.split(',')]) - self._HandleError(errors.MISSING_SPACE, 'Missing space after ","', - token, position=None, fix_data=fix_data.strip()) - - # Find extra spaces at the beginning of parameter lists. Make sure - # we aren't at the beginning of a continuing multi-line list. - if not first_in_line: - space_count = len(token.string) - len(token.string.lstrip()) - if space_count: - self._HandleError(errors.EXTRA_SPACE, 'Extra space after "("', - token, position=Position(0, space_count)) - - elif (token_type == Type.START_BLOCK and - token.metadata.context.type == Context.BLOCK): - self._CheckForMissingSpaceBeforeToken(token) - - elif token_type == Type.END_BLOCK: - last_code = token.metadata.last_code - - if FLAGS.check_trailing_comma: - if last_code.IsOperator(','): - self._HandleError( - errors.COMMA_AT_END_OF_LITERAL, - 'Illegal comma at end of object literal', last_code, - position=Position.All(last_code.string)) - - if state.InFunction() and state.IsFunctionClose(): - if state.InTopLevelFunction(): - # A semicolons should not be included at the end of a function - # declaration. - if not state.InAssignedFunction(): - if not last_in_line and token.next.type == Type.SEMICOLON: - self._HandleError( - errors.ILLEGAL_SEMICOLON_AFTER_FUNCTION, - 'Illegal semicolon after function declaration', - token.next, position=Position.All(token.next.string)) - - # A semicolon should be included at the end of a function expression - # that is not immediately called or used by a dot operator. - if (state.InAssignedFunction() and token.next - and token.next.type != Type.SEMICOLON): - next_token = tokenutil.GetNextCodeToken(token) - is_immediately_used = next_token and ( - next_token.type == Type.START_PAREN or - tokenutil.IsDot(next_token)) - if not is_immediately_used: - self._HandleError( - errors.MISSING_SEMICOLON_AFTER_FUNCTION, - 'Missing semicolon after function assigned to a variable', - token, position=Position.AtEnd(token.string)) - - if state.InInterfaceMethod() and last_code.type != Type.START_BLOCK: - self._HandleError(errors.INTERFACE_METHOD_CANNOT_HAVE_CODE, - 'Interface methods cannot contain code', last_code) - - elif (state.IsBlockClose() and - token.next and token.next.type == Type.SEMICOLON): - if (last_code.metadata.context.parent.type != Context.OBJECT_LITERAL - and last_code.metadata.context.type != Context.OBJECT_LITERAL): - self._HandleError( - errors.REDUNDANT_SEMICOLON, - 'No semicolon is required to end a code block', - token.next, position=Position.All(token.next.string)) - - elif token_type == Type.SEMICOLON: - if token.previous and token.previous.type == Type.WHITESPACE: - self._HandleError( - errors.EXTRA_SPACE, 'Extra space before ";"', - token.previous, position=Position.All(token.previous.string)) - - if token.next and token.next.line_number == token.line_number: - if token.metadata.context.type != Context.FOR_GROUP_BLOCK: - # TODO(robbyw): Error about no multi-statement lines. - pass - - elif token.next.type not in ( - Type.WHITESPACE, Type.SEMICOLON, Type.END_PAREN): - self._HandleError( - errors.MISSING_SPACE, - 'Missing space after ";" in for statement', - token.next, - position=Position.AtBeginning()) - - last_code = token.metadata.last_code - if last_code and last_code.type == Type.SEMICOLON: - # Allow a single double semi colon in for loops for cases like: - # for (;;) { }. - # NOTE(user): This is not a perfect check, and will not throw an error - # for cases like: for (var i = 0;; i < n; i++) {}, but then your code - # probably won't work either. - for_token = tokenutil.CustomSearch( - last_code, - lambda token: token.type == Type.KEYWORD and token.string == 'for', - end_func=lambda token: token.type == Type.SEMICOLON, - distance=None, - reverse=True) - - if not for_token: - self._HandleError(errors.REDUNDANT_SEMICOLON, 'Redundant semicolon', - token, position=Position.All(token.string)) - - elif token_type == Type.START_PAREN: - # Ensure that opening parentheses have a space before any keyword - # that is not being invoked like a member function. - if (token.previous and token.previous.type == Type.KEYWORD and - (not token.previous.metadata or - not token.previous.metadata.last_code or - not token.previous.metadata.last_code.string or - token.previous.metadata.last_code.string[-1:] != '.')): - self._HandleError(errors.MISSING_SPACE, 'Missing space before "("', - token, position=Position.AtBeginning()) - elif token.previous and token.previous.type == Type.WHITESPACE: - before_space = token.previous.previous - # Ensure that there is no extra space before a function invocation, - # even if the function being invoked happens to be a keyword. - if (before_space and before_space.line_number == token.line_number and - before_space.type == Type.IDENTIFIER or - (before_space.type == Type.KEYWORD and before_space.metadata and - before_space.metadata.last_code and - before_space.metadata.last_code.string and - before_space.metadata.last_code.string[-1:] == '.')): - self._HandleError( - errors.EXTRA_SPACE, 'Extra space before "("', - token.previous, position=Position.All(token.previous.string)) - - elif token_type == Type.START_BRACKET: - self._HandleStartBracket(token, last_non_space_token) - elif token_type in (Type.END_PAREN, Type.END_BRACKET): - # Ensure there is no space before closing parentheses, except when - # it's in a for statement with an omitted section, or when it's at the - # beginning of a line. - - last_code = token.metadata.last_code - if FLAGS.check_trailing_comma and token_type == Type.END_BRACKET: - if last_code.IsOperator(','): - self._HandleError( - errors.COMMA_AT_END_OF_LITERAL, - 'Illegal comma at end of array literal', last_code, - position=Position.All(last_code.string)) - - if (token.previous and token.previous.type == Type.WHITESPACE and - not token.previous.IsFirstInLine() and - not (last_non_space_token and last_non_space_token.line_number == - token.line_number and - last_non_space_token.type == Type.SEMICOLON)): - self._HandleError( - errors.EXTRA_SPACE, 'Extra space before "%s"' % - token.string, token.previous, - position=Position.All(token.previous.string)) - - elif token_type == Type.WHITESPACE: - if self.ILLEGAL_TAB.search(token.string): - if token.IsFirstInLine(): - if token.next: - self._HandleError( - errors.ILLEGAL_TAB, - 'Illegal tab in whitespace before "%s"' % token.next.string, - token, position=Position.All(token.string)) - else: - self._HandleError( - errors.ILLEGAL_TAB, - 'Illegal tab in whitespace', - token, position=Position.All(token.string)) - else: - self._HandleError( - errors.ILLEGAL_TAB, - 'Illegal tab in whitespace after "%s"' % token.previous.string, - token, position=Position.All(token.string)) - - # Check whitespace length if it's not the first token of the line and - # if it's not immediately before a comment. - if last_in_line: - # Check for extra whitespace at the end of a line. - self._HandleError(errors.EXTRA_SPACE, 'Extra space at end of line', - token, position=Position.All(token.string)) - elif not first_in_line and not token.next.IsComment(): - if token.length > 1: - self._HandleError( - errors.EXTRA_SPACE, 'Extra space after "%s"' % - token.previous.string, token, - position=Position(1, len(token.string) - 1)) - - elif token_type == Type.OPERATOR: - self._CheckOperator(token) - elif token_type == Type.DOC_FLAG: - flag = token.attached_object - - if flag.flag_type == 'bug': - # TODO(robbyw): Check for exactly 1 space on the left. - string = token.next.string.lstrip() - string = string.split(' ', 1)[0] - - if not string.isdigit(): - self._HandleError(errors.NO_BUG_NUMBER_AFTER_BUG_TAG, - '@bug should be followed by a bug number', token) - - elif flag.flag_type == 'suppress': - if flag.type is None: - # A syntactically invalid suppress tag will get tokenized as a normal - # flag, indicating an error. - self._HandleError( - errors.INCORRECT_SUPPRESS_SYNTAX, - 'Invalid suppress syntax: should be @suppress {errortype}. ' - 'Spaces matter.', token) - else: - for suppress_type in flag.jstype.IterIdentifiers(): - if suppress_type not in state.GetDocFlag().SUPPRESS_TYPES: - self._HandleError( - errors.INVALID_SUPPRESS_TYPE, - 'Invalid suppression type: %s' % suppress_type, token) - - elif (error_check.ShouldCheck(Rule.WELL_FORMED_AUTHOR) and - flag.flag_type == 'author'): - # TODO(user): In non strict mode check the author tag for as much as - # it exists, though the full form checked below isn't required. - string = token.next.string - result = self.AUTHOR_SPEC.match(string) - if not result: - self._HandleError(errors.INVALID_AUTHOR_TAG_DESCRIPTION, - 'Author tag line should be of the form: ' - '@author foo@somewhere.com (Your Name)', - token.next) - else: - # Check spacing between email address and name. Do this before - # checking earlier spacing so positions are easier to calculate for - # autofixing. - num_spaces = len(result.group(2)) - if num_spaces < 1: - self._HandleError(errors.MISSING_SPACE, - 'Missing space after email address', - token.next, position=Position(result.start(2), 0)) - elif num_spaces > 1: - self._HandleError( - errors.EXTRA_SPACE, 'Extra space after email address', - token.next, - position=Position(result.start(2) + 1, num_spaces - 1)) - - # Check for extra spaces before email address. Can't be too few, if - # not at least one we wouldn't match @author tag. - num_spaces = len(result.group(1)) - if num_spaces > 1: - self._HandleError(errors.EXTRA_SPACE, - 'Extra space before email address', - token.next, position=Position(1, num_spaces - 1)) - - elif (flag.flag_type in state.GetDocFlag().HAS_DESCRIPTION and - not self._limited_doc_checks): - if flag.flag_type == 'param': - if flag.name is None: - self._HandleError(errors.MISSING_JSDOC_PARAM_NAME, - 'Missing name in @param tag', token) - - if not flag.description or flag.description is None: - flag_name = token.type - if 'name' in token.values: - flag_name = '@' + token.values['name'] - - if flag_name not in self.JSDOC_FLAGS_DESCRIPTION_NOT_REQUIRED: - self._HandleError( - errors.MISSING_JSDOC_TAG_DESCRIPTION, - 'Missing description in %s tag' % flag_name, token) - else: - self._CheckForMissingSpaceBeforeToken(flag.description_start_token) - - if flag.HasType(): - if flag.type_start_token is not None: - self._CheckForMissingSpaceBeforeToken( - token.attached_object.type_start_token) - - if flag.jstype and not flag.jstype.IsEmpty(): - self._CheckJsDocType(token, flag.jstype) - - if error_check.ShouldCheck(Rule.BRACES_AROUND_TYPE) and ( - flag.type_start_token.type != Type.DOC_START_BRACE or - flag.type_end_token.type != Type.DOC_END_BRACE): - self._HandleError( - errors.MISSING_BRACES_AROUND_TYPE, - 'Type must always be surrounded by curly braces.', token) - - if token_type in (Type.DOC_FLAG, Type.DOC_INLINE_FLAG): - if (token.values['name'] not in state.GetDocFlag().LEGAL_DOC and - token.values['name'] not in FLAGS.custom_jsdoc_tags): - self._HandleError( - errors.INVALID_JSDOC_TAG, - 'Invalid JsDoc tag: %s' % token.values['name'], token) - - if (error_check.ShouldCheck(Rule.NO_BRACES_AROUND_INHERIT_DOC) and - token.values['name'] == 'inheritDoc' and - token_type == Type.DOC_INLINE_FLAG): - self._HandleError(errors.UNNECESSARY_BRACES_AROUND_INHERIT_DOC, - 'Unnecessary braces around @inheritDoc', - token) - - elif token_type == Type.SIMPLE_LVALUE: - identifier = token.values['identifier'] - - if ((not state.InFunction() or state.InConstructor()) and - state.InTopLevel() and not state.InObjectLiteralDescendant()): - jsdoc = state.GetDocComment() - if not state.HasDocComment(identifier): - # Only test for documentation on identifiers with .s in them to - # avoid checking things like simple variables. We don't require - # documenting assignments to .prototype itself (bug 1880803). - if (not state.InConstructor() and - identifier.find('.') != -1 and not - identifier.endswith('.prototype') and not - self._limited_doc_checks): - comment = state.GetLastComment() - if not (comment and comment.lower().count('jsdoc inherited')): - self._HandleError( - errors.MISSING_MEMBER_DOCUMENTATION, - "No docs found for member '%s'" % identifier, - token) - elif jsdoc and (not state.InConstructor() or - identifier.startswith('this.')): - # We are at the top level and the function/member is documented. - if identifier.endswith('_') and not identifier.endswith('__'): - # Can have a private class which inherits documentation from a - # public superclass. - # - # @inheritDoc is deprecated in favor of using @override, and they - if (jsdoc.HasFlag('override') and not jsdoc.HasFlag('constructor') - and ('accessControls' not in jsdoc.suppressions)): - self._HandleError( - errors.INVALID_OVERRIDE_PRIVATE, - '%s should not override a private member.' % identifier, - jsdoc.GetFlag('override').flag_token) - if (jsdoc.HasFlag('inheritDoc') and not jsdoc.HasFlag('constructor') - and ('accessControls' not in jsdoc.suppressions)): - self._HandleError( - errors.INVALID_INHERIT_DOC_PRIVATE, - '%s should not inherit from a private member.' % identifier, - jsdoc.GetFlag('inheritDoc').flag_token) - if (not jsdoc.HasFlag('private') and - ('underscore' not in jsdoc.suppressions) and not - ((jsdoc.HasFlag('inheritDoc') or jsdoc.HasFlag('override')) and - ('accessControls' in jsdoc.suppressions))): - self._HandleError( - errors.MISSING_PRIVATE, - 'Member "%s" must have @private JsDoc.' % - identifier, token) - if jsdoc.HasFlag('private') and 'underscore' in jsdoc.suppressions: - self._HandleError( - errors.UNNECESSARY_SUPPRESS, - '@suppress {underscore} is not necessary with @private', - jsdoc.suppressions['underscore']) - elif (jsdoc.HasFlag('private') and - not self.InExplicitlyTypedLanguage()): - # It is convention to hide public fields in some ECMA - # implementations from documentation using the @private tag. - self._HandleError( - errors.EXTRA_PRIVATE, - 'Member "%s" must not have @private JsDoc' % - identifier, token) - - # These flags are only legal on localizable message definitions; - # such variables always begin with the prefix MSG_. - if not identifier.startswith('MSG_') and '.MSG_' not in identifier: - for f in ('desc', 'hidden', 'meaning'): - if jsdoc.HasFlag(f): - self._HandleError( - errors.INVALID_USE_OF_DESC_TAG, - 'Member "%s" does not start with MSG_ and thus ' - 'should not have @%s JsDoc' % (identifier, f), - token) - - # Check for illegaly assigning live objects as prototype property values. - index = identifier.find('.prototype.') - # Ignore anything with additional .s after the prototype. - if index != -1 and identifier.find('.', index + 11) == -1: - equal_operator = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES) - next_code = tokenutil.SearchExcept(equal_operator, Type.NON_CODE_TYPES) - if next_code and ( - next_code.type in (Type.START_BRACKET, Type.START_BLOCK) or - next_code.IsOperator('new')): - self._HandleError( - errors.ILLEGAL_PROTOTYPE_MEMBER_VALUE, - 'Member %s cannot have a non-primitive value' % identifier, - token) - - elif token_type == Type.END_PARAMETERS: - # Find extra space at the end of parameter lists. We check the token - # prior to the current one when it is a closing paren. - if (token.previous and token.previous.type == Type.PARAMETERS - and self.ENDS_WITH_SPACE.search(token.previous.string)): - self._HandleError(errors.EXTRA_SPACE, 'Extra space before ")"', - token.previous) - - jsdoc = state.GetDocComment() - if state.GetFunction().is_interface: - if token.previous and token.previous.type == Type.PARAMETERS: - self._HandleError( - errors.INTERFACE_CONSTRUCTOR_CANNOT_HAVE_PARAMS, - 'Interface constructor cannot have parameters', - token.previous) - elif (state.InTopLevel() and jsdoc and not jsdoc.HasFlag('see') - and not jsdoc.InheritsDocumentation() - and not state.InObjectLiteralDescendant() and not - jsdoc.IsInvalidated()): - distance, edit = jsdoc.CompareParameters(state.GetParams()) - if distance: - params_iter = iter(state.GetParams()) - docs_iter = iter(jsdoc.ordered_params) - - for op in edit: - if op == 'I': - # Insertion. - # Parsing doc comments is the same for all languages - # but some languages care about parameters that don't have - # doc comments and some languages don't care. - # Languages that don't allow variables to by typed such as - # JavaScript care but languages such as ActionScript or Java - # that allow variables to be typed don't care. - if not self._limited_doc_checks: - self.HandleMissingParameterDoc(token, params_iter.next()) - - elif op == 'D': - # Deletion - self._HandleError(errors.EXTRA_PARAMETER_DOCUMENTATION, - 'Found docs for non-existing parameter: "%s"' % - docs_iter.next(), token) - elif op == 'S': - # Substitution - if not self._limited_doc_checks: - self._HandleError( - errors.WRONG_PARAMETER_DOCUMENTATION, - 'Parameter mismatch: got "%s", expected "%s"' % - (params_iter.next(), docs_iter.next()), token) - - else: - # Equality - just advance the iterators - params_iter.next() - docs_iter.next() - - elif token_type == Type.STRING_TEXT: - # If this is the first token after the start of the string, but it's at - # the end of a line, we know we have a multi-line string. - if token.previous.type in ( - Type.SINGLE_QUOTE_STRING_START, - Type.DOUBLE_QUOTE_STRING_START) and last_in_line: - self._HandleError(errors.MULTI_LINE_STRING, - 'Multi-line strings are not allowed', token) - - # This check is orthogonal to the ones above, and repeats some types, so - # it is a plain if and not an elif. - if token.type in Type.COMMENT_TYPES: - if self.ILLEGAL_TAB.search(token.string): - self._HandleError(errors.ILLEGAL_TAB, - 'Illegal tab in comment "%s"' % token.string, token) - - trimmed = token.string.rstrip() - if last_in_line and token.string != trimmed: - # Check for extra whitespace at the end of a line. - self._HandleError( - errors.EXTRA_SPACE, 'Extra space at end of line', token, - position=Position(len(trimmed), len(token.string) - len(trimmed))) - - # This check is also orthogonal since it is based on metadata. - if token.metadata.is_implied_semicolon: - self._HandleError(errors.MISSING_SEMICOLON, - 'Missing semicolon at end of line', token) - - def _HandleStartBracket(self, token, last_non_space_token): - """Handles a token that is an open bracket. - - Args: - token: The token to handle. - last_non_space_token: The last token that was not a space. - """ - if (not token.IsFirstInLine() and token.previous.type == Type.WHITESPACE and - last_non_space_token and - last_non_space_token.type in Type.EXPRESSION_ENDER_TYPES): - self._HandleError( - errors.EXTRA_SPACE, 'Extra space before "["', - token.previous, position=Position.All(token.previous.string)) - # If the [ token is the first token in a line we shouldn't complain - # about a missing space before [. This is because some Ecma script - # languages allow syntax like: - # [Annotation] - # class MyClass {...} - # So we don't want to blindly warn about missing spaces before [. - # In the the future, when rules for computing exactly how many spaces - # lines should be indented are added, then we can return errors for - # [ tokens that are improperly indented. - # For example: - # var someVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongVariableName = - # [a,b,c]; - # should trigger a proper indentation warning message as [ is not indented - # by four spaces. - elif (not token.IsFirstInLine() and token.previous and - token.previous.type not in ( - [Type.WHITESPACE, Type.START_PAREN, Type.START_BRACKET] + - Type.EXPRESSION_ENDER_TYPES)): - self._HandleError(errors.MISSING_SPACE, 'Missing space before "["', - token, position=Position.AtBeginning()) - - def Finalize(self, state): - """Perform all checks that need to occur after all lines are processed. - - Args: - state: State of the parser after parsing all tokens - - Raises: - TypeError: If not overridden. - """ - last_non_space_token = state.GetLastNonSpaceToken() - # Check last line for ending with newline. - if state.GetLastLine() and not ( - state.GetLastLine().isspace() or - state.GetLastLine().rstrip('\n\r\f') != state.GetLastLine()): - self._HandleError( - errors.FILE_MISSING_NEWLINE, - 'File does not end with new line. (%s)' % state.GetLastLine(), - last_non_space_token) - - try: - self._indentation.Finalize() - except Exception, e: - self._HandleError( - errors.FILE_DOES_NOT_PARSE, - str(e), - last_non_space_token) - - def GetLongLineExceptions(self): - """Gets a list of regexps for lines which can be longer than the limit. - - Returns: - A list of regexps, used as matches (rather than searches). - """ - return [] - - def InExplicitlyTypedLanguage(self): - """Returns whether this ecma implementation is explicitly typed.""" - return False
diff --git a/third_party/closure_linter/closure_linter/ecmametadatapass.py b/third_party/closure_linter/closure_linter/ecmametadatapass.py deleted file mode 100755 index 2036aa2..0000000 --- a/third_party/closure_linter/closure_linter/ecmametadatapass.py +++ /dev/null
@@ -1,575 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Metadata pass for annotating tokens in EcmaScript files.""" - -__author__ = ('robbyw@google.com (Robert Walker)') - -from closure_linter import javascripttokens -from closure_linter import tokenutil - - -TokenType = javascripttokens.JavaScriptTokenType - - -class ParseError(Exception): - """Exception indicating a parse error at the given token. - - Attributes: - token: The token where the parse error occurred. - """ - - def __init__(self, token, message=None): - """Initialize a parse error at the given token with an optional message. - - Args: - token: The token where the parse error occurred. - message: A message describing the parse error. - """ - Exception.__init__(self, message) - self.token = token - - -class EcmaContext(object): - """Context object for EcmaScript languages. - - Attributes: - type: The context type. - start_token: The token where this context starts. - end_token: The token where this context ends. - parent: The parent context. - """ - - # The root context. - ROOT = 'root' - - # A block of code. - BLOCK = 'block' - - # A pseudo-block of code for a given case or default section. - CASE_BLOCK = 'case_block' - - # Block of statements in a for loop's parentheses. - FOR_GROUP_BLOCK = 'for_block' - - # An implied block of code for 1 line if, while, and for statements - IMPLIED_BLOCK = 'implied_block' - - # An index in to an array or object. - INDEX = 'index' - - # An array literal in []. - ARRAY_LITERAL = 'array_literal' - - # An object literal in {}. - OBJECT_LITERAL = 'object_literal' - - # An individual element in an array or object literal. - LITERAL_ELEMENT = 'literal_element' - - # The portion of a ternary statement between ? and : - TERNARY_TRUE = 'ternary_true' - - # The portion of a ternary statment after : - TERNARY_FALSE = 'ternary_false' - - # The entire switch statment. This will contain a GROUP with the variable - # and a BLOCK with the code. - - # Since that BLOCK is not a normal block, it can not contain statements except - # for case and default. - SWITCH = 'switch' - - # A normal comment. - COMMENT = 'comment' - - # A JsDoc comment. - DOC = 'doc' - - # An individual statement. - STATEMENT = 'statement' - - # Code within parentheses. - GROUP = 'group' - - # Parameter names in a function declaration. - PARAMETERS = 'parameters' - - # A set of variable declarations appearing after the 'var' keyword. - VAR = 'var' - - # Context types that are blocks. - BLOCK_TYPES = frozenset([ - ROOT, BLOCK, CASE_BLOCK, FOR_GROUP_BLOCK, IMPLIED_BLOCK]) - - def __init__(self, context_type, start_token, parent=None): - """Initializes the context object. - - Args: - context_type: The context type. - start_token: The token where this context starts. - parent: The parent context. - - Attributes: - type: The context type. - start_token: The token where this context starts. - end_token: The token where this context ends. - parent: The parent context. - children: The child contexts of this context, in order. - """ - self.type = context_type - self.start_token = start_token - self.end_token = None - - self.parent = None - self.children = [] - - if parent: - parent.AddChild(self) - - def __repr__(self): - """Returns a string representation of the context object.""" - stack = [] - context = self - while context: - stack.append(context.type) - context = context.parent - return 'Context(%s)' % ' > '.join(stack) - - def AddChild(self, child): - """Adds a child to this context and sets child's parent to this context. - - Args: - child: A child EcmaContext. The child's parent will be set to this - context. - """ - - child.parent = self - - self.children.append(child) - self.children.sort(EcmaContext._CompareContexts) - - def GetRoot(self): - """Get the root context that contains this context, if any.""" - context = self - while context: - if context.type is EcmaContext.ROOT: - return context - context = context.parent - - @staticmethod - def _CompareContexts(context1, context2): - """Sorts contexts 1 and 2 by start token document position.""" - return tokenutil.Compare(context1.start_token, context2.start_token) - - -class EcmaMetaData(object): - """Token metadata for EcmaScript languages. - - Attributes: - last_code: The last code token to appear before this one. - context: The context this token appears in. - operator_type: The operator type, will be one of the *_OPERATOR constants - defined below. - aliased_symbol: The full symbol being identified, as a string (e.g. an - 'XhrIo' alias for 'goog.net.XhrIo'). Only applicable to identifier - tokens. This is set in aliaspass.py and is a best guess. - is_alias_definition: True if the symbol is part of an alias definition. - If so, these symbols won't be counted towards goog.requires/provides. - """ - - UNARY_OPERATOR = 'unary' - - UNARY_POST_OPERATOR = 'unary_post' - - BINARY_OPERATOR = 'binary' - - TERNARY_OPERATOR = 'ternary' - - def __init__(self): - """Initializes a token metadata object.""" - self.last_code = None - self.context = None - self.operator_type = None - self.is_implied_semicolon = False - self.is_implied_block = False - self.is_implied_block_close = False - self.aliased_symbol = None - self.is_alias_definition = False - - def __repr__(self): - """Returns a string representation of the context object.""" - parts = ['%r' % self.context] - if self.operator_type: - parts.append('optype: %r' % self.operator_type) - if self.is_implied_semicolon: - parts.append('implied;') - if self.aliased_symbol: - parts.append('alias for: %s' % self.aliased_symbol) - return 'MetaData(%s)' % ', '.join(parts) - - def IsUnaryOperator(self): - return self.operator_type in (EcmaMetaData.UNARY_OPERATOR, - EcmaMetaData.UNARY_POST_OPERATOR) - - def IsUnaryPostOperator(self): - return self.operator_type == EcmaMetaData.UNARY_POST_OPERATOR - - -class EcmaMetaDataPass(object): - """A pass that iterates over all tokens and builds metadata about them.""" - - def __init__(self): - """Initialize the meta data pass object.""" - self.Reset() - - def Reset(self): - """Resets the metadata pass to prepare for the next file.""" - self._token = None - self._context = None - self._AddContext(EcmaContext.ROOT) - self._last_code = None - - def _CreateContext(self, context_type): - """Overridable by subclasses to create the appropriate context type.""" - return EcmaContext(context_type, self._token, self._context) - - def _CreateMetaData(self): - """Overridable by subclasses to create the appropriate metadata type.""" - return EcmaMetaData() - - def _AddContext(self, context_type): - """Adds a context of the given type to the context stack. - - Args: - context_type: The type of context to create - """ - self._context = self._CreateContext(context_type) - - def _PopContext(self): - """Moves up one level in the context stack. - - Returns: - The former context. - - Raises: - ParseError: If the root context is popped. - """ - top_context = self._context - top_context.end_token = self._token - self._context = top_context.parent - if self._context: - return top_context - else: - raise ParseError(self._token) - - def _PopContextType(self, *stop_types): - """Pops the context stack until a context of the given type is popped. - - Args: - *stop_types: The types of context to pop to - stops at the first match. - - Returns: - The context object of the given type that was popped. - """ - last = None - while not last or last.type not in stop_types: - last = self._PopContext() - return last - - def _EndStatement(self): - """Process the end of a statement.""" - self._PopContextType(EcmaContext.STATEMENT) - if self._context.type == EcmaContext.IMPLIED_BLOCK: - self._token.metadata.is_implied_block_close = True - self._PopContext() - - def _ProcessContext(self): - """Process the context at the current token. - - Returns: - The context that should be assigned to the current token, or None if - the current context after this method should be used. - - Raises: - ParseError: When the token appears in an invalid context. - """ - token = self._token - token_type = token.type - - if self._context.type in EcmaContext.BLOCK_TYPES: - # Whenever we're in a block, we add a statement context. We make an - # exception for switch statements since they can only contain case: and - # default: and therefore don't directly contain statements. - # The block we add here may be immediately removed in some cases, but - # that causes no harm. - parent = self._context.parent - if not parent or parent.type != EcmaContext.SWITCH: - self._AddContext(EcmaContext.STATEMENT) - - elif self._context.type == EcmaContext.ARRAY_LITERAL: - self._AddContext(EcmaContext.LITERAL_ELEMENT) - - if token_type == TokenType.START_PAREN: - if self._last_code and self._last_code.IsKeyword('for'): - # for loops contain multiple statements in the group unlike while, - # switch, if, etc. - self._AddContext(EcmaContext.FOR_GROUP_BLOCK) - else: - self._AddContext(EcmaContext.GROUP) - - elif token_type == TokenType.END_PAREN: - result = self._PopContextType(EcmaContext.GROUP, - EcmaContext.FOR_GROUP_BLOCK) - keyword_token = result.start_token.metadata.last_code - # keyword_token will not exist if the open paren is the first line of the - # file, for example if all code is wrapped in an immediately executed - # annonymous function. - if keyword_token and keyword_token.string in ('if', 'for', 'while'): - next_code = tokenutil.SearchExcept(token, TokenType.NON_CODE_TYPES) - if next_code.type != TokenType.START_BLOCK: - # Check for do-while. - is_do_while = False - pre_keyword_token = keyword_token.metadata.last_code - if (pre_keyword_token and - pre_keyword_token.type == TokenType.END_BLOCK): - start_block_token = pre_keyword_token.metadata.context.start_token - is_do_while = start_block_token.metadata.last_code.string == 'do' - - # If it's not do-while, it's an implied block. - if not is_do_while: - self._AddContext(EcmaContext.IMPLIED_BLOCK) - token.metadata.is_implied_block = True - - return result - - # else (not else if) with no open brace after it should be considered the - # start of an implied block, similar to the case with if, for, and while - # above. - elif (token_type == TokenType.KEYWORD and - token.string == 'else'): - next_code = tokenutil.SearchExcept(token, TokenType.NON_CODE_TYPES) - if (next_code.type != TokenType.START_BLOCK and - (next_code.type != TokenType.KEYWORD or next_code.string != 'if')): - self._AddContext(EcmaContext.IMPLIED_BLOCK) - token.metadata.is_implied_block = True - - elif token_type == TokenType.START_PARAMETERS: - self._AddContext(EcmaContext.PARAMETERS) - - elif token_type == TokenType.END_PARAMETERS: - return self._PopContextType(EcmaContext.PARAMETERS) - - elif token_type == TokenType.START_BRACKET: - if (self._last_code and - self._last_code.type in TokenType.EXPRESSION_ENDER_TYPES): - self._AddContext(EcmaContext.INDEX) - else: - self._AddContext(EcmaContext.ARRAY_LITERAL) - - elif token_type == TokenType.END_BRACKET: - return self._PopContextType(EcmaContext.INDEX, EcmaContext.ARRAY_LITERAL) - - elif token_type == TokenType.START_BLOCK: - if (self._last_code.type in (TokenType.END_PAREN, - TokenType.END_PARAMETERS) or - self._last_code.IsKeyword('else') or - self._last_code.IsKeyword('do') or - self._last_code.IsKeyword('try') or - self._last_code.IsKeyword('finally') or - (self._last_code.IsOperator(':') and - self._last_code.metadata.context.type == EcmaContext.CASE_BLOCK)): - # else, do, try, and finally all might have no () before {. - # Also, handle the bizzare syntax case 10: {...}. - self._AddContext(EcmaContext.BLOCK) - else: - self._AddContext(EcmaContext.OBJECT_LITERAL) - - elif token_type == TokenType.END_BLOCK: - context = self._PopContextType(EcmaContext.BLOCK, - EcmaContext.OBJECT_LITERAL) - if self._context.type == EcmaContext.SWITCH: - # The end of the block also means the end of the switch statement it - # applies to. - return self._PopContext() - return context - - elif token.IsKeyword('switch'): - self._AddContext(EcmaContext.SWITCH) - - elif (token_type == TokenType.KEYWORD and - token.string in ('case', 'default') and - self._context.type != EcmaContext.OBJECT_LITERAL): - # Pop up to but not including the switch block. - while self._context.parent.type != EcmaContext.SWITCH: - self._PopContext() - if self._context.parent is None: - raise ParseError(token, 'Encountered case/default statement ' - 'without switch statement') - - elif token.IsOperator('?'): - self._AddContext(EcmaContext.TERNARY_TRUE) - - elif token.IsOperator(':'): - if self._context.type == EcmaContext.OBJECT_LITERAL: - self._AddContext(EcmaContext.LITERAL_ELEMENT) - - elif self._context.type == EcmaContext.TERNARY_TRUE: - self._PopContext() - self._AddContext(EcmaContext.TERNARY_FALSE) - - # Handle nested ternary statements like: - # foo = bar ? baz ? 1 : 2 : 3 - # When we encounter the second ":" the context is - # ternary_false > ternary_true > statement > root - elif (self._context.type == EcmaContext.TERNARY_FALSE and - self._context.parent.type == EcmaContext.TERNARY_TRUE): - self._PopContext() # Leave current ternary false context. - self._PopContext() # Leave current parent ternary true - self._AddContext(EcmaContext.TERNARY_FALSE) - - elif self._context.parent.type == EcmaContext.SWITCH: - self._AddContext(EcmaContext.CASE_BLOCK) - - elif token.IsKeyword('var'): - self._AddContext(EcmaContext.VAR) - - elif token.IsOperator(','): - while self._context.type not in (EcmaContext.VAR, - EcmaContext.ARRAY_LITERAL, - EcmaContext.OBJECT_LITERAL, - EcmaContext.STATEMENT, - EcmaContext.PARAMETERS, - EcmaContext.GROUP): - self._PopContext() - - elif token_type == TokenType.SEMICOLON: - self._EndStatement() - - def Process(self, first_token): - """Processes the token stream starting with the given token.""" - self._token = first_token - while self._token: - self._ProcessToken() - - if self._token.IsCode(): - self._last_code = self._token - - self._token = self._token.next - - try: - self._PopContextType(self, EcmaContext.ROOT) - except ParseError: - # Ignore the "popped to root" error. - pass - - def _ProcessToken(self): - """Process the given token.""" - token = self._token - token.metadata = self._CreateMetaData() - context = (self._ProcessContext() or self._context) - token.metadata.context = context - token.metadata.last_code = self._last_code - - # Determine the operator type of the token, if applicable. - if token.type == TokenType.OPERATOR: - token.metadata.operator_type = self._GetOperatorType(token) - - # Determine if there is an implied semicolon after the token. - if token.type != TokenType.SEMICOLON: - next_code = tokenutil.SearchExcept(token, TokenType.NON_CODE_TYPES) - # A statement like if (x) does not need a semicolon after it - is_implied_block = self._context == EcmaContext.IMPLIED_BLOCK - is_last_code_in_line = token.IsCode() and ( - not next_code or next_code.line_number != token.line_number) - is_continued_operator = (token.type == TokenType.OPERATOR and - not token.metadata.IsUnaryPostOperator()) - is_continued_dot = token.string == '.' - next_code_is_operator = next_code and next_code.type == TokenType.OPERATOR - is_end_of_block = ( - token.type == TokenType.END_BLOCK and - token.metadata.context.type != EcmaContext.OBJECT_LITERAL) - is_multiline_string = (token.type == TokenType.STRING_TEXT or - token.type == TokenType.TEMPLATE_STRING_START) - is_continued_var_decl = (token.IsKeyword('var') and - next_code and - (next_code.type in [TokenType.IDENTIFIER, - TokenType.SIMPLE_LVALUE]) and - token.line_number < next_code.line_number) - next_code_is_block = next_code and next_code.type == TokenType.START_BLOCK - if (is_last_code_in_line and - self._StatementCouldEndInContext() and - not is_multiline_string and - not is_end_of_block and - not is_continued_var_decl and - not is_continued_operator and - not is_continued_dot and - not next_code_is_operator and - not is_implied_block and - not next_code_is_block): - token.metadata.is_implied_semicolon = True - self._EndStatement() - - def _StatementCouldEndInContext(self): - """Returns if the current statement (if any) may end in this context.""" - # In the basic statement or variable declaration context, statement can - # always end in this context. - if self._context.type in (EcmaContext.STATEMENT, EcmaContext.VAR): - return True - - # End of a ternary false branch inside a statement can also be the - # end of the statement, for example: - # var x = foo ? foo.bar() : null - # In this case the statement ends after the null, when the context stack - # looks like ternary_false > var > statement > root. - if (self._context.type == EcmaContext.TERNARY_FALSE and - self._context.parent.type in (EcmaContext.STATEMENT, EcmaContext.VAR)): - return True - - # In all other contexts like object and array literals, ternary true, etc. - # the statement can't yet end. - return False - - def _GetOperatorType(self, token): - """Returns the operator type of the given operator token. - - Args: - token: The token to get arity for. - - Returns: - The type of the operator. One of the *_OPERATOR constants defined in - EcmaMetaData. - """ - if token.string == '?': - return EcmaMetaData.TERNARY_OPERATOR - - if token.string in TokenType.UNARY_OPERATORS: - return EcmaMetaData.UNARY_OPERATOR - - last_code = token.metadata.last_code - if not last_code or last_code.type == TokenType.END_BLOCK: - return EcmaMetaData.UNARY_OPERATOR - - if (token.string in TokenType.UNARY_POST_OPERATORS and - last_code.type in TokenType.EXPRESSION_ENDER_TYPES): - return EcmaMetaData.UNARY_POST_OPERATOR - - if (token.string in TokenType.UNARY_OK_OPERATORS and - last_code.type not in TokenType.EXPRESSION_ENDER_TYPES and - last_code.string not in TokenType.UNARY_POST_OPERATORS): - return EcmaMetaData.UNARY_OPERATOR - - return EcmaMetaData.BINARY_OPERATOR
diff --git a/third_party/closure_linter/closure_linter/error_check.py b/third_party/closure_linter/closure_linter/error_check.py deleted file mode 100755 index 5fe2b92..0000000 --- a/third_party/closure_linter/closure_linter/error_check.py +++ /dev/null
@@ -1,97 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2011 The Closure Linter Authors. All Rights Reserved. -# -# 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. - - -"""Specific JSLint errors checker.""" - - - -import gflags as flags - -FLAGS = flags.FLAGS - - -class Rule(object): - """Different rules to check.""" - - # Documentations for specific rules goes in flag definition. - BLANK_LINES_AT_TOP_LEVEL = 'blank_lines_at_top_level' - INDENTATION = 'indentation' - WELL_FORMED_AUTHOR = 'well_formed_author' - NO_BRACES_AROUND_INHERIT_DOC = 'no_braces_around_inherit_doc' - BRACES_AROUND_TYPE = 'braces_around_type' - OPTIONAL_TYPE_MARKER = 'optional_type_marker' - VARIABLE_ARG_MARKER = 'variable_arg_marker' - UNUSED_PRIVATE_MEMBERS = 'unused_private_members' - UNUSED_LOCAL_VARIABLES = 'unused_local_variables' - - # Rule to raise all known errors. - ALL = 'all' - - # All rules that are to be checked when using the strict flag. E.g. the rules - # that are specific to the stricter Closure style. - CLOSURE_RULES = frozenset([BLANK_LINES_AT_TOP_LEVEL, - INDENTATION, - WELL_FORMED_AUTHOR, - NO_BRACES_AROUND_INHERIT_DOC, - BRACES_AROUND_TYPE, - OPTIONAL_TYPE_MARKER, - VARIABLE_ARG_MARKER]) - - -flags.DEFINE_boolean('strict', False, - 'Whether to validate against the stricter Closure style. ' - 'This includes ' + (', '.join(Rule.CLOSURE_RULES)) + '.') -flags.DEFINE_multistring('jslint_error', [], - 'List of specific lint errors to check. Here is a list' - ' of accepted values:\n' - ' - ' + Rule.ALL + ': enables all following errors.\n' - ' - ' + Rule.BLANK_LINES_AT_TOP_LEVEL + ': validates' - 'number of blank lines between blocks at top level.\n' - ' - ' + Rule.INDENTATION + ': checks correct ' - 'indentation of code.\n' - ' - ' + Rule.WELL_FORMED_AUTHOR + ': validates the ' - '@author JsDoc tags.\n' - ' - ' + Rule.NO_BRACES_AROUND_INHERIT_DOC + ': ' - 'forbids braces around @inheritdoc JsDoc tags.\n' - ' - ' + Rule.BRACES_AROUND_TYPE + ': enforces braces ' - 'around types in JsDoc tags.\n' - ' - ' + Rule.OPTIONAL_TYPE_MARKER + ': checks correct ' - 'use of optional marker = in param types.\n' - ' - ' + Rule.UNUSED_PRIVATE_MEMBERS + ': checks for ' - 'unused private variables.\n' - ' - ' + Rule.UNUSED_LOCAL_VARIABLES + ': checks for ' - 'unused local variables.\n') - - -def ShouldCheck(rule): - """Returns whether the optional rule should be checked. - - Computes different flags (strict, jslint_error, jslint_noerror) to find out if - this specific rule should be checked. - - Args: - rule: Name of the rule (see Rule). - - Returns: - True if the rule should be checked according to the flags, otherwise False. - """ - if 'no_' + rule in FLAGS.jslint_error: - return False - if rule in FLAGS.jslint_error or Rule.ALL in FLAGS.jslint_error: - return True - # Checks strict rules. - return FLAGS.strict and rule in Rule.CLOSURE_RULES
diff --git a/third_party/closure_linter/closure_linter/error_fixer.py b/third_party/closure_linter/closure_linter/error_fixer.py deleted file mode 100755 index 221550a..0000000 --- a/third_party/closure_linter/closure_linter/error_fixer.py +++ /dev/null
@@ -1,620 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Main class responsible for automatically fixing simple style violations.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = 'robbyw@google.com (Robert Walker)' - -import re - -import gflags as flags -from closure_linter import errors -from closure_linter import javascriptstatetracker -from closure_linter import javascripttokens -from closure_linter import requireprovidesorter -from closure_linter import tokenutil -from closure_linter.common import errorhandler - -# Shorthand -Token = javascripttokens.JavaScriptToken -Type = javascripttokens.JavaScriptTokenType - -END_OF_FLAG_TYPE = re.compile(r'(}?\s*)$') - -# Regex to represent common mistake inverting author name and email as -# @author User Name (user@company) -INVERTED_AUTHOR_SPEC = re.compile(r'(?P<leading_whitespace>\s*)' - r'(?P<name>[^(]+)' - r'(?P<whitespace_after_name>\s+)' - r'\(' - r'(?P<email>[^\s]+@[^)\s]+)' - r'\)' - r'(?P<trailing_characters>.*)') - -FLAGS = flags.FLAGS -flags.DEFINE_boolean('disable_indentation_fixing', False, - 'Whether to disable automatic fixing of indentation.') -flags.DEFINE_list('fix_error_codes', [], 'A list of specific error codes to ' - 'fix. Defaults to all supported error codes when empty. ' - 'See errors.py for a list of error codes.') - - -class ErrorFixer(errorhandler.ErrorHandler): - """Object that fixes simple style errors.""" - - def __init__(self, external_file=None): - """Initialize the error fixer. - - Args: - external_file: If included, all output will be directed to this file - instead of overwriting the files the errors are found in. - """ - errorhandler.ErrorHandler.__init__(self) - - self._file_name = None - self._file_token = None - self._external_file = external_file - - try: - self._fix_error_codes = set([errors.ByName(error.upper()) for error in - FLAGS.fix_error_codes]) - except KeyError as ke: - raise ValueError('Unknown error code ' + ke.args[0]) - - def HandleFile(self, filename, first_token): - """Notifies this ErrorPrinter that subsequent errors are in filename. - - Args: - filename: The name of the file about to be checked. - first_token: The first token in the file. - """ - self._file_name = filename - self._file_is_html = filename.endswith('.html') or filename.endswith('.htm') - self._file_token = first_token - self._file_fix_count = 0 - self._file_changed_lines = set() - - def _AddFix(self, tokens): - """Adds the fix to the internal count. - - Args: - tokens: The token or sequence of tokens changed to fix an error. - """ - self._file_fix_count += 1 - if hasattr(tokens, 'line_number'): - self._file_changed_lines.add(tokens.line_number) - else: - for token in tokens: - self._file_changed_lines.add(token.line_number) - - def _FixJsDocPipeNull(self, js_type): - """Change number|null or null|number to ?number. - - Args: - js_type: The typeannotation.TypeAnnotation instance to fix. - """ - - # Recurse into all sub_types if the error was at a deeper level. - map(self._FixJsDocPipeNull, js_type.IterTypes()) - - if js_type.type_group and len(js_type.sub_types) == 2: - # Find and remove the null sub_type: - sub_type = None - for sub_type in js_type.sub_types: - if sub_type.identifier == 'null': - map(tokenutil.DeleteToken, sub_type.tokens) - self._AddFix(sub_type.tokens) - break - else: - return - - first_token = js_type.FirstToken() - question_mark = Token('?', Type.DOC_TYPE_MODIFIER, first_token.line, - first_token.line_number) - tokenutil.InsertTokenBefore(question_mark, first_token) - js_type.tokens.insert(0, question_mark) - js_type.tokens.remove(sub_type) - js_type.sub_types.remove(sub_type) - js_type.or_null = True - - # Now also remove the separator, which is in the parent's token list, - # either before or after the sub_type, there is exactly one. Scan for it. - for token in js_type.tokens: - if (token and isinstance(token, Token) and - token.type == Type.DOC_TYPE_MODIFIER and token.string == '|'): - tokenutil.DeleteToken(token) - js_type.tokens.remove(token) - self._AddFix(token) - break - - def HandleError(self, error): - """Attempts to fix the error. - - Args: - error: The error object - """ - code = error.code - token = error.token - - if self._fix_error_codes and code not in self._fix_error_codes: - return - - if code == errors.JSDOC_PREFER_QUESTION_TO_PIPE_NULL: - self._FixJsDocPipeNull(token.attached_object.jstype) - - elif code == errors.JSDOC_MISSING_OPTIONAL_TYPE: - iterator = token.attached_object.type_end_token - if iterator.type == Type.DOC_END_BRACE or iterator.string.isspace(): - iterator = iterator.previous - - ending_space = len(iterator.string) - len(iterator.string.rstrip()) - iterator.string = '%s=%s' % (iterator.string.rstrip(), - ' ' * ending_space) - - # Create a new flag object with updated type info. - token.attached_object = javascriptstatetracker.JsDocFlag(token) - self._AddFix(token) - - elif code == errors.JSDOC_MISSING_VAR_ARGS_TYPE: - iterator = token.attached_object.type_start_token - if iterator.type == Type.DOC_START_BRACE or iterator.string.isspace(): - iterator = iterator.next - - starting_space = len(iterator.string) - len(iterator.string.lstrip()) - iterator.string = '%s...%s' % (' ' * starting_space, - iterator.string.lstrip()) - - # Create a new flag object with updated type info. - token.attached_object = javascriptstatetracker.JsDocFlag(token) - self._AddFix(token) - - elif code in (errors.MISSING_SEMICOLON_AFTER_FUNCTION, - errors.MISSING_SEMICOLON): - semicolon_token = Token(';', Type.SEMICOLON, token.line, - token.line_number) - tokenutil.InsertTokenAfter(semicolon_token, token) - token.metadata.is_implied_semicolon = False - semicolon_token.metadata.is_implied_semicolon = False - self._AddFix(token) - - elif code in (errors.ILLEGAL_SEMICOLON_AFTER_FUNCTION, - errors.REDUNDANT_SEMICOLON, - errors.COMMA_AT_END_OF_LITERAL): - self._DeleteToken(token) - self._AddFix(token) - - elif code == errors.INVALID_JSDOC_TAG: - if token.string == '@returns': - token.string = '@return' - self._AddFix(token) - - elif code == errors.FILE_MISSING_NEWLINE: - # This error is fixed implicitly by the way we restore the file - self._AddFix(token) - - elif code == errors.MISSING_SPACE: - if error.fix_data: - token.string = error.fix_data - self._AddFix(token) - elif error.position: - if error.position.IsAtBeginning(): - tokenutil.InsertSpaceTokenAfter(token.previous) - elif error.position.IsAtEnd(token.string): - tokenutil.InsertSpaceTokenAfter(token) - else: - token.string = error.position.Set(token.string, ' ') - self._AddFix(token) - - elif code == errors.EXTRA_SPACE: - if error.position: - token.string = error.position.Set(token.string, '') - self._AddFix(token) - - elif code == errors.MISSING_LINE: - if error.position.IsAtBeginning(): - tokenutil.InsertBlankLineAfter(token.previous) - else: - tokenutil.InsertBlankLineAfter(token) - self._AddFix(token) - - elif code == errors.EXTRA_LINE: - self._DeleteToken(token) - self._AddFix(token) - - elif code == errors.WRONG_BLANK_LINE_COUNT: - if not token.previous: - # TODO(user): Add an insertBefore method to tokenutil. - return - - num_lines = error.fix_data - should_delete = False - - if num_lines < 0: - num_lines *= -1 - should_delete = True - - for unused_i in xrange(1, num_lines + 1): - if should_delete: - # TODO(user): DeleteToken should update line numbers. - self._DeleteToken(token.previous) - else: - tokenutil.InsertBlankLineAfter(token.previous) - self._AddFix(token) - - elif code == errors.UNNECESSARY_DOUBLE_QUOTED_STRING: - end_quote = tokenutil.Search(token, Type.DOUBLE_QUOTE_STRING_END) - if end_quote: - single_quote_start = Token( - "'", Type.SINGLE_QUOTE_STRING_START, token.line, token.line_number) - single_quote_end = Token( - "'", Type.SINGLE_QUOTE_STRING_START, end_quote.line, - token.line_number) - - tokenutil.InsertTokenAfter(single_quote_start, token) - tokenutil.InsertTokenAfter(single_quote_end, end_quote) - self._DeleteToken(token) - self._DeleteToken(end_quote) - self._AddFix([token, end_quote]) - - elif code == errors.MISSING_BRACES_AROUND_TYPE: - fixed_tokens = [] - start_token = token.attached_object.type_start_token - - if start_token.type != Type.DOC_START_BRACE: - leading_space = ( - len(start_token.string) - len(start_token.string.lstrip())) - if leading_space: - start_token = tokenutil.SplitToken(start_token, leading_space) - # Fix case where start and end token were the same. - if token.attached_object.type_end_token == start_token.previous: - token.attached_object.type_end_token = start_token - - new_token = Token('{', Type.DOC_START_BRACE, start_token.line, - start_token.line_number) - tokenutil.InsertTokenAfter(new_token, start_token.previous) - token.attached_object.type_start_token = new_token - fixed_tokens.append(new_token) - - end_token = token.attached_object.type_end_token - if end_token.type != Type.DOC_END_BRACE: - # If the start token was a brace, the end token will be a - # FLAG_ENDING_TYPE token, if there wasn't a starting brace then - # the end token is the last token of the actual type. - last_type = end_token - if not fixed_tokens: - last_type = end_token.previous - - while last_type.string.isspace(): - last_type = last_type.previous - - # If there was no starting brace then a lone end brace wouldn't have - # been type end token. Now that we've added any missing start brace, - # see if the last effective type token was an end brace. - if last_type.type != Type.DOC_END_BRACE: - trailing_space = (len(last_type.string) - - len(last_type.string.rstrip())) - if trailing_space: - tokenutil.SplitToken(last_type, - len(last_type.string) - trailing_space) - - new_token = Token('}', Type.DOC_END_BRACE, last_type.line, - last_type.line_number) - tokenutil.InsertTokenAfter(new_token, last_type) - token.attached_object.type_end_token = new_token - fixed_tokens.append(new_token) - - self._AddFix(fixed_tokens) - - elif code == errors.LINE_STARTS_WITH_OPERATOR: - # Remove whitespace following the operator so the line starts clean. - self._StripSpace(token, before=False) - - # Remove the operator. - tokenutil.DeleteToken(token) - self._AddFix(token) - - insertion_point = tokenutil.GetPreviousCodeToken(token) - - # Insert a space between the previous token and the new operator. - space = Token(' ', Type.WHITESPACE, insertion_point.line, - insertion_point.line_number) - tokenutil.InsertTokenAfter(space, insertion_point) - - # Insert the operator on the end of the previous line. - new_token = Token(token.string, token.type, insertion_point.line, - insertion_point.line_number) - tokenutil.InsertTokenAfter(new_token, space) - self._AddFix(new_token) - - elif code == errors.LINE_ENDS_WITH_DOT: - # Remove whitespace preceding the operator to remove trailing whitespace. - self._StripSpace(token, before=True) - - # Remove the dot. - tokenutil.DeleteToken(token) - self._AddFix(token) - - insertion_point = tokenutil.GetNextCodeToken(token) - - # Insert the dot at the beginning of the next line of code. - new_token = Token(token.string, token.type, insertion_point.line, - insertion_point.line_number) - tokenutil.InsertTokenBefore(new_token, insertion_point) - self._AddFix(new_token) - - elif code == errors.GOOG_REQUIRES_NOT_ALPHABETIZED: - require_start_token = error.fix_data - sorter = requireprovidesorter.RequireProvideSorter() - sorter.FixRequires(require_start_token) - - self._AddFix(require_start_token) - - elif code == errors.GOOG_PROVIDES_NOT_ALPHABETIZED: - provide_start_token = error.fix_data - sorter = requireprovidesorter.RequireProvideSorter() - sorter.FixProvides(provide_start_token) - - self._AddFix(provide_start_token) - - elif code == errors.UNNECESSARY_BRACES_AROUND_INHERIT_DOC: - if token.previous.string == '{' and token.next.string == '}': - self._DeleteToken(token.previous) - self._DeleteToken(token.next) - self._AddFix([token]) - - elif code == errors.INVALID_AUTHOR_TAG_DESCRIPTION: - match = INVERTED_AUTHOR_SPEC.match(token.string) - if match: - token.string = '%s%s%s(%s)%s' % (match.group('leading_whitespace'), - match.group('email'), - match.group('whitespace_after_name'), - match.group('name'), - match.group('trailing_characters')) - self._AddFix(token) - - elif (code == errors.WRONG_INDENTATION and - not FLAGS.disable_indentation_fixing): - token = tokenutil.GetFirstTokenInSameLine(token) - actual = error.position.start - expected = error.position.length - - # Cases where first token is param but with leading spaces. - if (len(token.string.lstrip()) == len(token.string) - actual and - token.string.lstrip()): - token.string = token.string.lstrip() - actual = 0 - - if token.type in (Type.WHITESPACE, Type.PARAMETERS) and actual != 0: - token.string = token.string.lstrip() + (' ' * expected) - self._AddFix([token]) - else: - # We need to add indentation. - new_token = Token(' ' * expected, Type.WHITESPACE, - token.line, token.line_number) - # Note that we'll never need to add indentation at the first line, - # since it will always not be indented. Therefore it's safe to assume - # token.previous exists. - tokenutil.InsertTokenAfter(new_token, token.previous) - self._AddFix([token]) - - elif code in [errors.MALFORMED_END_OF_SCOPE_COMMENT, - errors.MISSING_END_OF_SCOPE_COMMENT]: - # Only fix cases where }); is found with no trailing content on the line - # other than a comment. Value of 'token' is set to } for this error. - if (token.type == Type.END_BLOCK and - token.next.type == Type.END_PAREN and - token.next.next.type == Type.SEMICOLON): - current_token = token.next.next.next - removed_tokens = [] - while current_token and current_token.line_number == token.line_number: - if current_token.IsAnyType(Type.WHITESPACE, - Type.START_SINGLE_LINE_COMMENT, - Type.COMMENT): - removed_tokens.append(current_token) - current_token = current_token.next - else: - return - - if removed_tokens: - self._DeleteTokens(removed_tokens[0], len(removed_tokens)) - - whitespace_token = Token(' ', Type.WHITESPACE, token.line, - token.line_number) - start_comment_token = Token('//', Type.START_SINGLE_LINE_COMMENT, - token.line, token.line_number) - comment_token = Token(' goog.scope', Type.COMMENT, token.line, - token.line_number) - insertion_tokens = [whitespace_token, start_comment_token, - comment_token] - - tokenutil.InsertTokensAfter(insertion_tokens, token.next.next) - self._AddFix(removed_tokens + insertion_tokens) - - elif code in [errors.EXTRA_GOOG_PROVIDE, errors.EXTRA_GOOG_REQUIRE]: - tokens_in_line = tokenutil.GetAllTokensInSameLine(token) - num_delete_tokens = len(tokens_in_line) - # If line being deleted is preceded and succeed with blank lines then - # delete one blank line also. - if (tokens_in_line[0].previous and tokens_in_line[-1].next - and tokens_in_line[0].previous.type == Type.BLANK_LINE - and tokens_in_line[-1].next.type == Type.BLANK_LINE): - num_delete_tokens += 1 - self._DeleteTokens(tokens_in_line[0], num_delete_tokens) - self._AddFix(tokens_in_line) - - elif code in [errors.MISSING_GOOG_PROVIDE, errors.MISSING_GOOG_REQUIRE]: - missing_namespaces = error.fix_data[0] - need_blank_line = error.fix_data[1] or (not token.previous) - - insert_location = Token('', Type.NORMAL, '', token.line_number - 1) - dummy_first_token = insert_location - tokenutil.InsertTokenBefore(insert_location, token) - - # If inserting a blank line check blank line does not exist before - # token to avoid extra blank lines. - if (need_blank_line and insert_location.previous - and insert_location.previous.type != Type.BLANK_LINE): - tokenutil.InsertBlankLineAfter(insert_location) - insert_location = insert_location.next - - for missing_namespace in missing_namespaces: - new_tokens = self._GetNewRequireOrProvideTokens( - code == errors.MISSING_GOOG_PROVIDE, - missing_namespace, insert_location.line_number + 1) - tokenutil.InsertLineAfter(insert_location, new_tokens) - insert_location = new_tokens[-1] - self._AddFix(new_tokens) - - # If inserting a blank line check blank line does not exist after - # token to avoid extra blank lines. - if (need_blank_line and insert_location.next - and insert_location.next.type != Type.BLANK_LINE): - tokenutil.InsertBlankLineAfter(insert_location) - - tokenutil.DeleteToken(dummy_first_token) - - def _StripSpace(self, token, before): - """Strip whitespace tokens either preceding or following the given token. - - Args: - token: The token. - before: If true, strip space before the token, if false, after it. - """ - token = token.previous if before else token.next - while token and token.type == Type.WHITESPACE: - tokenutil.DeleteToken(token) - token = token.previous if before else token.next - - def _GetNewRequireOrProvideTokens(self, is_provide, namespace, line_number): - """Returns a list of tokens to create a goog.require/provide statement. - - Args: - is_provide: True if getting tokens for a provide, False for require. - namespace: The required or provided namespaces to get tokens for. - line_number: The line number the new require or provide statement will be - on. - - Returns: - Tokens to create a new goog.require or goog.provide statement. - """ - string = 'goog.require' - if is_provide: - string = 'goog.provide' - line_text = string + '(\'' + namespace + '\');\n' - return [ - Token(string, Type.IDENTIFIER, line_text, line_number), - Token('(', Type.START_PAREN, line_text, line_number), - Token('\'', Type.SINGLE_QUOTE_STRING_START, line_text, line_number), - Token(namespace, Type.STRING_TEXT, line_text, line_number), - Token('\'', Type.SINGLE_QUOTE_STRING_END, line_text, line_number), - Token(')', Type.END_PAREN, line_text, line_number), - Token(';', Type.SEMICOLON, line_text, line_number) - ] - - def _DeleteToken(self, token): - """Deletes the specified token from the linked list of tokens. - - Updates instance variables pointing to tokens such as _file_token if - they reference the deleted token. - - Args: - token: The token to delete. - """ - if token == self._file_token: - self._file_token = token.next - - tokenutil.DeleteToken(token) - - def _DeleteTokens(self, token, token_count): - """Deletes the given number of tokens starting with the given token. - - Updates instance variables pointing to tokens such as _file_token if - they reference the deleted token. - - Args: - token: The first token to delete. - token_count: The total number of tokens to delete. - """ - if token == self._file_token: - for unused_i in xrange(token_count): - self._file_token = self._file_token.next - - tokenutil.DeleteTokens(token, token_count) - - def FinishFile(self): - """Called when the current file has finished style checking. - - Used to go back and fix any errors in the file. It currently supports both - js and html files. For js files it does a simple dump of all tokens, but in - order to support html file, we need to merge the original file with the new - token set back together. This works because the tokenized html file is the - original html file with all non js lines kept but blanked out with one blank - line token per line of html. - """ - if self._file_fix_count: - # Get the original file content for html. - if self._file_is_html: - f = open(self._file_name, 'r') - original_lines = f.readlines() - f.close() - - f = self._external_file - if not f: - error_noun = 'error' if self._file_fix_count == 1 else 'errors' - print 'Fixed %d %s in %s' % ( - self._file_fix_count, error_noun, self._file_name) - f = open(self._file_name, 'w') - - token = self._file_token - # Finding the first not deleted token. - while token.is_deleted: - token = token.next - # If something got inserted before first token (e.g. due to sorting) - # then move to start. Bug 8398202. - while token.previous: - token = token.previous - char_count = 0 - line = '' - while token: - line += token.string - char_count += len(token.string) - - if token.IsLastInLine(): - # We distinguish if a blank line in html was from stripped original - # file or newly added error fix by looking at the "org_line_number" - # field on the token. It is only set in the tokenizer, so for all - # error fixes, the value should be None. - if (line or not self._file_is_html or - token.orig_line_number is None): - f.write(line) - f.write('\n') - else: - f.write(original_lines[token.orig_line_number - 1]) - line = '' - if char_count > 80 and token.line_number in self._file_changed_lines: - print 'WARNING: Line %d of %s is now longer than 80 characters.' % ( - token.line_number, self._file_name) - - char_count = 0 - - token = token.next - - if not self._external_file: - # Close the file if we created it - f.close()
diff --git a/third_party/closure_linter/closure_linter/error_fixer_test.py b/third_party/closure_linter/closure_linter/error_fixer_test.py deleted file mode 100644 index 0deeb3bc..0000000 --- a/third_party/closure_linter/closure_linter/error_fixer_test.py +++ /dev/null
@@ -1,77 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Unit tests for the error_fixer module.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - - - -import unittest as googletest -from closure_linter import error_fixer -from closure_linter import testutil -from closure_linter import tokenutil - - -class ErrorFixerTest(googletest.TestCase): - """Unit tests for error_fixer.""" - - def setUp(self): - self.error_fixer = error_fixer.ErrorFixer() - - def testDeleteToken(self): - start_token = testutil.TokenizeSourceAndRunEcmaPass(_TEST_SCRIPT) - second_token = start_token.next - self.error_fixer.HandleFile('test_file', start_token) - - self.error_fixer._DeleteToken(start_token) - - self.assertEqual(second_token, self.error_fixer._file_token) - - def testDeleteTokens(self): - start_token = testutil.TokenizeSourceAndRunEcmaPass(_TEST_SCRIPT) - fourth_token = start_token.next.next.next - self.error_fixer.HandleFile('test_file', start_token) - - self.error_fixer._DeleteTokens(start_token, 3) - - self.assertEqual(fourth_token, self.error_fixer._file_token) - - def DoTestFixJsDocPipeNull(self, expected, original): - _, comments = testutil.ParseFunctionsAndComments( - '/** @param {%s} */' % original) - jstype = comments[0].GetDocFlags()[0].jstype - self.error_fixer.HandleFile('unittest', None) - self.error_fixer._FixJsDocPipeNull(jstype) - self.assertEquals(expected, repr(jstype)) - result = tokenutil.TokensToString(jstype.FirstToken()).strip('} */') - self.assertEquals(expected, result) - - def testFixJsDocPipeNull(self): - self.DoTestFixJsDocPipeNull('?Object', 'Object|null') - self.DoTestFixJsDocPipeNull('function(?Object)', 'function(Object|null)') - self.DoTestFixJsDocPipeNull('function(?Object=)', - 'function(Object|null=)') - self.DoTestFixJsDocPipeNull( - 'function(?(Object)=,null=,?(Object)=):string', - 'function((Object|null)=,null=,(Object|null)=):string') - -_TEST_SCRIPT = """\ -var x = 3; -""" - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/errorrecord.py b/third_party/closure_linter/closure_linter/errorrecord.py deleted file mode 100644 index ce9fb90..0000000 --- a/third_party/closure_linter/closure_linter/errorrecord.py +++ /dev/null
@@ -1,66 +0,0 @@ -#!/usr/bin/env python -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# -# 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. - - -"""A simple, pickle-serializable class to represent a lint error.""" - -__author__ = 'nnaze@google.com (Nathan Naze)' - -import gflags as flags - -from closure_linter import errors -from closure_linter.common import erroroutput - -FLAGS = flags.FLAGS - - -class ErrorRecord(object): - """Record-keeping struct that can be serialized back from a process. - - Attributes: - path: Path to the file. - error_string: Error string for the user. - new_error: Whether this is a "new error" (see errors.NEW_ERRORS). - """ - - def __init__(self, path, error_string, new_error): - self.path = path - self.error_string = error_string - self.new_error = new_error - - -def MakeErrorRecord(path, error): - """Make an error record with correctly formatted error string. - - Errors are not able to be serialized (pickled) over processes because of - their pointers to the complex token/context graph. We use an intermediary - serializable class to pass back just the relevant information. - - Args: - path: Path of file the error was found in. - error: An error.Error instance. - - Returns: - _ErrorRecord instance. - """ - new_error = error.code in errors.NEW_ERRORS - - if FLAGS.unix_mode: - error_string = erroroutput.GetUnixErrorOutput( - path, error, new_error=new_error) - else: - error_string = erroroutput.GetErrorOutput(error, new_error=new_error) - - return ErrorRecord(path, error_string, new_error)
diff --git a/third_party/closure_linter/closure_linter/errorrules.py b/third_party/closure_linter/closure_linter/errorrules.py deleted file mode 100755 index b1b72aa..0000000 --- a/third_party/closure_linter/closure_linter/errorrules.py +++ /dev/null
@@ -1,72 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Linter error rules class for Closure Linter.""" - -__author__ = 'robbyw@google.com (Robert Walker)' - -import gflags as flags -from closure_linter import errors - - -FLAGS = flags.FLAGS -flags.DEFINE_boolean('jsdoc', True, - 'Whether to report errors for missing JsDoc.') -flags.DEFINE_list('disable', None, - 'Disable specific error. Usage Ex.: gjslint --disable 1,' - '0011 foo.js.') -flags.DEFINE_integer('max_line_length', 80, 'Maximum line length allowed ' - 'without warning.', lower_bound=1) - -disabled_error_nums = None - - -def GetMaxLineLength(): - """Returns allowed maximum length of line. - - Returns: - Length of line allowed without any warning. - """ - return FLAGS.max_line_length - - -def ShouldReportError(error): - """Whether the given error should be reported. - - Returns: - True for all errors except missing documentation errors and disabled - errors. For missing documentation, it returns the value of the - jsdoc flag. - """ - global disabled_error_nums - if disabled_error_nums is None: - disabled_error_nums = [] - if FLAGS.disable: - for error_str in FLAGS.disable: - error_num = 0 - try: - error_num = int(error_str) - except ValueError: - pass - disabled_error_nums.append(error_num) - - return ((FLAGS.jsdoc or error not in ( - errors.MISSING_PARAMETER_DOCUMENTATION, - errors.MISSING_RETURN_DOCUMENTATION, - errors.MISSING_MEMBER_DOCUMENTATION, - errors.MISSING_PRIVATE, - errors.MISSING_JSDOC_TAG_THIS)) and - (not FLAGS.disable or error not in disabled_error_nums))
diff --git a/third_party/closure_linter/closure_linter/errorrules_test.py b/third_party/closure_linter/closure_linter/errorrules_test.py deleted file mode 100644 index cb90378..0000000 --- a/third_party/closure_linter/closure_linter/errorrules_test.py +++ /dev/null
@@ -1,117 +0,0 @@ -#!/usr/bin/env python -# Copyright 2013 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Medium tests for the gjslint errorrules. - -Currently its just verifying that warnings can't be disabled. -""" - - - -import gflags as flags -import unittest as googletest - -from closure_linter import errors -from closure_linter import runner -from closure_linter.common import erroraccumulator - -flags.FLAGS.strict = True -flags.FLAGS.limited_doc_files = ('dummy.js', 'externs.js') -flags.FLAGS.closurized_namespaces = ('goog', 'dummy') - - -class ErrorRulesTest(googletest.TestCase): - """Test case to for gjslint errorrules.""" - - def testNoMaxLineLengthFlagExists(self): - """Tests that --max_line_length flag does not exists.""" - self.assertTrue('max_line_length' not in flags.FLAGS.FlagDict()) - - def testGetMaxLineLength(self): - """Tests warning are reported for line greater than 80. - """ - - # One line > 100 and one line > 80 and < 100. So should produce two - # line too long error. - original = [ - 'goog.require(\'dummy.aa\');', - '', - 'function a() {', - ' dummy.aa.i = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13' - ' + 14 + 15 + 16 + 17 + 18 + 19 + 20;', - ' dummy.aa.j = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13' - ' + 14 + 15 + 16 + 17 + 18;', - '}', - '' - ] - - # Expect line too long. - expected = [errors.LINE_TOO_LONG, errors.LINE_TOO_LONG] - - self._AssertErrors(original, expected) - - def testNoDisableFlagExists(self): - """Tests that --disable flag does not exists.""" - self.assertTrue('disable' not in flags.FLAGS.FlagDict()) - - def testWarningsNotDisabled(self): - """Tests warnings are reported when nothing is disabled. - """ - original = [ - 'goog.require(\'dummy.aa\');', - 'goog.require(\'dummy.Cc\');', - 'goog.require(\'dummy.Dd\');', - '', - 'function a() {', - ' dummy.aa.i = 1;', - ' dummy.Cc.i = 1;', - ' dummy.Dd.i = 1;', - '}', - ] - - expected = [errors.GOOG_REQUIRES_NOT_ALPHABETIZED, - errors.FILE_MISSING_NEWLINE] - - self._AssertErrors(original, expected) - - def _AssertErrors(self, original, expected_errors, include_header=True): - """Asserts that the error fixer corrects original to expected.""" - if include_header: - original = self._GetHeader() + original - - # Trap gjslint's output parse it to get messages added. - error_accumulator = erroraccumulator.ErrorAccumulator() - runner.Run('testing.js', error_accumulator, source=original) - error_nums = [e.code for e in error_accumulator.GetErrors()] - - error_nums.sort() - expected_errors.sort() - self.assertListEqual(error_nums, expected_errors) - - def _GetHeader(self): - """Returns a fake header for a JavaScript file.""" - return [ - '// Copyright 2011 Google Inc. All Rights Reserved.', - '', - '/**', - ' * @fileoverview Fake file overview.', - ' * @author fake@google.com (Fake Person)', - ' */', - '' - ] - - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/errors.py b/third_party/closure_linter/closure_linter/errors.py deleted file mode 100755 index 46a957ed..0000000 --- a/third_party/closure_linter/closure_linter/errors.py +++ /dev/null
@@ -1,154 +0,0 @@ -#!/usr/bin/env python -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Error codes for JavaScript style checker.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - - -def ByName(name): - """Get the error code for the given error name. - - Args: - name: The name of the error - - Returns: - The error code - """ - return globals()[name] - - -# "File-fatal" errors - these errors stop further parsing of a single file -FILE_NOT_FOUND = -1 -FILE_DOES_NOT_PARSE = -2 - -# Spacing -EXTRA_SPACE = 1 -MISSING_SPACE = 2 -EXTRA_LINE = 3 -MISSING_LINE = 4 -ILLEGAL_TAB = 5 -WRONG_INDENTATION = 6 -WRONG_BLANK_LINE_COUNT = 7 - -# Semicolons -MISSING_SEMICOLON = 10 -MISSING_SEMICOLON_AFTER_FUNCTION = 11 -ILLEGAL_SEMICOLON_AFTER_FUNCTION = 12 -REDUNDANT_SEMICOLON = 13 - -# Miscellaneous -ILLEGAL_PROTOTYPE_MEMBER_VALUE = 100 -LINE_TOO_LONG = 110 -LINE_STARTS_WITH_OPERATOR = 120 -COMMA_AT_END_OF_LITERAL = 121 -LINE_ENDS_WITH_DOT = 122 -MULTI_LINE_STRING = 130 -UNNECESSARY_DOUBLE_QUOTED_STRING = 131 -UNUSED_PRIVATE_MEMBER = 132 -UNUSED_LOCAL_VARIABLE = 133 - -# Requires, provides -GOOG_REQUIRES_NOT_ALPHABETIZED = 140 -GOOG_PROVIDES_NOT_ALPHABETIZED = 141 -MISSING_GOOG_REQUIRE = 142 -MISSING_GOOG_PROVIDE = 143 -EXTRA_GOOG_REQUIRE = 144 -EXTRA_GOOG_PROVIDE = 145 -ALIAS_STMT_NEEDS_GOOG_REQUIRE = 146 - -# JsDoc -INVALID_JSDOC_TAG = 200 -INVALID_USE_OF_DESC_TAG = 201 -NO_BUG_NUMBER_AFTER_BUG_TAG = 202 -MISSING_PARAMETER_DOCUMENTATION = 210 -EXTRA_PARAMETER_DOCUMENTATION = 211 -WRONG_PARAMETER_DOCUMENTATION = 212 -MISSING_JSDOC_TAG_TYPE = 213 -MISSING_JSDOC_TAG_DESCRIPTION = 214 -MISSING_JSDOC_PARAM_NAME = 215 -OUT_OF_ORDER_JSDOC_TAG_TYPE = 216 -MISSING_RETURN_DOCUMENTATION = 217 -UNNECESSARY_RETURN_DOCUMENTATION = 218 -MISSING_BRACES_AROUND_TYPE = 219 -MISSING_MEMBER_DOCUMENTATION = 220 -MISSING_PRIVATE = 221 -EXTRA_PRIVATE = 222 -INVALID_OVERRIDE_PRIVATE = 223 -INVALID_INHERIT_DOC_PRIVATE = 224 -MISSING_JSDOC_TAG_THIS = 225 -UNNECESSARY_BRACES_AROUND_INHERIT_DOC = 226 -INVALID_AUTHOR_TAG_DESCRIPTION = 227 -JSDOC_PREFER_QUESTION_TO_PIPE_NULL = 230 -JSDOC_ILLEGAL_QUESTION_WITH_PIPE = 231 -JSDOC_MISSING_OPTIONAL_TYPE = 232 -JSDOC_MISSING_OPTIONAL_PREFIX = 233 -JSDOC_MISSING_VAR_ARGS_TYPE = 234 -JSDOC_MISSING_VAR_ARGS_NAME = 235 -JSDOC_DOES_NOT_PARSE = 236 -# TODO(robbyw): Split this in to more specific syntax problems. -INCORRECT_SUPPRESS_SYNTAX = 250 -INVALID_SUPPRESS_TYPE = 251 -UNNECESSARY_SUPPRESS = 252 - -# File ending -FILE_MISSING_NEWLINE = 300 -FILE_IN_BLOCK = 301 - -# Interfaces -INTERFACE_CONSTRUCTOR_CANNOT_HAVE_PARAMS = 400 -INTERFACE_METHOD_CANNOT_HAVE_CODE = 401 - -# Comments -MISSING_END_OF_SCOPE_COMMENT = 500 -MALFORMED_END_OF_SCOPE_COMMENT = 501 - -# goog.scope - Namespace aliasing -# TODO(nnaze) Add additional errors here and in aliaspass.py -INVALID_USE_OF_GOOG_SCOPE = 600 -EXTRA_GOOG_SCOPE_USAGE = 601 - -# ActionScript specific errors: -# TODO(user): move these errors to their own file and move all JavaScript -# specific errors to their own file as well. -# All ActionScript specific errors should have error number at least 1000. -FUNCTION_MISSING_RETURN_TYPE = 1132 -PARAMETER_MISSING_TYPE = 1133 -VAR_MISSING_TYPE = 1134 -PARAMETER_MISSING_DEFAULT_VALUE = 1135 -IMPORTS_NOT_ALPHABETIZED = 1140 -IMPORT_CONTAINS_WILDCARD = 1141 -UNUSED_IMPORT = 1142 -INVALID_TRACE_SEVERITY_LEVEL = 1250 -MISSING_TRACE_SEVERITY_LEVEL = 1251 -MISSING_TRACE_MESSAGE = 1252 -REMOVE_TRACE_BEFORE_SUBMIT = 1253 -REMOVE_COMMENT_BEFORE_SUBMIT = 1254 -# End of list of ActionScript specific errors. - -NEW_ERRORS = frozenset([ - # Errors added after 2.0.2: - WRONG_INDENTATION, - MISSING_SEMICOLON, - # Errors added after 2.3.9: - JSDOC_MISSING_VAR_ARGS_TYPE, - JSDOC_MISSING_VAR_ARGS_NAME, - # Errors added after 2.3.15: - ALIAS_STMT_NEEDS_GOOG_REQUIRE, - JSDOC_DOES_NOT_PARSE, - LINE_ENDS_WITH_DOT, - # Errors added after 2.3.19: - ])
diff --git a/third_party/closure_linter/closure_linter/fixjsstyle.py b/third_party/closure_linter/closure_linter/fixjsstyle.py deleted file mode 100755 index 2d65e03..0000000 --- a/third_party/closure_linter/closure_linter/fixjsstyle.py +++ /dev/null
@@ -1,66 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Automatically fix simple style guide violations.""" - -__author__ = 'robbyw@google.com (Robert Walker)' - -import StringIO -import sys - -import gflags as flags - -from closure_linter import error_fixer -from closure_linter import runner -from closure_linter.common import simplefileflags as fileflags - -FLAGS = flags.FLAGS -flags.DEFINE_list('additional_extensions', None, 'List of additional file ' - 'extensions (not js) that should be treated as ' - 'JavaScript files.') -flags.DEFINE_boolean('dry_run', False, 'Do not modify the file, only print it.') - - -def main(argv=None): - """Main function. - - Args: - argv: Sequence of command line arguments. - """ - if argv is None: - argv = flags.FLAGS(sys.argv) - - suffixes = ['.js'] - if FLAGS.additional_extensions: - suffixes += ['.%s' % ext for ext in FLAGS.additional_extensions] - - files = fileflags.GetFileList(argv, 'JavaScript', suffixes) - - output_buffer = None - if FLAGS.dry_run: - output_buffer = StringIO.StringIO() - - fixer = error_fixer.ErrorFixer(output_buffer) - - # Check the list of files. - for filename in files: - runner.Run(filename, fixer) - if FLAGS.dry_run: - print output_buffer.getvalue() - - -if __name__ == '__main__': - main()
diff --git a/third_party/closure_linter/closure_linter/fixjsstyle_test.py b/third_party/closure_linter/closure_linter/fixjsstyle_test.py deleted file mode 100755 index 34de3f8..0000000 --- a/third_party/closure_linter/closure_linter/fixjsstyle_test.py +++ /dev/null
@@ -1,615 +0,0 @@ -#!/usr/bin/env python -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Medium tests for the gpylint auto-fixer.""" - -__author__ = 'robbyw@google.com (Robby Walker)' - -import StringIO - -import gflags as flags -import unittest as googletest -from closure_linter import error_fixer -from closure_linter import runner - - -_RESOURCE_PREFIX = 'closure_linter/testdata' - -flags.FLAGS.strict = True -flags.FLAGS.limited_doc_files = ('dummy.js', 'externs.js') -flags.FLAGS.closurized_namespaces = ('goog', 'dummy') - - -class FixJsStyleTest(googletest.TestCase): - """Test case to for gjslint auto-fixing.""" - - def setUp(self): - flags.FLAGS.dot_on_next_line = True - - def tearDown(self): - flags.FLAGS.dot_on_next_line = False - - def testFixJsStyle(self): - test_cases = [ - ['fixjsstyle.in.js', 'fixjsstyle.out.js'], - ['indentation.js', 'fixjsstyle.indentation.out.js'], - ['fixjsstyle.html.in.html', 'fixjsstyle.html.out.html'], - ['fixjsstyle.oplineend.in.js', 'fixjsstyle.oplineend.out.js']] - for [running_input_file, running_output_file] in test_cases: - print 'Checking %s vs %s' % (running_input_file, running_output_file) - input_filename = None - golden_filename = None - current_filename = None - try: - input_filename = '%s/%s' % (_RESOURCE_PREFIX, running_input_file) - current_filename = input_filename - - golden_filename = '%s/%s' % (_RESOURCE_PREFIX, running_output_file) - current_filename = golden_filename - except IOError as ex: - raise IOError('Could not find testdata resource for %s: %s' % - (current_filename, ex)) - - if running_input_file == 'fixjsstyle.in.js': - with open(input_filename) as f: - for line in f: - # Go to last line. - pass - self.assertTrue(line == line.rstrip(), '%s file should not end ' - 'with a new line.' % (input_filename)) - - # Autofix the file, sending output to a fake file. - actual = StringIO.StringIO() - runner.Run(input_filename, error_fixer.ErrorFixer(actual)) - - # Now compare the files. - actual.seek(0) - expected = open(golden_filename, 'r') - - # Uncomment to generate new golden files and run - # open('/'.join(golden_filename.split('/')[4:]), 'w').write(actual.read()) - # actual.seek(0) - - self.assertEqual(actual.readlines(), expected.readlines()) - - def testAddProvideFirstLine(self): - """Tests handling of case where goog.provide is added.""" - original = [ - 'dummy.bb.cc = 1;', - ] - - expected = [ - 'goog.provide(\'dummy.bb\');', - '', - 'dummy.bb.cc = 1;', - ] - - self._AssertFixes(original, expected, include_header=False) - - original = [ - '', - 'dummy.bb.cc = 1;', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testAddRequireFirstLine(self): - """Tests handling of case where goog.require is added.""" - original = [ - 'a = dummy.bb.cc;', - ] - - expected = [ - 'goog.require(\'dummy.bb\');', - '', - 'a = dummy.bb.cc;', - ] - - self._AssertFixes(original, expected, include_header=False) - - original = [ - '', - 'a = dummy.bb.cc;', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testDeleteProvideAndAddProvideFirstLine(self): - """Tests handling of case where goog.provide is deleted and added. - - Bug 14832597. - """ - original = [ - 'goog.provide(\'dummy.aa\');', - '', - 'dummy.bb.cc = 1;', - ] - - expected = [ - 'goog.provide(\'dummy.bb\');', - '', - 'dummy.bb.cc = 1;', - ] - - self._AssertFixes(original, expected, include_header=False) - - original = [ - 'goog.provide(\'dummy.aa\');', - 'dummy.bb.cc = 1;', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testDeleteProvideAndAddRequireFirstLine(self): - """Tests handling where goog.provide is deleted and goog.require added. - - Bug 14832597. - """ - original = [ - 'goog.provide(\'dummy.aa\');', - '', - 'a = dummy.bb.cc;', - ] - - expected = [ - 'goog.require(\'dummy.bb\');', - '', - 'a = dummy.bb.cc;', - ] - - self._AssertFixes(original, expected, include_header=False) - - original = [ - 'goog.provide(\'dummy.aa\');', - 'a = dummy.bb.cc;', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testDeleteRequireAndAddRequireFirstLine(self): - """Tests handling of case where goog.require is deleted and added. - - Bug 14832597. - """ - original = [ - 'goog.require(\'dummy.aa\');', - '', - 'a = dummy.bb.cc;', - ] - - expected = [ - 'goog.require(\'dummy.bb\');', - '', - 'a = dummy.bb.cc;', - ] - - self._AssertFixes(original, expected, include_header=False) - - original = [ - 'goog.require(\'dummy.aa\');', - 'a = dummy.bb.cc;', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testDeleteRequireAndAddProvideFirstLine(self): - """Tests handling where goog.require is deleted and goog.provide added. - - Bug 14832597. - """ - original = [ - 'goog.require(\'dummy.aa\');', - '', - 'dummy.bb.cc = 1;', - ] - - expected = [ - 'goog.provide(\'dummy.bb\');', - '', - 'dummy.bb.cc = 1;', - ] - - self._AssertFixes(original, expected, include_header=False) - - original = [ - 'goog.require(\'dummy.aa\');', - 'dummy.bb.cc = 1;', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testMultipleProvideInsert(self): - original = [ - 'goog.provide(\'dummy.bb\');', - 'goog.provide(\'dummy.dd\');', - '', - 'dummy.aa.ff = 1;', - 'dummy.bb.ff = 1;', - 'dummy.cc.ff = 1;', - 'dummy.dd.ff = 1;', - 'dummy.ee.ff = 1;', - ] - - expected = [ - 'goog.provide(\'dummy.aa\');', - 'goog.provide(\'dummy.bb\');', - 'goog.provide(\'dummy.cc\');', - 'goog.provide(\'dummy.dd\');', - 'goog.provide(\'dummy.ee\');', - '', - 'dummy.aa.ff = 1;', - 'dummy.bb.ff = 1;', - 'dummy.cc.ff = 1;', - 'dummy.dd.ff = 1;', - 'dummy.ee.ff = 1;', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testMultipleRequireInsert(self): - original = [ - 'goog.require(\'dummy.bb\');', - 'goog.require(\'dummy.dd\');', - '', - 'a = dummy.aa.ff;', - 'b = dummy.bb.ff;', - 'c = dummy.cc.ff;', - 'd = dummy.dd.ff;', - 'e = dummy.ee.ff;', - ] - - expected = [ - 'goog.require(\'dummy.aa\');', - 'goog.require(\'dummy.bb\');', - 'goog.require(\'dummy.cc\');', - 'goog.require(\'dummy.dd\');', - 'goog.require(\'dummy.ee\');', - '', - 'a = dummy.aa.ff;', - 'b = dummy.bb.ff;', - 'c = dummy.cc.ff;', - 'd = dummy.dd.ff;', - 'e = dummy.ee.ff;', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testUnsortedRequires(self): - """Tests handling of unsorted goog.require statements without header. - - Bug 8398202. - """ - original = [ - 'goog.require(\'dummy.aa\');', - 'goog.require(\'dummy.Cc\');', - 'goog.require(\'dummy.Dd\');', - '', - 'function a() {', - ' dummy.aa.i = 1;', - ' dummy.Cc.i = 1;', - ' dummy.Dd.i = 1;', - '}', - ] - - expected = [ - 'goog.require(\'dummy.Cc\');', - 'goog.require(\'dummy.Dd\');', - 'goog.require(\'dummy.aa\');', - '', - 'function a() {', - ' dummy.aa.i = 1;', - ' dummy.Cc.i = 1;', - ' dummy.Dd.i = 1;', - '}', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testMissingExtraAndUnsortedRequires(self): - """Tests handling of missing extra and unsorted goog.require statements.""" - original = [ - 'goog.require(\'dummy.aa\');', - 'goog.require(\'dummy.Cc\');', - 'goog.require(\'dummy.Dd\');', - '', - 'var x = new dummy.Bb();', - 'dummy.Cc.someMethod();', - 'dummy.aa.someMethod();', - ] - - expected = [ - 'goog.require(\'dummy.Bb\');', - 'goog.require(\'dummy.Cc\');', - 'goog.require(\'dummy.aa\');', - '', - 'var x = new dummy.Bb();', - 'dummy.Cc.someMethod();', - 'dummy.aa.someMethod();', - ] - - self._AssertFixes(original, expected) - - def testExtraRequireOnFirstLine(self): - """Tests handling of extra goog.require statement on the first line. - - There was a bug when fixjsstyle quits with an exception. It happened if - - the first line of the file is an extra goog.require() statement, - - goog.require() statements are not sorted. - """ - original = [ - 'goog.require(\'dummy.aa\');', - 'goog.require(\'dummy.cc\');', - 'goog.require(\'dummy.bb\');', - '', - 'var x = new dummy.bb();', - 'var y = new dummy.cc();', - ] - - expected = [ - 'goog.require(\'dummy.bb\');', - 'goog.require(\'dummy.cc\');', - '', - 'var x = new dummy.bb();', - 'var y = new dummy.cc();', - ] - - self._AssertFixes(original, expected, include_header=False) - - def testUnsortedProvides(self): - """Tests handling of unsorted goog.provide statements without header. - - Bug 8398202. - """ - original = [ - 'goog.provide(\'dummy.aa\');', - 'goog.provide(\'dummy.Cc\');', - 'goog.provide(\'dummy.Dd\');', - '', - 'dummy.aa = function() {};' - 'dummy.Cc = function() {};' - 'dummy.Dd = function() {};' - ] - - expected = [ - 'goog.provide(\'dummy.Cc\');', - 'goog.provide(\'dummy.Dd\');', - 'goog.provide(\'dummy.aa\');', - '', - 'dummy.aa = function() {};' - 'dummy.Cc = function() {};' - 'dummy.Dd = function() {};' - ] - - self._AssertFixes(original, expected, include_header=False) - - def testMissingExtraAndUnsortedProvides(self): - """Tests handling of missing extra and unsorted goog.provide statements.""" - original = [ - 'goog.provide(\'dummy.aa\');', - 'goog.provide(\'dummy.Cc\');', - 'goog.provide(\'dummy.Dd\');', - '', - 'dummy.Cc = function() {};', - 'dummy.Bb = function() {};', - 'dummy.aa.someMethod = function();', - ] - - expected = [ - 'goog.provide(\'dummy.Bb\');', - 'goog.provide(\'dummy.Cc\');', - 'goog.provide(\'dummy.aa\');', - '', - 'dummy.Cc = function() {};', - 'dummy.Bb = function() {};', - 'dummy.aa.someMethod = function();', - ] - - self._AssertFixes(original, expected) - - def testNoRequires(self): - """Tests positioning of missing requires without existing requires.""" - original = [ - 'goog.provide(\'dummy.Something\');', - '', - 'dummy.Something = function() {};', - '', - 'var x = new dummy.Bb();', - ] - - expected = [ - 'goog.provide(\'dummy.Something\');', - '', - 'goog.require(\'dummy.Bb\');', - '', - 'dummy.Something = function() {};', - '', - 'var x = new dummy.Bb();', - ] - - self._AssertFixes(original, expected) - - def testNoProvides(self): - """Tests positioning of missing provides without existing provides.""" - original = [ - 'goog.require(\'dummy.Bb\');', - '', - 'dummy.Something = function() {};', - '', - 'var x = new dummy.Bb();', - ] - - expected = [ - 'goog.provide(\'dummy.Something\');', - '', - 'goog.require(\'dummy.Bb\');', - '', - 'dummy.Something = function() {};', - '', - 'var x = new dummy.Bb();', - ] - - self._AssertFixes(original, expected) - - def testOutputOkayWhenFirstTokenIsDeleted(self): - """Tests that autofix output is is correct when first token is deleted. - - Regression test for bug 4581567 - """ - original = ['"use strict";'] - expected = ["'use strict';"] - - self._AssertFixes(original, expected, include_header=False) - - def testGoogScopeIndentation(self): - """Tests Handling a typical end-of-scope indentation fix.""" - original = [ - 'goog.scope(function() {', - ' // TODO(brain): Take over the world.', - '}); // goog.scope', - ] - - expected = [ - 'goog.scope(function() {', - '// TODO(brain): Take over the world.', - '}); // goog.scope', - ] - - self._AssertFixes(original, expected) - - def testMissingEndOfScopeComment(self): - """Tests Handling a missing comment at end of goog.scope.""" - original = [ - 'goog.scope(function() {', - '});', - ] - - expected = [ - 'goog.scope(function() {', - '}); // goog.scope', - ] - - self._AssertFixes(original, expected) - - def testMissingEndOfScopeCommentWithOtherComment(self): - """Tests handling an irrelevant comment at end of goog.scope.""" - original = [ - 'goog.scope(function() {', - "}); // I don't belong here!", - ] - - expected = [ - 'goog.scope(function() {', - '}); // goog.scope', - ] - - self._AssertFixes(original, expected) - - def testMalformedEndOfScopeComment(self): - """Tests Handling a malformed comment at end of goog.scope.""" - original = [ - 'goog.scope(function() {', - '}); // goog.scope FTW', - ] - - expected = [ - 'goog.scope(function() {', - '}); // goog.scope', - ] - - self._AssertFixes(original, expected) - - def testEndsWithIdentifier(self): - """Tests Handling case where script ends with identifier. Bug 7643404.""" - original = [ - 'goog.provide(\'xyz\');', - '', - 'abc' - ] - - expected = [ - 'goog.provide(\'xyz\');', - '', - 'abc;' - ] - - self._AssertFixes(original, expected) - - def testFileStartsWithSemicolon(self): - """Tests handling files starting with semicolon. - - b/10062516 - """ - original = [ - ';goog.provide(\'xyz\');', - '', - 'abc;' - ] - - expected = [ - 'goog.provide(\'xyz\');', - '', - 'abc;' - ] - - self._AssertFixes(original, expected, include_header=False) - - def testCodeStartsWithSemicolon(self): - """Tests handling code in starting with semicolon after comments. - - b/10062516 - """ - original = [ - ';goog.provide(\'xyz\');', - '', - 'abc;' - ] - - expected = [ - 'goog.provide(\'xyz\');', - '', - 'abc;' - ] - - self._AssertFixes(original, expected) - - def _AssertFixes(self, original, expected, include_header=True): - """Asserts that the error fixer corrects original to expected.""" - if include_header: - original = self._GetHeader() + original - expected = self._GetHeader() + expected - - actual = StringIO.StringIO() - runner.Run('testing.js', error_fixer.ErrorFixer(actual), original) - actual.seek(0) - - expected = [x + '\n' for x in expected] - - self.assertListEqual(actual.readlines(), expected) - - def _GetHeader(self): - """Returns a fake header for a JavaScript file.""" - return [ - '// Copyright 2011 Google Inc. All Rights Reserved.', - '', - '/**', - ' * @fileoverview Fake file overview.', - ' * @author fake@google.com (Fake Person)', - ' */', - '' - ] - - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/full_test.py b/third_party/closure_linter/closure_linter/full_test.py deleted file mode 100755 index e69a8c09..0000000 --- a/third_party/closure_linter/closure_linter/full_test.py +++ /dev/null
@@ -1,122 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Full regression-type (Medium) tests for gjslint. - -Tests every error that can be thrown by gjslint. Based heavily on -devtools/javascript/gpylint/full_test.py -""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -import os -import sys -import unittest - -import gflags as flags -import unittest as googletest - -from closure_linter import error_check -from closure_linter import errors -from closure_linter import runner -from closure_linter.common import filetestcase - -_RESOURCE_PREFIX = 'closure_linter/testdata' - -flags.FLAGS.strict = True -flags.FLAGS.custom_jsdoc_tags = ('customtag', 'requires') -flags.FLAGS.closurized_namespaces = ('goog', 'dummy') -flags.FLAGS.limited_doc_files = ('externs.js', 'dummy.js', - 'limited_doc_checks.js') -flags.FLAGS.jslint_error = error_check.Rule.ALL - -# List of files under testdata to test. -# We need to list files explicitly since pyglib can't list directories. -# TODO(user): Figure out how to list the directory. -_TEST_FILES = [ - 'all_js_wrapped.js', - 'blank_lines.js', - 'ends_with_block.js', - 'empty_file.js', - 'externs.js', - 'externs_jsdoc.js', - 'goog_scope.js', - 'html_parse_error.html', - 'indentation.js', - 'interface.js', - 'jsdoc.js', - 'limited_doc_checks.js', - 'minimal.js', - 'other.js', - 'provide_blank.js', - 'provide_extra.js', - 'provide_missing.js', - 'require_alias.js', - 'require_all_caps.js', - 'require_blank.js', - 'require_extra.js', - 'require_function.js', - 'require_function_missing.js', - 'require_function_through_both.js', - 'require_function_through_namespace.js', - 'require_interface.js', - 'require_interface_alias.js', - 'require_interface_base.js', - 'require_lower_case.js', - 'require_missing.js', - 'require_numeric.js', - 'require_provide_blank.js', - 'require_provide_missing.js', - 'require_provide_ok.js', - 'semicolon_missing.js', - 'semicolon_missing2.js', - 'simple.html', - 'spaces.js', - 'tokenizer.js', - 'unparseable.js', - 'unused_local_variables.js', - 'unused_private_members.js', - 'utf8.html', -] - - -class GJsLintTestSuite(unittest.TestSuite): - """Test suite to run a GJsLintTest for each of several files. - - If sys.argv[1:] is non-empty, it is interpreted as a list of filenames in - testdata to test. Otherwise, _TEST_FILES is used. - """ - - def __init__(self, tests=()): - unittest.TestSuite.__init__(self, tests) - - argv = sys.argv and sys.argv[1:] or [] - if argv: - test_files = argv - else: - test_files = _TEST_FILES - for test_file in test_files: - resource_path = os.path.join(_RESOURCE_PREFIX, test_file) - self.addTest( - filetestcase.AnnotatedFileTestCase( - resource_path, - runner.Run, - errors.ByName)) - -if __name__ == '__main__': - # Don't let main parse args; it happens in the TestSuite. - googletest.main(argv=sys.argv[0:1], defaultTest='GJsLintTestSuite')
diff --git a/third_party/closure_linter/closure_linter/gjslint.py b/third_party/closure_linter/closure_linter/gjslint.py deleted file mode 100755 index b67c5a98..0000000 --- a/third_party/closure_linter/closure_linter/gjslint.py +++ /dev/null
@@ -1,327 +0,0 @@ -#!/usr/bin/env python -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Checks JavaScript files for common style guide violations. - -gjslint.py is designed to be used as a PRESUBMIT script to check for javascript -style guide violations. As of now, it checks for the following violations: - - * Missing and extra spaces - * Lines longer than 80 characters - * Missing newline at end of file - * Missing semicolon after function declaration - * Valid JsDoc including parameter matching - -Someday it will validate to the best of its ability against the entirety of the -JavaScript style guide. - -This file is a front end that parses arguments and flags. The core of the code -is in tokenizer.py and checker.py. -""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)', - 'nnaze@google.com (Nathan Naze)',) - -import errno -import itertools -import os -import platform -import re -import sys -import time - -import gflags as flags - -from closure_linter import errorrecord -from closure_linter import runner -from closure_linter.common import erroraccumulator -from closure_linter.common import simplefileflags as fileflags - -# Attempt import of multiprocessing (should be available in Python 2.6 and up). -try: - # pylint: disable=g-import-not-at-top - import multiprocessing -except ImportError: - multiprocessing = None - -FLAGS = flags.FLAGS -flags.DEFINE_boolean('unix_mode', False, - 'Whether to emit warnings in standard unix format.') -flags.DEFINE_boolean('beep', True, 'Whether to beep when errors are found.') -flags.DEFINE_boolean('time', False, 'Whether to emit timing statistics.') -flags.DEFINE_boolean('quiet', False, 'Whether to minimize logged messages. ' - 'Most useful for per-file linting, such as that performed ' - 'by the presubmit linter service.') -flags.DEFINE_boolean('check_html', False, - 'Whether to check javascript in html files.') -flags.DEFINE_boolean('summary', False, - 'Whether to show an error count summary.') -flags.DEFINE_list('additional_extensions', None, 'List of additional file ' - 'extensions (not js) that should be treated as ' - 'JavaScript files.') -flags.DEFINE_boolean('multiprocess', - platform.system() is 'Linux' and bool(multiprocessing), - 'Whether to attempt parallelized linting using the ' - 'multiprocessing module. Enabled by default on Linux ' - 'if the multiprocessing module is present (Python 2.6+). ' - 'Otherwise disabled by default. ' - 'Disabling may make debugging easier.') -flags.ADOPT_module_key_flags(fileflags) -flags.ADOPT_module_key_flags(runner) - - -GJSLINT_ONLY_FLAGS = ['--unix_mode', '--beep', '--nobeep', '--time', - '--check_html', '--summary', '--quiet'] - - - -def _MultiprocessCheckPaths(paths): - """Run _CheckPath over mutltiple processes. - - Tokenization, passes, and checks are expensive operations. Running in a - single process, they can only run on one CPU/core. Instead, - shard out linting over all CPUs with multiprocessing to parallelize. - - Args: - paths: paths to check. - - Yields: - errorrecord.ErrorRecords for any found errors. - """ - - pool = multiprocessing.Pool() - - path_results = pool.imap(_CheckPath, paths) - for results in path_results: - for result in results: - yield result - - # Force destruct before returning, as this can sometimes raise spurious - # "interrupted system call" (EINTR), which we can ignore. - try: - pool.close() - pool.join() - del pool - except OSError as err: - if err.errno is not errno.EINTR: - raise err - - -def _CheckPaths(paths): - """Run _CheckPath on all paths in one thread. - - Args: - paths: paths to check. - - Yields: - errorrecord.ErrorRecords for any found errors. - """ - - for path in paths: - results = _CheckPath(path) - for record in results: - yield record - - -def _CheckPath(path): - """Check a path and return any errors. - - Args: - path: paths to check. - - Returns: - A list of errorrecord.ErrorRecords for any found errors. - """ - - error_handler = erroraccumulator.ErrorAccumulator() - runner.Run(path, error_handler) - - make_error_record = lambda err: errorrecord.MakeErrorRecord(path, err) - return map(make_error_record, error_handler.GetErrors()) - - -def _GetFilePaths(argv): - suffixes = ['.js'] - if FLAGS.additional_extensions: - suffixes += ['.%s' % ext for ext in FLAGS.additional_extensions] - if FLAGS.check_html: - suffixes += ['.html', '.htm'] - return fileflags.GetFileList(argv, 'JavaScript', suffixes) - - -# Error printing functions - - -def _PrintFileSummary(paths, records): - """Print a detailed summary of the number of errors in each file.""" - - paths = list(paths) - paths.sort() - - for path in paths: - path_errors = [e for e in records if e.path == path] - print '%s: %d' % (path, len(path_errors)) - - -def _PrintFileSeparator(path): - print '----- FILE : %s -----' % path - - -def _PrintSummary(paths, error_records): - """Print a summary of the number of errors and files.""" - - error_count = len(error_records) - all_paths = set(paths) - all_paths_count = len(all_paths) - - if error_count is 0: - print '%d files checked, no errors found.' % all_paths_count - - new_error_count = len([e for e in error_records if e.new_error]) - - error_paths = set([e.path for e in error_records]) - error_paths_count = len(error_paths) - no_error_paths_count = all_paths_count - error_paths_count - - if (error_count or new_error_count) and not FLAGS.quiet: - error_noun = 'error' if error_count == 1 else 'errors' - new_error_noun = 'error' if new_error_count == 1 else 'errors' - error_file_noun = 'file' if error_paths_count == 1 else 'files' - ok_file_noun = 'file' if no_error_paths_count == 1 else 'files' - print ('Found %d %s, including %d new %s, in %d %s (%d %s OK).' % - (error_count, - error_noun, - new_error_count, - new_error_noun, - error_paths_count, - error_file_noun, - no_error_paths_count, - ok_file_noun)) - - -def _PrintErrorRecords(error_records): - """Print error records strings in the expected format.""" - - current_path = None - for record in error_records: - - if current_path != record.path: - current_path = record.path - if not FLAGS.unix_mode: - _PrintFileSeparator(current_path) - - print record.error_string - - -def _FormatTime(t): - """Formats a duration as a human-readable string. - - Args: - t: A duration in seconds. - - Returns: - A formatted duration string. - """ - if t < 1: - return '%dms' % round(t * 1000) - else: - return '%.2fs' % t - - - - -def main(argv=None): - """Main function. - - Args: - argv: Sequence of command line arguments. - """ - if argv is None: - argv = flags.FLAGS(sys.argv) - - if FLAGS.time: - start_time = time.time() - - # Emacs sets the environment variable INSIDE_EMACS in the subshell. - # Request Unix mode as emacs will expect output to be in Unix format - # for integration. - # See https://www.gnu.org/software/emacs/manual/html_node/emacs/ - # Interactive-Shell.html - if 'INSIDE_EMACS' in os.environ: - FLAGS.unix_mode = True - - suffixes = ['.js'] - if FLAGS.additional_extensions: - suffixes += ['.%s' % ext for ext in FLAGS.additional_extensions] - if FLAGS.check_html: - suffixes += ['.html', '.htm'] - paths = fileflags.GetFileList(argv, 'JavaScript', suffixes) - - if FLAGS.multiprocess: - records_iter = _MultiprocessCheckPaths(paths) - else: - records_iter = _CheckPaths(paths) - - records_iter, records_iter_copy = itertools.tee(records_iter, 2) - _PrintErrorRecords(records_iter_copy) - - error_records = list(records_iter) - _PrintSummary(paths, error_records) - - exit_code = 0 - - # If there are any errors - if error_records: - exit_code += 1 - - # If there are any new errors - if [r for r in error_records if r.new_error]: - exit_code += 2 - - if exit_code: - if FLAGS.summary: - _PrintFileSummary(paths, error_records) - - if FLAGS.beep: - # Make a beep noise. - sys.stdout.write(chr(7)) - - # Write out instructions for using fixjsstyle script to fix some of the - # reported errors. - fix_args = [] - for flag in sys.argv[1:]: - for f in GJSLINT_ONLY_FLAGS: - if flag.startswith(f): - break - else: - fix_args.append(flag) - - if not FLAGS.quiet: - print """ -Some of the errors reported by GJsLint may be auto-fixable using the script -fixjsstyle. Please double check any changes it makes and report any bugs. The -script can be run by executing: - -fixjsstyle %s """ % ' '.join(fix_args) - - if FLAGS.time: - print 'Done in %s.' % _FormatTime(time.time() - start_time) - - sys.exit(exit_code) - - -if __name__ == '__main__': - main()
diff --git a/third_party/closure_linter/closure_linter/indentation.py b/third_party/closure_linter/closure_linter/indentation.py deleted file mode 100755 index d48ad2b8..0000000 --- a/third_party/closure_linter/closure_linter/indentation.py +++ /dev/null
@@ -1,617 +0,0 @@ -#!/usr/bin/env python -# Copyright 2010 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Methods for checking EcmaScript files for indentation issues.""" - -__author__ = ('robbyw@google.com (Robert Walker)') - -import gflags as flags - -from closure_linter import ecmametadatapass -from closure_linter import errors -from closure_linter import javascripttokens -from closure_linter import tokenutil -from closure_linter.common import error -from closure_linter.common import position - - -flags.DEFINE_boolean('debug_indentation', False, - 'Whether to print debugging information for indentation.') - - -# Shorthand -Context = ecmametadatapass.EcmaContext -Error = error.Error -Position = position.Position -Type = javascripttokens.JavaScriptTokenType - - -# The general approach: -# -# 1. Build a stack of tokens that can affect indentation. -# For each token, we determine if it is a block or continuation token. -# Some tokens need to be temporarily overwritten in case they are removed -# before the end of the line. -# Much of the work here is determining which tokens to keep on the stack -# at each point. Operators, for example, should be removed once their -# expression or line is gone, while parentheses must stay until the matching -# end parentheses is found. -# -# 2. Given that stack, determine the allowable indentations. -# Due to flexible indentation rules in JavaScript, there may be many -# allowable indentations for each stack. We follows the general -# "no false positives" approach of GJsLint and build the most permissive -# set possible. - - -class TokenInfo(object): - """Stores information about a token. - - Attributes: - token: The token - is_block: Whether the token represents a block indentation. - is_transient: Whether the token should be automatically removed without - finding a matching end token. - overridden_by: TokenInfo for a token that overrides the indentation that - this token would require. - is_permanent_override: Whether the override on this token should persist - even after the overriding token is removed from the stack. For example: - x([ - 1], - 2); - needs this to be set so the last line is not required to be a continuation - indent. - line_number: The effective line number of this token. Will either be the - actual line number or the one before it in the case of a mis-wrapped - operator. - """ - - def __init__(self, token, is_block=False): - """Initializes a TokenInfo object. - - Args: - token: The token - is_block: Whether the token represents a block indentation. - """ - self.token = token - self.overridden_by = None - self.is_permanent_override = False - self.is_block = is_block - self.is_transient = not is_block and token.type not in ( - Type.START_PAREN, Type.START_PARAMETERS) - self.line_number = token.line_number - - def __repr__(self): - result = '\n %s' % self.token - if self.overridden_by: - result = '%s OVERRIDDEN [by "%s"]' % ( - result, self.overridden_by.token.string) - result += ' {is_block: %s, is_transient: %s}' % ( - self.is_block, self.is_transient) - return result - - -class IndentationRules(object): - """EmcaScript indentation rules. - - Can be used to find common indentation errors in JavaScript, ActionScript and - other Ecma like scripting languages. - """ - - def __init__(self): - """Initializes the IndentationRules checker.""" - self._stack = [] - - # Map from line number to number of characters it is off in indentation. - self._start_index_offset = {} - - def Finalize(self): - if self._stack: - old_stack = self._stack - self._stack = [] - raise Exception('INTERNAL ERROR: indentation stack is not empty: %r' % - old_stack) - - def CheckToken(self, token, state): - """Checks a token for indentation errors. - - Args: - token: The current token under consideration - state: Additional information about the current tree state - - Returns: - An error array [error code, error string, error token] if the token is - improperly indented, or None if indentation is correct. - """ - - token_type = token.type - indentation_errors = [] - stack = self._stack - is_first = self._IsFirstNonWhitespaceTokenInLine(token) - - # Add tokens that could decrease indentation before checking. - if token_type == Type.END_PAREN: - self._PopTo(Type.START_PAREN) - - elif token_type == Type.END_PARAMETERS: - self._PopTo(Type.START_PARAMETERS) - - elif token_type == Type.END_BRACKET: - self._PopTo(Type.START_BRACKET) - - elif token_type == Type.END_BLOCK: - start_token = self._PopTo(Type.START_BLOCK) - # Check for required goog.scope comment. - if start_token: - goog_scope = tokenutil.GoogScopeOrNoneFromStartBlock(start_token.token) - if goog_scope is not None: - if not token.line.endswith('; // goog.scope\n'): - if (token.line.find('//') > -1 and - token.line.find('goog.scope') > - token.line.find('//')): - indentation_errors.append([ - errors.MALFORMED_END_OF_SCOPE_COMMENT, - ('Malformed end of goog.scope comment. Please use the ' - 'exact following syntax to close the scope:\n' - '}); // goog.scope'), - token, - Position(token.start_index, token.length)]) - else: - indentation_errors.append([ - errors.MISSING_END_OF_SCOPE_COMMENT, - ('Missing comment for end of goog.scope which opened at line ' - '%d. End the scope with:\n' - '}); // goog.scope' % - (start_token.line_number)), - token, - Position(token.start_index, token.length)]) - - elif token_type == Type.KEYWORD and token.string in ('case', 'default'): - self._Add(self._PopTo(Type.START_BLOCK)) - - elif token_type == Type.SEMICOLON: - self._PopTransient() - - if (is_first and - token_type not in (Type.COMMENT, Type.DOC_PREFIX, Type.STRING_TEXT)): - if flags.FLAGS.debug_indentation: - print 'Line #%d: stack %r' % (token.line_number, stack) - - # Ignore lines that start in JsDoc since we don't check them properly yet. - # TODO(robbyw): Support checking JsDoc indentation. - # Ignore lines that start as multi-line strings since indentation is N/A. - # Ignore lines that start with operators since we report that already. - # Ignore lines with tabs since we report that already. - expected = self._GetAllowableIndentations() - actual = self._GetActualIndentation(token) - - # Special case comments describing else, case, and default. Allow them - # to outdent to the parent block. - if token_type in Type.COMMENT_TYPES: - next_code = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES) - if next_code and next_code.type == Type.END_BLOCK: - next_code = tokenutil.SearchExcept(next_code, Type.NON_CODE_TYPES) - if next_code and next_code.string in ('else', 'case', 'default'): - # TODO(robbyw): This almost certainly introduces false negatives. - expected |= self._AddToEach(expected, -2) - - if actual >= 0 and actual not in expected: - expected = sorted(expected) - indentation_errors.append([ - errors.WRONG_INDENTATION, - 'Wrong indentation: expected any of {%s} but got %d' % ( - ', '.join('%d' % x for x in expected if x < 80), actual), - token, - Position(actual, expected[0])]) - self._start_index_offset[token.line_number] = expected[0] - actual - - # Add tokens that could increase indentation. - if token_type == Type.START_BRACKET: - self._Add(TokenInfo( - token=token, - is_block=token.metadata.context.type == Context.ARRAY_LITERAL)) - - elif token_type == Type.START_BLOCK or token.metadata.is_implied_block: - self._Add(TokenInfo(token=token, is_block=True)) - - elif token_type in (Type.START_PAREN, Type.START_PARAMETERS): - self._Add(TokenInfo(token=token, is_block=False)) - - elif token_type == Type.KEYWORD and token.string == 'return': - self._Add(TokenInfo(token)) - - elif not token.IsLastInLine() and ( - token.IsAssignment() or token.IsOperator('?')): - self._Add(TokenInfo(token=token)) - - # Handle implied block closes. - if token.metadata.is_implied_block_close: - self._PopToImpliedBlock() - - # Add some tokens only if they appear at the end of the line. - is_last = self._IsLastCodeInLine(token) - if is_last: - next_code_token = tokenutil.GetNextCodeToken(token) - # Increase required indentation if this is an overlong wrapped statement - # ending in an operator. - if token_type == Type.OPERATOR: - if token.string == ':': - if stack and stack[-1].token.string == '?': - # When a ternary : is on a different line than its '?', it doesn't - # add indentation. - if token.line_number == stack[-1].token.line_number: - self._Add(TokenInfo(token)) - elif token.metadata.context.type == Context.CASE_BLOCK: - # Pop transient tokens from say, line continuations, e.g., - # case x. - # y: - # Want to pop the transient 4 space continuation indent. - self._PopTransient() - # Starting the body of the case statement, which is a type of - # block. - self._Add(TokenInfo(token=token, is_block=True)) - elif token.metadata.context.type == Context.LITERAL_ELEMENT: - # When in an object literal, acts as operator indicating line - # continuations. - self._Add(TokenInfo(token)) - else: - # ':' might also be a statement label, no effect on indentation in - # this case. - pass - - elif token.string != ',': - self._Add(TokenInfo(token)) - else: - # The token is a comma. - if token.metadata.context.type == Context.VAR: - self._Add(TokenInfo(token)) - elif token.metadata.context.type != Context.PARAMETERS: - self._PopTransient() - # Increase required indentation if this is the end of a statement that's - # continued with an operator on the next line (e.g. the '.'). - elif (next_code_token and next_code_token.type == Type.OPERATOR and - not next_code_token.metadata.IsUnaryOperator()): - self._Add(TokenInfo(token)) - elif token_type == Type.PARAMETERS and token.string.endswith(','): - # Parameter lists. - self._Add(TokenInfo(token)) - elif token.IsKeyword('var'): - self._Add(TokenInfo(token)) - elif token.metadata.is_implied_semicolon: - self._PopTransient() - elif token.IsAssignment(): - self._Add(TokenInfo(token)) - - return indentation_errors - - def _AddToEach(self, original, amount): - """Returns a new set with the given amount added to each element. - - Args: - original: The original set of numbers - amount: The amount to add to each element - - Returns: - A new set containing each element of the original set added to the amount. - """ - return set([x + amount for x in original]) - - _HARD_STOP_TYPES = (Type.START_PAREN, Type.START_PARAMETERS, - Type.START_BRACKET) - - _HARD_STOP_STRINGS = ('return', '?') - - def _IsHardStop(self, token): - """Determines if the given token can have a hard stop after it. - - Args: - token: token to examine - - Returns: - Whether the token can have a hard stop after it. - - Hard stops are indentations defined by the position of another token as in - indentation lined up with return, (, [, and ?. - """ - return (token.type in self._HARD_STOP_TYPES or - token.string in self._HARD_STOP_STRINGS or - token.IsAssignment()) - - def _GetAllowableIndentations(self): - """Computes the set of allowable indentations. - - Returns: - The set of allowable indentations, given the current stack. - """ - expected = set([0]) - hard_stops = set([]) - - # Whether the tokens are still in the same continuation, meaning additional - # indentation is optional. As an example: - # x = 5 + - # 6 + - # 7; - # The second '+' does not add any required indentation. - in_same_continuation = False - - for token_info in self._stack: - token = token_info.token - - # Handle normal additive indentation tokens. - if not token_info.overridden_by and token.string != 'return': - if token_info.is_block: - expected = self._AddToEach(expected, 2) - hard_stops = self._AddToEach(hard_stops, 2) - in_same_continuation = False - elif in_same_continuation: - expected |= self._AddToEach(expected, 4) - hard_stops |= self._AddToEach(hard_stops, 4) - else: - expected = self._AddToEach(expected, 4) - hard_stops |= self._AddToEach(hard_stops, 4) - in_same_continuation = True - - # Handle hard stops after (, [, return, =, and ? - if self._IsHardStop(token): - override_is_hard_stop = (token_info.overridden_by and - self._IsHardStop( - token_info.overridden_by.token)) - if token.type == Type.START_PAREN and token.previous: - # For someFunction(...) we allow to indent at the beginning of the - # identifier +4 - prev = token.previous - if (prev.type == Type.IDENTIFIER and - prev.line_number == token.line_number): - hard_stops.add(prev.start_index + 4) - if not override_is_hard_stop: - start_index = token.start_index - if token.line_number in self._start_index_offset: - start_index += self._start_index_offset[token.line_number] - if (token.type in (Type.START_PAREN, Type.START_PARAMETERS) and - not token_info.overridden_by): - hard_stops.add(start_index + 1) - - elif token.string == 'return' and not token_info.overridden_by: - hard_stops.add(start_index + 7) - - elif token.type == Type.START_BRACKET: - hard_stops.add(start_index + 1) - - elif token.IsAssignment(): - hard_stops.add(start_index + len(token.string) + 1) - - elif token.IsOperator('?') and not token_info.overridden_by: - hard_stops.add(start_index + 2) - - return (expected | hard_stops) or set([0]) - - def _GetActualIndentation(self, token): - """Gets the actual indentation of the line containing the given token. - - Args: - token: Any token on the line. - - Returns: - The actual indentation of the line containing the given token. Returns - -1 if this line should be ignored due to the presence of tabs. - """ - # Move to the first token in the line - token = tokenutil.GetFirstTokenInSameLine(token) - - # If it is whitespace, it is the indentation. - if token.type == Type.WHITESPACE: - if token.string.find('\t') >= 0: - return -1 - else: - return len(token.string) - elif token.type == Type.PARAMETERS: - return len(token.string) - len(token.string.lstrip()) - else: - return 0 - - def _IsFirstNonWhitespaceTokenInLine(self, token): - """Determines if the given token is the first non-space token on its line. - - Args: - token: The token. - - Returns: - True if the token is the first non-whitespace token on its line. - """ - if token.type in (Type.WHITESPACE, Type.BLANK_LINE): - return False - if token.IsFirstInLine(): - return True - return (token.previous and token.previous.IsFirstInLine() and - token.previous.type == Type.WHITESPACE) - - def _IsLastCodeInLine(self, token): - """Determines if the given token is the last code token on its line. - - Args: - token: The token. - - Returns: - True if the token is the last code token on its line. - """ - if token.type in Type.NON_CODE_TYPES: - return False - start_token = token - while True: - token = token.next - if not token or token.line_number != start_token.line_number: - return True - if token.type not in Type.NON_CODE_TYPES: - return False - - def _AllFunctionPropertyAssignTokens(self, start_token, end_token): - """Checks if tokens are (likely) a valid function property assignment. - - Args: - start_token: Start of the token range. - end_token: End of the token range. - - Returns: - True if all tokens between start_token and end_token are legal tokens - within a function declaration and assignment into a property. - """ - for token in tokenutil.GetTokenRange(start_token, end_token): - fn_decl_tokens = (Type.FUNCTION_DECLARATION, - Type.PARAMETERS, - Type.START_PARAMETERS, - Type.END_PARAMETERS, - Type.END_PAREN) - if (token.type not in fn_decl_tokens and - token.IsCode() and - not tokenutil.IsIdentifierOrDot(token) and - not token.IsAssignment() and - not (token.type == Type.OPERATOR and token.string == ',')): - return False - return True - - def _Add(self, token_info): - """Adds the given token info to the stack. - - Args: - token_info: The token information to add. - """ - if self._stack and self._stack[-1].token == token_info.token: - # Don't add the same token twice. - return - - if token_info.is_block or token_info.token.type == Type.START_PAREN: - scope_token = tokenutil.GoogScopeOrNoneFromStartBlock(token_info.token) - token_info.overridden_by = TokenInfo(scope_token) if scope_token else None - - if (token_info.token.type == Type.START_BLOCK and - token_info.token.metadata.context.type == Context.BLOCK): - # Handle function() {} assignments: their block contents get special - # treatment and are allowed to just indent by two whitespace. - # For example - # long.long.name = function( - # a) { - # In this case the { and the = are on different lines. But the - # override should still apply for all previous stack tokens that are - # part of an assignment of a block. - - has_assignment = any(x for x in self._stack if x.token.IsAssignment()) - if has_assignment: - last_token = token_info.token.previous - for stack_info in reversed(self._stack): - if (last_token and - not self._AllFunctionPropertyAssignTokens(stack_info.token, - last_token)): - break - stack_info.overridden_by = token_info - stack_info.is_permanent_override = True - last_token = stack_info.token - - index = len(self._stack) - 1 - while index >= 0: - stack_info = self._stack[index] - stack_token = stack_info.token - - if stack_info.line_number == token_info.line_number: - # In general, tokens only override each other when they are on - # the same line. - stack_info.overridden_by = token_info - if (token_info.token.type == Type.START_BLOCK and - (stack_token.IsAssignment() or - stack_token.type in (Type.IDENTIFIER, Type.START_PAREN))): - # Multi-line blocks have lasting overrides, as in: - # callFn({ - # a: 10 - # }, - # 30); - # b/11450054. If a string is not closed properly then close_block - # could be null. - close_block = token_info.token.metadata.context.end_token - stack_info.is_permanent_override = close_block and ( - close_block.line_number != token_info.token.line_number) - else: - break - index -= 1 - - self._stack.append(token_info) - - def _Pop(self): - """Pops the top token from the stack. - - Returns: - The popped token info. - """ - token_info = self._stack.pop() - if token_info.token.type not in (Type.START_BLOCK, Type.START_BRACKET): - # Remove any temporary overrides. - self._RemoveOverrides(token_info) - else: - # For braces and brackets, which can be object and array literals, remove - # overrides when the literal is closed on the same line. - token_check = token_info.token - same_type = token_check.type - goal_type = None - if token_info.token.type == Type.START_BRACKET: - goal_type = Type.END_BRACKET - else: - goal_type = Type.END_BLOCK - line_number = token_info.token.line_number - count = 0 - while token_check and token_check.line_number == line_number: - if token_check.type == goal_type: - count -= 1 - if not count: - self._RemoveOverrides(token_info) - break - if token_check.type == same_type: - count += 1 - token_check = token_check.next - return token_info - - def _PopToImpliedBlock(self): - """Pops the stack until an implied block token is found.""" - while not self._Pop().token.metadata.is_implied_block: - pass - - def _PopTo(self, stop_type): - """Pops the stack until a token of the given type is popped. - - Args: - stop_type: The type of token to pop to. - - Returns: - The token info of the given type that was popped. - """ - last = None - while True: - last = self._Pop() - if last.token.type == stop_type: - break - return last - - def _RemoveOverrides(self, token_info): - """Marks any token that was overridden by this token as active again. - - Args: - token_info: The token that is being removed from the stack. - """ - for stack_token in self._stack: - if (stack_token.overridden_by == token_info and - not stack_token.is_permanent_override): - stack_token.overridden_by = None - - def _PopTransient(self): - """Pops all transient tokens - i.e. not blocks, literals, or parens.""" - while self._stack and self._stack[-1].is_transient: - self._Pop()
diff --git a/third_party/closure_linter/closure_linter/javascriptlintrules.py b/third_party/closure_linter/closure_linter/javascriptlintrules.py deleted file mode 100755 index 79c6448..0000000 --- a/third_party/closure_linter/closure_linter/javascriptlintrules.py +++ /dev/null
@@ -1,755 +0,0 @@ -#!/usr/bin/env python -# Copyright 2011 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Methods for checking JS files for common style guide violations. - -These style guide violations should only apply to JavaScript and not an Ecma -scripting languages. -""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)', - 'jacobr@google.com (Jacob Richman)') - -import re - -from closure_linter import ecmalintrules -from closure_linter import error_check -from closure_linter import errors -from closure_linter import javascripttokenizer -from closure_linter import javascripttokens -from closure_linter import requireprovidesorter -from closure_linter import tokenutil -from closure_linter.common import error -from closure_linter.common import position - -# Shorthand -Error = error.Error -Position = position.Position -Rule = error_check.Rule -Type = javascripttokens.JavaScriptTokenType - - -class JavaScriptLintRules(ecmalintrules.EcmaScriptLintRules): - """JavaScript lint rules that catch JavaScript specific style errors.""" - - def __init__(self, namespaces_info): - """Initializes a JavaScriptLintRules instance.""" - ecmalintrules.EcmaScriptLintRules.__init__(self) - self._namespaces_info = namespaces_info - self._declared_private_member_tokens = {} - self._declared_private_members = set() - self._used_private_members = set() - # A stack of dictionaries, one for each function scope entered. Each - # dictionary is keyed by an identifier that defines a local variable and has - # a token as its value. - self._unused_local_variables_by_scope = [] - - def HandleMissingParameterDoc(self, token, param_name): - """Handle errors associated with a parameter missing a param tag.""" - self._HandleError(errors.MISSING_PARAMETER_DOCUMENTATION, - 'Missing docs for parameter: "%s"' % param_name, token) - - # pylint: disable=too-many-statements - def CheckToken(self, token, state): - """Checks a token, given the current parser_state, for warnings and errors. - - Args: - token: The current token under consideration - state: parser_state object that indicates the current state in the page - """ - - # Call the base class's CheckToken function. - super(JavaScriptLintRules, self).CheckToken(token, state) - - # Store some convenience variables - namespaces_info = self._namespaces_info - - if error_check.ShouldCheck(Rule.UNUSED_LOCAL_VARIABLES): - self._CheckUnusedLocalVariables(token, state) - - if error_check.ShouldCheck(Rule.UNUSED_PRIVATE_MEMBERS): - # Find all assignments to private members. - if token.type == Type.SIMPLE_LVALUE: - identifier = token.string - if identifier.endswith('_') and not identifier.endswith('__'): - doc_comment = state.GetDocComment() - suppressed = doc_comment and ( - 'underscore' in doc_comment.suppressions or - 'unusedPrivateMembers' in doc_comment.suppressions) - if not suppressed: - # Look for static members defined on a provided namespace. - if namespaces_info: - namespace = namespaces_info.GetClosurizedNamespace(identifier) - provided_namespaces = namespaces_info.GetProvidedNamespaces() - else: - namespace = None - provided_namespaces = set() - - # Skip cases of this.something_.somethingElse_. - regex = re.compile(r'^this\.[a-zA-Z_]+$') - if namespace in provided_namespaces or regex.match(identifier): - variable = identifier.split('.')[-1] - self._declared_private_member_tokens[variable] = token - self._declared_private_members.add(variable) - elif not identifier.endswith('__'): - # Consider setting public members of private members to be a usage. - for piece in identifier.split('.'): - if piece.endswith('_'): - self._used_private_members.add(piece) - - # Find all usages of private members. - if token.type == Type.IDENTIFIER: - for piece in token.string.split('.'): - if piece.endswith('_'): - self._used_private_members.add(piece) - - if token.type == Type.DOC_FLAG: - flag = token.attached_object - - if flag.flag_type == 'param' and flag.name_token is not None: - self._CheckForMissingSpaceBeforeToken( - token.attached_object.name_token) - - if flag.type is not None and flag.name is not None: - if error_check.ShouldCheck(Rule.VARIABLE_ARG_MARKER): - # Check for variable arguments marker in type. - if flag.jstype.IsVarArgsType() and flag.name != 'var_args': - self._HandleError(errors.JSDOC_MISSING_VAR_ARGS_NAME, - 'Variable length argument %s must be renamed ' - 'to var_args.' % flag.name, - token) - elif not flag.jstype.IsVarArgsType() and flag.name == 'var_args': - self._HandleError(errors.JSDOC_MISSING_VAR_ARGS_TYPE, - 'Variable length argument %s type must start ' - 'with \'...\'.' % flag.name, - token) - - if error_check.ShouldCheck(Rule.OPTIONAL_TYPE_MARKER): - # Check for optional marker in type. - if (flag.jstype.opt_arg and - not flag.name.startswith('opt_')): - self._HandleError(errors.JSDOC_MISSING_OPTIONAL_PREFIX, - 'Optional parameter name %s must be prefixed ' - 'with opt_.' % flag.name, - token) - elif (not flag.jstype.opt_arg and - flag.name.startswith('opt_')): - self._HandleError(errors.JSDOC_MISSING_OPTIONAL_TYPE, - 'Optional parameter %s type must end with =.' % - flag.name, - token) - - if flag.flag_type in state.GetDocFlag().HAS_TYPE: - # Check for both missing type token and empty type braces '{}' - # Missing suppress types are reported separately and we allow enums, - # const, private, public and protected without types. - if (flag.flag_type not in state.GetDocFlag().CAN_OMIT_TYPE - and (not flag.jstype or flag.jstype.IsEmpty())): - self._HandleError(errors.MISSING_JSDOC_TAG_TYPE, - 'Missing type in %s tag' % token.string, token) - - elif flag.name_token and flag.type_end_token and tokenutil.Compare( - flag.type_end_token, flag.name_token) > 0: - self._HandleError( - errors.OUT_OF_ORDER_JSDOC_TAG_TYPE, - 'Type should be immediately after %s tag' % token.string, - token) - - elif token.type == Type.DOUBLE_QUOTE_STRING_START: - next_token = token.next - while next_token.type == Type.STRING_TEXT: - if javascripttokenizer.JavaScriptTokenizer.SINGLE_QUOTE.search( - next_token.string): - break - next_token = next_token.next - else: - self._HandleError( - errors.UNNECESSARY_DOUBLE_QUOTED_STRING, - 'Single-quoted string preferred over double-quoted string.', - token, - position=Position.All(token.string)) - - elif token.type == Type.END_DOC_COMMENT: - doc_comment = state.GetDocComment() - - # When @externs appears in a @fileoverview comment, it should trigger - # the same limited doc checks as a special filename like externs.js. - if doc_comment.HasFlag('fileoverview') and doc_comment.HasFlag('externs'): - self._SetLimitedDocChecks(True) - - if (error_check.ShouldCheck(Rule.BLANK_LINES_AT_TOP_LEVEL) and - not self._is_html and - state.InTopLevel() and - not state.InNonScopeBlock()): - - # Check if we're in a fileoverview or constructor JsDoc. - is_constructor = ( - doc_comment.HasFlag('constructor') or - doc_comment.HasFlag('interface')) - # @fileoverview is an optional tag so if the dosctring is the first - # token in the file treat it as a file level docstring. - is_file_level_comment = ( - doc_comment.HasFlag('fileoverview') or - not doc_comment.start_token.previous) - - # If the comment is not a file overview, and it does not immediately - # precede some code, skip it. - # NOTE: The tokenutil methods are not used here because of their - # behavior at the top of a file. - next_token = token.next - if (not next_token or - (not is_file_level_comment and - next_token.type in Type.NON_CODE_TYPES)): - return - - # Don't require extra blank lines around suppression of extra - # goog.require errors. - if (doc_comment.SuppressionOnly() and - next_token.type == Type.IDENTIFIER and - next_token.string in ['goog.provide', 'goog.require']): - return - - # Find the start of this block (include comments above the block, unless - # this is a file overview). - block_start = doc_comment.start_token - if not is_file_level_comment: - token = block_start.previous - while token and token.type in Type.COMMENT_TYPES: - block_start = token - token = token.previous - - # Count the number of blank lines before this block. - blank_lines = 0 - token = block_start.previous - while token and token.type in [Type.WHITESPACE, Type.BLANK_LINE]: - if token.type == Type.BLANK_LINE: - # A blank line. - blank_lines += 1 - elif token.type == Type.WHITESPACE and not token.line.strip(): - # A line with only whitespace on it. - blank_lines += 1 - token = token.previous - - # Log errors. - error_message = False - expected_blank_lines = 0 - - # Only need blank line before file overview if it is not the beginning - # of the file, e.g. copyright is first. - if is_file_level_comment and blank_lines == 0 and block_start.previous: - error_message = 'Should have a blank line before a file overview.' - expected_blank_lines = 1 - elif is_constructor and blank_lines != 3: - error_message = ( - 'Should have 3 blank lines before a constructor/interface.') - expected_blank_lines = 3 - elif (not is_file_level_comment and not is_constructor and - blank_lines != 2): - error_message = 'Should have 2 blank lines between top-level blocks.' - expected_blank_lines = 2 - - if error_message: - self._HandleError( - errors.WRONG_BLANK_LINE_COUNT, error_message, - block_start, position=Position.AtBeginning(), - fix_data=expected_blank_lines - blank_lines) - - elif token.type == Type.END_BLOCK: - if state.InFunction() and state.IsFunctionClose(): - is_immediately_called = (token.next and - token.next.type == Type.START_PAREN) - - function = state.GetFunction() - if not self._limited_doc_checks: - if (function.has_return and function.doc and - not is_immediately_called and - not function.doc.HasFlag('return') and - not function.doc.InheritsDocumentation() and - not function.doc.HasFlag('constructor')): - # Check for proper documentation of return value. - self._HandleError( - errors.MISSING_RETURN_DOCUMENTATION, - 'Missing @return JsDoc in function with non-trivial return', - function.doc.end_token, position=Position.AtBeginning()) - elif (not function.has_return and - not function.has_throw and - function.doc and - function.doc.HasFlag('return') and - not state.InInterfaceMethod()): - flag = function.doc.GetFlag('return') - valid_no_return_names = ['undefined', 'void', '*'] - invalid_return = flag.jstype is None or not any( - sub_type.identifier in valid_no_return_names - for sub_type in flag.jstype.IterTypeGroup()) - - if invalid_return: - self._HandleError( - errors.UNNECESSARY_RETURN_DOCUMENTATION, - 'Found @return JsDoc on function that returns nothing', - flag.flag_token, position=Position.AtBeginning()) - - # b/4073735. Method in object literal definition of prototype can - # safely reference 'this'. - prototype_object_literal = False - block_start = None - previous_code = None - previous_previous_code = None - - # Search for cases where prototype is defined as object literal. - # previous_previous_code - # | previous_code - # | | block_start - # | | | - # a.b.prototype = { - # c : function() { - # this.d = 1; - # } - # } - - # If in object literal, find first token of block so to find previous - # tokens to check above condition. - if state.InObjectLiteral(): - block_start = state.GetCurrentBlockStart() - - # If an object literal then get previous token (code type). For above - # case it should be '='. - if block_start: - previous_code = tokenutil.SearchExcept(block_start, - Type.NON_CODE_TYPES, - reverse=True) - - # If previous token to block is '=' then get its previous token. - if previous_code and previous_code.IsOperator('='): - previous_previous_code = tokenutil.SearchExcept(previous_code, - Type.NON_CODE_TYPES, - reverse=True) - - # If variable/token before '=' ends with '.prototype' then its above - # case of prototype defined with object literal. - prototype_object_literal = (previous_previous_code and - previous_previous_code.string.endswith( - '.prototype')) - - if (function.has_this and function.doc and - not function.doc.HasFlag('this') and - not function.is_constructor and - not function.is_interface and - '.prototype.' not in function.name and - not prototype_object_literal): - self._HandleError( - errors.MISSING_JSDOC_TAG_THIS, - 'Missing @this JsDoc in function referencing "this". (' - 'this usually means you are trying to reference "this" in ' - 'a static function, or you have forgotten to mark a ' - 'constructor with @constructor)', - function.doc.end_token, position=Position.AtBeginning()) - - elif token.type == Type.IDENTIFIER: - if token.string == 'goog.inherits' and not state.InFunction(): - if state.GetLastNonSpaceToken().line_number == token.line_number: - self._HandleError( - errors.MISSING_LINE, - 'Missing newline between constructor and goog.inherits', - token, - position=Position.AtBeginning()) - - extra_space = state.GetLastNonSpaceToken().next - while extra_space != token: - if extra_space.type == Type.BLANK_LINE: - self._HandleError( - errors.EXTRA_LINE, - 'Extra line between constructor and goog.inherits', - extra_space) - extra_space = extra_space.next - - # TODO(robbyw): Test the last function was a constructor. - # TODO(robbyw): Test correct @extends and @implements documentation. - - elif (token.string == 'goog.provide' and - not state.InFunction() and - namespaces_info is not None): - namespace = tokenutil.GetStringAfterToken(token) - - # Report extra goog.provide statement. - if not namespace or namespaces_info.IsExtraProvide(token): - if not namespace: - msg = 'Empty namespace in goog.provide' - else: - msg = 'Unnecessary goog.provide: ' + namespace - - # Hint to user if this is a Test namespace. - if namespace.endswith('Test'): - msg += (' *Test namespaces must be mentioned in the ' - 'goog.setTestOnly() call') - - self._HandleError( - errors.EXTRA_GOOG_PROVIDE, - msg, - token, position=Position.AtBeginning()) - - if namespaces_info.IsLastProvide(token): - # Report missing provide statements after the last existing provide. - missing_provides = namespaces_info.GetMissingProvides() - if missing_provides: - self._ReportMissingProvides( - missing_provides, - tokenutil.GetLastTokenInSameLine(token).next, - False) - - # If there are no require statements, missing requires should be - # reported after the last provide. - if not namespaces_info.GetRequiredNamespaces(): - missing_requires, illegal_alias_statements = ( - namespaces_info.GetMissingRequires()) - if missing_requires: - self._ReportMissingRequires( - missing_requires, - tokenutil.GetLastTokenInSameLine(token).next, - True) - if illegal_alias_statements: - self._ReportIllegalAliasStatement(illegal_alias_statements) - - elif (token.string == 'goog.require' and - not state.InFunction() and - namespaces_info is not None): - namespace = tokenutil.GetStringAfterToken(token) - - # If there are no provide statements, missing provides should be - # reported before the first require. - if (namespaces_info.IsFirstRequire(token) and - not namespaces_info.GetProvidedNamespaces()): - missing_provides = namespaces_info.GetMissingProvides() - if missing_provides: - self._ReportMissingProvides( - missing_provides, - tokenutil.GetFirstTokenInSameLine(token), - True) - - # Report extra goog.require statement. - if not namespace or namespaces_info.IsExtraRequire(token): - if not namespace: - msg = 'Empty namespace in goog.require' - else: - msg = 'Unnecessary goog.require: ' + namespace - - self._HandleError( - errors.EXTRA_GOOG_REQUIRE, - msg, - token, position=Position.AtBeginning()) - - # Report missing goog.require statements. - if namespaces_info.IsLastRequire(token): - missing_requires, illegal_alias_statements = ( - namespaces_info.GetMissingRequires()) - if missing_requires: - self._ReportMissingRequires( - missing_requires, - tokenutil.GetLastTokenInSameLine(token).next, - False) - if illegal_alias_statements: - self._ReportIllegalAliasStatement(illegal_alias_statements) - - elif token.type == Type.OPERATOR: - last_in_line = token.IsLastInLine() - # If the token is unary and appears to be used in a unary context - # it's ok. Otherwise, if it's at the end of the line or immediately - # before a comment, it's ok. - # Don't report an error before a start bracket - it will be reported - # by that token's space checks. - if (not token.metadata.IsUnaryOperator() and not last_in_line - and not token.next.IsComment() - and not token.next.IsOperator(',') - and not tokenutil.IsDot(token) - and token.next.type not in (Type.WHITESPACE, Type.END_PAREN, - Type.END_BRACKET, Type.SEMICOLON, - Type.START_BRACKET)): - self._HandleError( - errors.MISSING_SPACE, - 'Missing space after "%s"' % token.string, - token, - position=Position.AtEnd(token.string)) - elif token.type == Type.WHITESPACE: - first_in_line = token.IsFirstInLine() - last_in_line = token.IsLastInLine() - # Check whitespace length if it's not the first token of the line and - # if it's not immediately before a comment. - if not last_in_line and not first_in_line and not token.next.IsComment(): - # Ensure there is no space after opening parentheses. - if (token.previous.type in (Type.START_PAREN, Type.START_BRACKET, - Type.FUNCTION_NAME) - or token.next.type == Type.START_PARAMETERS): - self._HandleError( - errors.EXTRA_SPACE, - 'Extra space after "%s"' % token.previous.string, - token, - position=Position.All(token.string)) - elif token.type == Type.SEMICOLON: - previous_token = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES, - reverse=True) - if not previous_token: - self._HandleError( - errors.REDUNDANT_SEMICOLON, - 'Semicolon without any statement', - token, - position=Position.AtEnd(token.string)) - elif (previous_token.type == Type.KEYWORD and - previous_token.string not in ['break', 'continue', 'return']): - self._HandleError( - errors.REDUNDANT_SEMICOLON, - ('Semicolon after \'%s\' without any statement.' - ' Looks like an error.' % previous_token.string), - token, - position=Position.AtEnd(token.string)) - - def _CheckUnusedLocalVariables(self, token, state): - """Checks for unused local variables in function blocks. - - Args: - token: The token to check. - state: The state tracker. - """ - # We don't use state.InFunction because that disregards scope functions. - in_function = state.FunctionDepth() > 0 - if token.type == Type.SIMPLE_LVALUE or token.type == Type.IDENTIFIER: - if in_function: - identifier = token.string - # Check whether the previous token was var. - previous_code_token = tokenutil.CustomSearch( - token, - lambda t: t.type not in Type.NON_CODE_TYPES, - reverse=True) - if previous_code_token and previous_code_token.IsKeyword('var'): - # Add local variable declaration to the top of the unused locals - # stack. - self._unused_local_variables_by_scope[-1][identifier] = token - elif token.type == Type.IDENTIFIER: - # This covers most cases where the variable is used as an identifier. - self._MarkLocalVariableUsed(token.string) - elif token.type == Type.SIMPLE_LVALUE and '.' in identifier: - # This covers cases where a value is assigned to a property of the - # variable. - self._MarkLocalVariableUsed(token.string) - elif token.type == Type.START_BLOCK: - if in_function and state.IsFunctionOpen(): - # Push a new map onto the stack - self._unused_local_variables_by_scope.append({}) - elif token.type == Type.END_BLOCK: - if state.IsFunctionClose(): - # Pop the stack and report any remaining locals as unused. - unused_local_variables = self._unused_local_variables_by_scope.pop() - for unused_token in unused_local_variables.values(): - self._HandleError( - errors.UNUSED_LOCAL_VARIABLE, - 'Unused local variable: %s.' % unused_token.string, - unused_token) - elif token.type == Type.DOC_FLAG: - # Flags that use aliased symbols should be counted. - flag = token.attached_object - js_type = flag and flag.jstype - if flag and flag.flag_type in state.GetDocFlag().HAS_TYPE and js_type: - self._MarkAliasUsed(js_type) - - def _MarkAliasUsed(self, js_type): - """Marks aliases in a type as used. - - Recursively iterates over all subtypes in a jsdoc type annotation and - tracks usage of aliased symbols (which may be local variables). - Marks the local variable as used in the scope nearest to the current - scope that matches the given token. - - Args: - js_type: The jsdoc type, a typeannotation.TypeAnnotation object. - """ - if js_type.alias: - self._MarkLocalVariableUsed(js_type.identifier) - for sub_type in js_type.IterTypes(): - self._MarkAliasUsed(sub_type) - - def _MarkLocalVariableUsed(self, identifier): - """Marks the local variable as used in the relevant scope. - - Marks the local variable in the scope nearest to the current scope that - matches the given identifier as used. - - Args: - identifier: The identifier representing the potential usage of a local - variable. - """ - identifier = identifier.split('.', 1)[0] - # Find the first instance of the identifier in the stack of function scopes - # and mark it used. - for unused_local_variables in reversed( - self._unused_local_variables_by_scope): - if identifier in unused_local_variables: - del unused_local_variables[identifier] - break - - def _ReportMissingProvides(self, missing_provides, token, need_blank_line): - """Reports missing provide statements to the error handler. - - Args: - missing_provides: A dictionary of string(key) and integer(value) where - each string(key) is a namespace that should be provided, but is not - and integer(value) is first line number where it's required. - token: The token where the error was detected (also where the new provides - will be inserted. - need_blank_line: Whether a blank line needs to be inserted after the new - provides are inserted. May be True, False, or None, where None - indicates that the insert location is unknown. - """ - - missing_provides_msg = 'Missing the following goog.provide statements:\n' - missing_provides_msg += '\n'.join(['goog.provide(\'%s\');' % x for x in - sorted(missing_provides)]) - missing_provides_msg += '\n' - - missing_provides_msg += '\nFirst line where provided: \n' - missing_provides_msg += '\n'.join( - [' %s : line %d' % (x, missing_provides[x]) for x in - sorted(missing_provides)]) - missing_provides_msg += '\n' - - self._HandleError( - errors.MISSING_GOOG_PROVIDE, - missing_provides_msg, - token, position=Position.AtBeginning(), - fix_data=(missing_provides.keys(), need_blank_line)) - - def _ReportMissingRequires(self, missing_requires, token, need_blank_line): - """Reports missing require statements to the error handler. - - Args: - missing_requires: A dictionary of string(key) and integer(value) where - each string(key) is a namespace that should be required, but is not - and integer(value) is first line number where it's required. - token: The token where the error was detected (also where the new requires - will be inserted. - need_blank_line: Whether a blank line needs to be inserted before the new - requires are inserted. May be True, False, or None, where None - indicates that the insert location is unknown. - """ - - missing_requires_msg = 'Missing the following goog.require statements:\n' - missing_requires_msg += '\n'.join(['goog.require(\'%s\');' % x for x in - sorted(missing_requires)]) - missing_requires_msg += '\n' - - missing_requires_msg += '\nFirst line where required: \n' - missing_requires_msg += '\n'.join( - [' %s : line %d' % (x, missing_requires[x]) for x in - sorted(missing_requires)]) - missing_requires_msg += '\n' - - self._HandleError( - errors.MISSING_GOOG_REQUIRE, - missing_requires_msg, - token, position=Position.AtBeginning(), - fix_data=(missing_requires.keys(), need_blank_line)) - - def _ReportIllegalAliasStatement(self, illegal_alias_statements): - """Reports alias statements that would need a goog.require.""" - for namespace, token in illegal_alias_statements.iteritems(): - self._HandleError( - errors.ALIAS_STMT_NEEDS_GOOG_REQUIRE, - 'The alias definition would need the namespace \'%s\' which is not ' - 'required through any other symbol.' % namespace, - token, position=Position.AtBeginning()) - - def Finalize(self, state): - """Perform all checks that need to occur after all lines are processed.""" - # Call the base class's Finalize function. - super(JavaScriptLintRules, self).Finalize(state) - - if error_check.ShouldCheck(Rule.UNUSED_PRIVATE_MEMBERS): - # Report an error for any declared private member that was never used. - unused_private_members = (self._declared_private_members - - self._used_private_members) - - for variable in unused_private_members: - token = self._declared_private_member_tokens[variable] - self._HandleError(errors.UNUSED_PRIVATE_MEMBER, - 'Unused private member: %s.' % token.string, - token) - - # Clear state to prepare for the next file. - self._declared_private_member_tokens = {} - self._declared_private_members = set() - self._used_private_members = set() - - namespaces_info = self._namespaces_info - if namespaces_info is not None: - # If there are no provide or require statements, missing provides and - # requires should be reported on line 1. - if (not namespaces_info.GetProvidedNamespaces() and - not namespaces_info.GetRequiredNamespaces()): - missing_provides = namespaces_info.GetMissingProvides() - if missing_provides: - self._ReportMissingProvides( - missing_provides, state.GetFirstToken(), None) - - missing_requires, illegal_alias = namespaces_info.GetMissingRequires() - if missing_requires: - self._ReportMissingRequires( - missing_requires, state.GetFirstToken(), None) - if illegal_alias: - self._ReportIllegalAliasStatement(illegal_alias) - - self._CheckSortedRequiresProvides(state.GetFirstToken()) - - def _CheckSortedRequiresProvides(self, token): - """Checks that all goog.require and goog.provide statements are sorted. - - Note that this method needs to be run after missing statements are added to - preserve alphabetical order. - - Args: - token: The first token in the token stream. - """ - sorter = requireprovidesorter.RequireProvideSorter() - first_provide_token = sorter.CheckProvides(token) - if first_provide_token: - new_order = sorter.GetFixedProvideString(first_provide_token) - self._HandleError( - errors.GOOG_PROVIDES_NOT_ALPHABETIZED, - 'goog.provide classes must be alphabetized. The correct code is:\n' + - new_order, - first_provide_token, - position=Position.AtBeginning(), - fix_data=first_provide_token) - - first_require_token = sorter.CheckRequires(token) - if first_require_token: - new_order = sorter.GetFixedRequireString(first_require_token) - self._HandleError( - errors.GOOG_REQUIRES_NOT_ALPHABETIZED, - 'goog.require classes must be alphabetized. The correct code is:\n' + - new_order, - first_require_token, - position=Position.AtBeginning(), - fix_data=first_require_token) - - def GetLongLineExceptions(self): - """Gets a list of regexps for lines which can be longer than the limit. - - Returns: - A list of regexps, used as matches (rather than searches). - """ - return [ - re.compile(r'((var|let|const) .+\s*=\s*)?goog\.require\(.+\);?\s*$'), - re.compile(r'goog\.(forwardDeclare|module|provide|setTestOnly)' - r'\(.+\);?\s*$'), - re.compile(r'[\s/*]*@visibility\s*{.*}[\s*/]*$'), - ]
diff --git a/third_party/closure_linter/closure_linter/javascriptstatetracker.py b/third_party/closure_linter/closure_linter/javascriptstatetracker.py deleted file mode 100755 index e0a42f6..0000000 --- a/third_party/closure_linter/closure_linter/javascriptstatetracker.py +++ /dev/null
@@ -1,150 +0,0 @@ -#!/usr/bin/env python -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Parser for JavaScript files.""" - - - -from closure_linter import javascripttokens -from closure_linter import statetracker -from closure_linter import tokenutil - -# Shorthand -Type = javascripttokens.JavaScriptTokenType - - -class JsDocFlag(statetracker.DocFlag): - """Javascript doc flag object. - - Attribute: - flag_type: param, return, define, type, etc. - flag_token: The flag token. - type_start_token: The first token specifying the flag JS type, - including braces. - type_end_token: The last token specifying the flag JS type, - including braces. - type: The type spec string. - jstype: The type spec, a TypeAnnotation instance. - name_token: The token specifying the flag name. - name: The flag name - description_start_token: The first token in the description. - description_end_token: The end token in the description. - description: The description. - """ - - # Please keep these lists alphabetized. - - # Some projects use the following extensions to JsDoc. - # TODO(robbyw): determine which of these, if any, should be illegal. - EXTENDED_DOC = frozenset([ - 'class', 'code', 'desc', 'final', 'hidden', 'inheritDoc', 'link', - 'meaning', 'provideGoog', 'throws']) - - LEGAL_DOC = EXTENDED_DOC | statetracker.DocFlag.LEGAL_DOC - - -class JavaScriptStateTracker(statetracker.StateTracker): - """JavaScript state tracker. - - Inherits from the core EcmaScript StateTracker adding extra state tracking - functionality needed for JavaScript. - """ - - def __init__(self): - """Initializes a JavaScript token stream state tracker.""" - statetracker.StateTracker.__init__(self, JsDocFlag) - - def Reset(self): - self._scope_depth = 0 - self._block_stack = [] - super(JavaScriptStateTracker, self).Reset() - - def InTopLevel(self): - """Compute whether we are at the top level in the class. - - This function call is language specific. In some languages like - JavaScript, a function is top level if it is not inside any parenthesis. - In languages such as ActionScript, a function is top level if it is directly - within a class. - - Returns: - Whether we are at the top level in the class. - """ - return self._scope_depth == self.ParenthesesDepth() - - def InFunction(self): - """Returns true if the current token is within a function. - - This js-specific override ignores goog.scope functions. - - Returns: - True if the current token is within a function. - """ - return self._scope_depth != self.FunctionDepth() - - def InNonScopeBlock(self): - """Compute whether we are nested within a non-goog.scope block. - - Returns: - True if the token is not enclosed in a block that does not originate from - a goog.scope statement. False otherwise. - """ - return self._scope_depth != self.BlockDepth() - - def GetBlockType(self, token): - """Determine the block type given a START_BLOCK token. - - Code blocks come after parameters, keywords like else, and closing parens. - - Args: - token: The current token. Can be assumed to be type START_BLOCK - Returns: - Code block type for current token. - """ - last_code = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES, reverse=True) - if last_code.type in (Type.END_PARAMETERS, Type.END_PAREN, - Type.KEYWORD) and not last_code.IsKeyword('return'): - return self.CODE - else: - return self.OBJECT_LITERAL - - def GetCurrentBlockStart(self): - """Gets the start token of current block. - - Returns: - Starting token of current block. None if not in block. - """ - if self._block_stack: - return self._block_stack[-1] - else: - return None - - def HandleToken(self, token, last_non_space_token): - """Handles the given token and updates state. - - Args: - token: The token to handle. - last_non_space_token: The last non space token encountered - """ - if token.type == Type.START_BLOCK: - self._block_stack.append(token) - if token.type == Type.IDENTIFIER and token.string == 'goog.scope': - self._scope_depth += 1 - if token.type == Type.END_BLOCK: - start_token = self._block_stack.pop() - if tokenutil.GoogScopeOrNoneFromStartBlock(start_token): - self._scope_depth -= 1 - super(JavaScriptStateTracker, self).HandleToken(token, - last_non_space_token)
diff --git a/third_party/closure_linter/closure_linter/javascriptstatetracker_test.py b/third_party/closure_linter/closure_linter/javascriptstatetracker_test.py deleted file mode 100644 index 76dabd2..0000000 --- a/third_party/closure_linter/closure_linter/javascriptstatetracker_test.py +++ /dev/null
@@ -1,278 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Unit tests for the javascriptstatetracker module.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = ('nnaze@google.com (Nathan Naze)') - - -import unittest as googletest - -from closure_linter import javascripttokens -from closure_linter import testutil -from closure_linter import tokenutil - - -_FUNCTION_SCRIPT = """\ -var a = 3; - -function foo(aaa, bbb, ccc) { - var b = 4; -} - - -/** - * JSDoc comment. - */ -var bar = function(ddd, eee, fff) { - -}; - - -/** - * Verify that nested functions get their proper parameters recorded. - */ -var baz = function(ggg, hhh, iii) { - var qux = function(jjj, kkk, lll) { - }; - // make sure that entering a new block does not change baz' parameters. - {}; -}; - -""" - - -class FunctionTest(googletest.TestCase): - - def testFunctionParse(self): - functions, _ = testutil.ParseFunctionsAndComments(_FUNCTION_SCRIPT) - self.assertEquals(4, len(functions)) - - # First function - function = functions[0] - self.assertEquals(['aaa', 'bbb', 'ccc'], function.parameters) - - start_token = function.start_token - end_token = function.end_token - - self.assertEquals( - javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION, - function.start_token.type) - - self.assertEquals('function', start_token.string) - self.assertEquals(3, start_token.line_number) - self.assertEquals(0, start_token.start_index) - - self.assertEquals('}', end_token.string) - self.assertEquals(5, end_token.line_number) - self.assertEquals(0, end_token.start_index) - - self.assertEquals('foo', function.name) - - self.assertIsNone(function.doc) - - # Second function - function = functions[1] - self.assertEquals(['ddd', 'eee', 'fff'], function.parameters) - - start_token = function.start_token - end_token = function.end_token - - self.assertEquals( - javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION, - function.start_token.type) - - self.assertEquals('function', start_token.string) - self.assertEquals(11, start_token.line_number) - self.assertEquals(10, start_token.start_index) - - self.assertEquals('}', end_token.string) - self.assertEquals(13, end_token.line_number) - self.assertEquals(0, end_token.start_index) - - self.assertEquals('bar', function.name) - - self.assertIsNotNone(function.doc) - - # Check function JSDoc - doc = function.doc - doc_tokens = tokenutil.GetTokenRange(doc.start_token, doc.end_token) - - comment_type = javascripttokens.JavaScriptTokenType.COMMENT - comment_tokens = filter(lambda t: t.type is comment_type, doc_tokens) - - self.assertEquals('JSDoc comment.', - tokenutil.TokensToString(comment_tokens).strip()) - - # Third function - function = functions[2] - self.assertEquals(['ggg', 'hhh', 'iii'], function.parameters) - - start_token = function.start_token - end_token = function.end_token - - self.assertEquals( - javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION, - function.start_token.type) - - self.assertEquals('function', start_token.string) - self.assertEquals(19, start_token.line_number) - self.assertEquals(10, start_token.start_index) - - self.assertEquals('}', end_token.string) - self.assertEquals(24, end_token.line_number) - self.assertEquals(0, end_token.start_index) - - self.assertEquals('baz', function.name) - self.assertIsNotNone(function.doc) - - # Fourth function (inside third function) - function = functions[3] - self.assertEquals(['jjj', 'kkk', 'lll'], function.parameters) - - start_token = function.start_token - end_token = function.end_token - - self.assertEquals( - javascripttokens.JavaScriptTokenType.FUNCTION_DECLARATION, - function.start_token.type) - - self.assertEquals('function', start_token.string) - self.assertEquals(20, start_token.line_number) - self.assertEquals(12, start_token.start_index) - - self.assertEquals('}', end_token.string) - self.assertEquals(21, end_token.line_number) - self.assertEquals(2, end_token.start_index) - - self.assertEquals('qux', function.name) - self.assertIsNone(function.doc) - - - -class CommentTest(googletest.TestCase): - - def testGetDescription(self): - comment = self._ParseComment(""" - /** - * Comment targeting goog.foo. - * - * This is the second line. - * @param {number} foo The count of foo. - */ - target;""") - - self.assertEqual( - 'Comment targeting goog.foo.\n\nThis is the second line.', - comment.description) - - def testCommentGetTarget(self): - self.assertCommentTarget('goog.foo', """ - /** - * Comment targeting goog.foo. - */ - goog.foo = 6; - """) - - self.assertCommentTarget('bar', """ - /** - * Comment targeting bar. - */ - var bar = "Karate!"; - """) - - self.assertCommentTarget('doThing', """ - /** - * Comment targeting doThing. - */ - function doThing() {}; - """) - - self.assertCommentTarget('this.targetProperty', """ - goog.bar.Baz = function() { - /** - * Comment targeting targetProperty. - */ - this.targetProperty = 3; - }; - """) - - self.assertCommentTarget('goog.bar.prop', """ - /** - * Comment targeting goog.bar.prop. - */ - goog.bar.prop; - """) - - self.assertCommentTarget('goog.aaa.bbb', """ - /** - * Comment targeting goog.aaa.bbb. - */ - (goog.aaa.bbb) - """) - - self.assertCommentTarget('theTarget', """ - /** - * Comment targeting symbol preceded by newlines, whitespace, - * and parens -- things we ignore. - */ - (theTarget) - """) - - self.assertCommentTarget(None, """ - /** - * @fileoverview File overview. - */ - (notATarget) - """) - - self.assertCommentTarget(None, """ - /** - * Comment that doesn't find a target. - */ - """) - - self.assertCommentTarget('theTarget.is.split.across.lines', """ - /** - * Comment that addresses a symbol split across lines. - */ - (theTarget.is.split - .across.lines) - """) - - self.assertCommentTarget('theTarget.is.split.across.lines', """ - /** - * Comment that addresses a symbol split across lines. - */ - (theTarget.is.split. - across.lines) - """) - - def _ParseComment(self, script): - """Parse a script that contains one comment and return it.""" - _, comments = testutil.ParseFunctionsAndComments(script) - self.assertEquals(1, len(comments)) - return comments[0] - - def assertCommentTarget(self, target, script): - comment = self._ParseComment(script) - self.assertEquals(target, comment.GetTargetIdentifier()) - - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/javascripttokenizer.py b/third_party/closure_linter/closure_linter/javascripttokenizer.py deleted file mode 100755 index 964db7ce..0000000 --- a/third_party/closure_linter/closure_linter/javascripttokenizer.py +++ /dev/null
@@ -1,478 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Regular expression based JavaScript parsing classes.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -import copy -import re - -from closure_linter import javascripttokens -from closure_linter.common import matcher -from closure_linter.common import tokenizer - -# Shorthand -Type = javascripttokens.JavaScriptTokenType -Matcher = matcher.Matcher - - -class JavaScriptModes(object): - """Enumeration of the different matcher modes used for JavaScript.""" - TEXT_MODE = 'text' - SINGLE_QUOTE_STRING_MODE = 'single_quote_string' - DOUBLE_QUOTE_STRING_MODE = 'double_quote_string' - TEMPLATE_STRING_MODE = 'template_string' - BLOCK_COMMENT_MODE = 'block_comment' - DOC_COMMENT_MODE = 'doc_comment' - DOC_COMMENT_LEX_SPACES_MODE = 'doc_comment_spaces' - LINE_COMMENT_MODE = 'line_comment' - PARAMETER_MODE = 'parameter' - FUNCTION_MODE = 'function' - - -class JavaScriptTokenizer(tokenizer.Tokenizer): - """JavaScript tokenizer. - - Convert JavaScript code in to an array of tokens. - """ - - # Useful patterns for JavaScript parsing. - IDENTIFIER_CHAR = r'A-Za-z0-9_$' - - # Number patterns based on: - # http://www.mozilla.org/js/language/js20-2000-07/formal/lexer-grammar.html - MANTISSA = r""" - (\d+(?!\.)) | # Matches '10' - (\d+\.(?!\d)) | # Matches '10.' - (\d*\.\d+) # Matches '.5' or '10.5' - """ - DECIMAL_LITERAL = r'(%s)([eE][-+]?\d+)?' % MANTISSA - HEX_LITERAL = r'0[xX][0-9a-fA-F]+' - NUMBER = re.compile(r""" - ((%s)|(%s)) - """ % (HEX_LITERAL, DECIMAL_LITERAL), re.VERBOSE) - - # Strings come in three parts - first we match the start of the string, then - # the contents, then the end. The contents consist of any character except a - # backslash or end of string, or a backslash followed by any character, or a - # backslash followed by end of line to support correct parsing of multi-line - # strings. - SINGLE_QUOTE = re.compile(r"'") - SINGLE_QUOTE_TEXT = re.compile(r"([^'\\]|\\(.|$))+") - DOUBLE_QUOTE = re.compile(r'"') - DOUBLE_QUOTE_TEXT = re.compile(r'([^"\\]|\\(.|$))+') - # Template strings are different from normal strings in that they do not - # require escaping of end of lines in order to be multi-line. - TEMPLATE_QUOTE = re.compile(r'`') - TEMPLATE_QUOTE_TEXT = re.compile(r'([^`]|$)+') - - START_SINGLE_LINE_COMMENT = re.compile(r'//') - END_OF_LINE_SINGLE_LINE_COMMENT = re.compile(r'//$') - - START_DOC_COMMENT = re.compile(r'/\*\*') - START_BLOCK_COMMENT = re.compile(r'/\*') - END_BLOCK_COMMENT = re.compile(r'\*/') - BLOCK_COMMENT_TEXT = re.compile(r'([^*]|\*(?!/))+') - - # Comment text is anything that we are not going to parse into another special - # token like (inline) flags or end comments. Complicated regex to match - # most normal characters, and '*', '{', '}', and '@' when we are sure that - # it is safe. Expression [^*{\s]@ must come first, or the other options will - # match everything before @, and we won't match @'s that aren't part of flags - # like in email addresses in the @author tag. - DOC_COMMENT_TEXT = re.compile(r'([^*{}\s]@|[^*{}@]|\*(?!/))+') - DOC_COMMENT_NO_SPACES_TEXT = re.compile(r'([^*{}\s]@|[^*{}@\s]|\*(?!/))+') - # Match anything that is allowed in a type definition, except for tokens - # needed to parse it (and the lookahead assertion for "*/"). - DOC_COMMENT_TYPE_TEXT = re.compile(r'([^*|!?=<>(){}:,\s]|\*(?!/))+') - - # Match the prefix ' * ' that starts every line of jsdoc. Want to include - # spaces after the '*', but nothing else that occurs after a '*', and don't - # want to match the '*' in '*/'. - DOC_PREFIX = re.compile(r'\s*\*(\s+|(?!/))') - - START_BLOCK = re.compile('{') - END_BLOCK = re.compile('}') - - REGEX_CHARACTER_CLASS = r""" - \[ # Opening bracket - ([^\]\\]|\\.)* # Anything but a ] or \, - # or a backslash followed by anything - \] # Closing bracket - """ - # We ensure the regex is followed by one of the above tokens to avoid - # incorrectly parsing something like x / y / z as x REGEX(/ y /) z - POST_REGEX_LIST = [ - ';', ',', r'\.', r'\)', r'\]', '$', r'\/\/', r'\/\*', ':', '}'] - - REGEX = re.compile(r""" - / # opening slash - (?!\*) # not the start of a comment - (\\.|[^\[\/\\]|(%s))* # a backslash followed by anything, - # or anything but a / or [ or \, - # or a character class - / # closing slash - [gimsx]* # optional modifiers - (?=\s*(%s)) - """ % (REGEX_CHARACTER_CLASS, '|'.join(POST_REGEX_LIST)), - re.VERBOSE) - - ANYTHING = re.compile(r'.*') - PARAMETERS = re.compile(r'[^\)]+') - CLOSING_PAREN_WITH_SPACE = re.compile(r'\)\s*') - - FUNCTION_DECLARATION = re.compile(r'\bfunction\b') - - OPENING_PAREN = re.compile(r'\(') - CLOSING_PAREN = re.compile(r'\)') - - OPENING_BRACKET = re.compile(r'\[') - CLOSING_BRACKET = re.compile(r'\]') - - # We omit these JS keywords from the list: - # function - covered by FUNCTION_DECLARATION. - # delete, in, instanceof, new, typeof - included as operators. - # this - included in identifiers. - # null, undefined - not included, should go in some "special constant" list. - KEYWORD_LIST = [ - 'break', - 'case', - 'catch', - 'continue', - 'default', - 'do', - 'else', - 'finally', - 'for', - 'if', - 'return', - 'switch', - 'throw', - 'try', - 'var', - 'while', - 'with', - ] - - # List of regular expressions to match as operators. Some notes: for our - # purposes, the comma behaves similarly enough to a normal operator that we - # include it here. r'\bin\b' actually matches 'in' surrounded by boundary - # characters - this may not match some very esoteric uses of the in operator. - # Operators that are subsets of larger operators must come later in this list - # for proper matching, e.g., '>>' must come AFTER '>>>'. - OPERATOR_LIST = [ - ',', - r'\+\+', - '===', - '!==', - '>>>=', - '>>>', - '==', - '>=', - '<=', - '!=', - '<<=', - '>>=', - '<<', - '>>', - '=>', - '>', - '<', - r'\+=', - r'\+', - '--', - r'\^=', - '-=', - '-', - '/=', - '/', - r'\*=', - r'\*', - '%=', - '%', - '&&', - r'\|\|', - '&=', - '&', - r'\|=', - r'\|', - '=', - '!', - ':', - r'\?', - r'\^', - r'\bdelete\b', - r'\bin\b', - r'\binstanceof\b', - r'\bnew\b', - r'\btypeof\b', - r'\bvoid\b', - r'\.', - ] - OPERATOR = re.compile('|'.join(OPERATOR_LIST)) - - WHITESPACE = re.compile(r'\s+') - SEMICOLON = re.compile(r';') - # Technically JavaScript identifiers can't contain '.', but we treat a set of - # nested identifiers as a single identifier, except for trailing dots. - NESTED_IDENTIFIER = r'[a-zA-Z_$]([%s]|\.[a-zA-Z_$])*' % IDENTIFIER_CHAR - IDENTIFIER = re.compile(NESTED_IDENTIFIER) - - SIMPLE_LVALUE = re.compile(r""" - (?P<identifier>%s) # a valid identifier - (?=\s* # optional whitespace - \= # look ahead to equal sign - (?!=)) # not follwed by equal - """ % NESTED_IDENTIFIER, re.VERBOSE) - - # A doc flag is a @ sign followed by non-space characters that appears at the - # beginning of the line, after whitespace, or after a '{'. The look-behind - # check is necessary to not match someone@google.com as a flag. - DOC_FLAG = re.compile(r'(^|(?<=\s))@(?P<name>[a-zA-Z]+)') - # To properly parse parameter names and complex doctypes containing - # whitespace, we need to tokenize whitespace into a token after certain - # doctags. All statetracker.HAS_TYPE that are not listed here must not contain - # any whitespace in their types. - DOC_FLAG_LEX_SPACES = re.compile( - r'(^|(?<=\s))@(?P<name>%s)\b' % - '|'.join([ - 'const', - 'enum', - 'export', - 'extends', - 'final', - 'implements', - 'package', - 'param', - 'private', - 'protected', - 'public', - 'return', - 'type', - 'typedef' - ])) - - DOC_INLINE_FLAG = re.compile(r'(?<={)@(?P<name>[a-zA-Z]+)') - - DOC_TYPE_BLOCK_START = re.compile(r'[<(]') - DOC_TYPE_BLOCK_END = re.compile(r'[>)]') - DOC_TYPE_MODIFIERS = re.compile(r'[!?|,:=]') - - # Star followed by non-slash, i.e a star that does not end a comment. - # This is used for TYPE_GROUP below. - SAFE_STAR = r'(\*(?!/))' - - COMMON_DOC_MATCHERS = [ - # Find the end of the comment. - Matcher(END_BLOCK_COMMENT, Type.END_DOC_COMMENT, - JavaScriptModes.TEXT_MODE), - - # Tokenize documented flags like @private. - Matcher(DOC_INLINE_FLAG, Type.DOC_INLINE_FLAG), - Matcher(DOC_FLAG_LEX_SPACES, Type.DOC_FLAG, - JavaScriptModes.DOC_COMMENT_LEX_SPACES_MODE), - - # Encountering a doc flag should leave lex spaces mode. - Matcher(DOC_FLAG, Type.DOC_FLAG, JavaScriptModes.DOC_COMMENT_MODE), - - # Tokenize braces so we can find types. - Matcher(START_BLOCK, Type.DOC_START_BRACE), - Matcher(END_BLOCK, Type.DOC_END_BRACE), - - # And some more to parse types. - Matcher(DOC_TYPE_BLOCK_START, Type.DOC_TYPE_START_BLOCK), - Matcher(DOC_TYPE_BLOCK_END, Type.DOC_TYPE_END_BLOCK), - - Matcher(DOC_TYPE_MODIFIERS, Type.DOC_TYPE_MODIFIER), - Matcher(DOC_COMMENT_TYPE_TEXT, Type.COMMENT), - - Matcher(DOC_PREFIX, Type.DOC_PREFIX, None, True)] - - # When text is not matched, it is given this default type based on mode. - # If unspecified in this map, the default default is Type.NORMAL. - JAVASCRIPT_DEFAULT_TYPES = { - JavaScriptModes.DOC_COMMENT_MODE: Type.COMMENT, - JavaScriptModes.DOC_COMMENT_LEX_SPACES_MODE: Type.COMMENT - } - - @classmethod - def BuildMatchers(cls): - """Builds the token matcher group. - - The token matcher groups work as follows: it is a list of Matcher objects. - The matchers will be tried in this order, and the first to match will be - returned. Hence the order is important because the matchers that come first - overrule the matchers that come later. - - Returns: - The completed token matcher group. - """ - # Match a keyword string followed by a non-identifier character in order to - # not match something like doSomething as do + Something. - keyword = re.compile('(%s)((?=[^%s])|$)' % ( - '|'.join(cls.KEYWORD_LIST), cls.IDENTIFIER_CHAR)) - return { - - # Matchers for basic text mode. - JavaScriptModes.TEXT_MODE: [ - # Check a big group - strings, starting comments, and regexes - all - # of which could be intertwined. 'string with /regex/', - # /regex with 'string'/, /* comment with /regex/ and string */ (and - # so on) - Matcher(cls.START_DOC_COMMENT, Type.START_DOC_COMMENT, - JavaScriptModes.DOC_COMMENT_MODE), - Matcher(cls.START_BLOCK_COMMENT, Type.START_BLOCK_COMMENT, - JavaScriptModes.BLOCK_COMMENT_MODE), - Matcher(cls.END_OF_LINE_SINGLE_LINE_COMMENT, - Type.START_SINGLE_LINE_COMMENT), - Matcher(cls.START_SINGLE_LINE_COMMENT, - Type.START_SINGLE_LINE_COMMENT, - JavaScriptModes.LINE_COMMENT_MODE), - Matcher(cls.SINGLE_QUOTE, Type.SINGLE_QUOTE_STRING_START, - JavaScriptModes.SINGLE_QUOTE_STRING_MODE), - Matcher(cls.DOUBLE_QUOTE, Type.DOUBLE_QUOTE_STRING_START, - JavaScriptModes.DOUBLE_QUOTE_STRING_MODE), - Matcher(cls.TEMPLATE_QUOTE, Type.TEMPLATE_STRING_START, - JavaScriptModes.TEMPLATE_STRING_MODE), - Matcher(cls.REGEX, Type.REGEX), - - # Next we check for start blocks appearing outside any of the items - # above. - Matcher(cls.START_BLOCK, Type.START_BLOCK), - Matcher(cls.END_BLOCK, Type.END_BLOCK), - - # Then we search for function declarations. - Matcher(cls.FUNCTION_DECLARATION, Type.FUNCTION_DECLARATION, - JavaScriptModes.FUNCTION_MODE), - - # Next, we convert non-function related parens to tokens. - Matcher(cls.OPENING_PAREN, Type.START_PAREN), - Matcher(cls.CLOSING_PAREN, Type.END_PAREN), - - # Next, we convert brackets to tokens. - Matcher(cls.OPENING_BRACKET, Type.START_BRACKET), - Matcher(cls.CLOSING_BRACKET, Type.END_BRACKET), - - # Find numbers. This has to happen before operators because - # scientific notation numbers can have + and - in them. - Matcher(cls.NUMBER, Type.NUMBER), - - # Find operators and simple assignments - Matcher(cls.SIMPLE_LVALUE, Type.SIMPLE_LVALUE), - Matcher(cls.OPERATOR, Type.OPERATOR), - - # Find key words and whitespace. - Matcher(keyword, Type.KEYWORD), - Matcher(cls.WHITESPACE, Type.WHITESPACE), - - # Find identifiers. - Matcher(cls.IDENTIFIER, Type.IDENTIFIER), - - # Finally, we convert semicolons to tokens. - Matcher(cls.SEMICOLON, Type.SEMICOLON)], - - # Matchers for single quote strings. - JavaScriptModes.SINGLE_QUOTE_STRING_MODE: [ - Matcher(cls.SINGLE_QUOTE_TEXT, Type.STRING_TEXT), - Matcher(cls.SINGLE_QUOTE, Type.SINGLE_QUOTE_STRING_END, - JavaScriptModes.TEXT_MODE)], - - # Matchers for double quote strings. - JavaScriptModes.DOUBLE_QUOTE_STRING_MODE: [ - Matcher(cls.DOUBLE_QUOTE_TEXT, Type.STRING_TEXT), - Matcher(cls.DOUBLE_QUOTE, Type.DOUBLE_QUOTE_STRING_END, - JavaScriptModes.TEXT_MODE)], - - # Matchers for template strings. - JavaScriptModes.TEMPLATE_STRING_MODE: [ - Matcher(cls.TEMPLATE_QUOTE_TEXT, Type.STRING_TEXT), - Matcher(cls.TEMPLATE_QUOTE, Type.TEMPLATE_STRING_END, - JavaScriptModes.TEXT_MODE)], - - # Matchers for block comments. - JavaScriptModes.BLOCK_COMMENT_MODE: [ - # First we check for exiting a block comment. - Matcher(cls.END_BLOCK_COMMENT, Type.END_BLOCK_COMMENT, - JavaScriptModes.TEXT_MODE), - - # Match non-comment-ending text.. - Matcher(cls.BLOCK_COMMENT_TEXT, Type.COMMENT)], - - # Matchers for doc comments. - JavaScriptModes.DOC_COMMENT_MODE: cls.COMMON_DOC_MATCHERS + [ - Matcher(cls.DOC_COMMENT_TEXT, Type.COMMENT)], - - JavaScriptModes.DOC_COMMENT_LEX_SPACES_MODE: cls.COMMON_DOC_MATCHERS + [ - Matcher(cls.WHITESPACE, Type.COMMENT), - Matcher(cls.DOC_COMMENT_NO_SPACES_TEXT, Type.COMMENT)], - - # Matchers for single line comments. - JavaScriptModes.LINE_COMMENT_MODE: [ - # We greedy match until the end of the line in line comment mode. - Matcher(cls.ANYTHING, Type.COMMENT, JavaScriptModes.TEXT_MODE)], - - # Matchers for code after the function keyword. - JavaScriptModes.FUNCTION_MODE: [ - # Must match open paren before anything else and move into parameter - # mode, otherwise everything inside the parameter list is parsed - # incorrectly. - Matcher(cls.OPENING_PAREN, Type.START_PARAMETERS, - JavaScriptModes.PARAMETER_MODE), - Matcher(cls.WHITESPACE, Type.WHITESPACE), - Matcher(cls.IDENTIFIER, Type.FUNCTION_NAME)], - - # Matchers for function parameters - JavaScriptModes.PARAMETER_MODE: [ - # When in function parameter mode, a closing paren is treated - # specially. Everything else is treated as lines of parameters. - Matcher(cls.CLOSING_PAREN_WITH_SPACE, Type.END_PARAMETERS, - JavaScriptModes.TEXT_MODE), - Matcher(cls.PARAMETERS, Type.PARAMETERS, - JavaScriptModes.PARAMETER_MODE)]} - - def __init__(self, parse_js_doc=True): - """Create a tokenizer object. - - Args: - parse_js_doc: Whether to do detailed parsing of javascript doc comments, - or simply treat them as normal comments. Defaults to parsing JsDoc. - """ - matchers = self.BuildMatchers() - if not parse_js_doc: - # Make a copy so the original doesn't get modified. - matchers = copy.deepcopy(matchers) - matchers[JavaScriptModes.DOC_COMMENT_MODE] = matchers[ - JavaScriptModes.BLOCK_COMMENT_MODE] - - tokenizer.Tokenizer.__init__(self, JavaScriptModes.TEXT_MODE, matchers, - self.JAVASCRIPT_DEFAULT_TYPES) - - def _CreateToken(self, string, token_type, line, line_number, values=None): - """Creates a new JavaScriptToken object. - - Args: - string: The string of input the token contains. - token_type: The type of token. - line: The text of the line this token is in. - line_number: The line number of the token. - values: A dict of named values within the token. For instance, a - function declaration may have a value called 'name' which captures the - name of the function. - """ - return javascripttokens.JavaScriptToken(string, token_type, line, - line_number, values, line_number)
diff --git a/third_party/closure_linter/closure_linter/javascripttokens.py b/third_party/closure_linter/closure_linter/javascripttokens.py deleted file mode 100755 index 2696195ae..0000000 --- a/third_party/closure_linter/closure_linter/javascripttokens.py +++ /dev/null
@@ -1,157 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Classes to represent JavaScript tokens.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -from closure_linter.common import tokens - -class JavaScriptTokenType(tokens.TokenType): - """Enumeration of JavaScript token types, and useful sets of token types.""" - NUMBER = 'number' - START_SINGLE_LINE_COMMENT = '//' - START_BLOCK_COMMENT = '/*' - START_DOC_COMMENT = '/**' - END_BLOCK_COMMENT = '*/' - END_DOC_COMMENT = 'doc */' - COMMENT = 'comment' - SINGLE_QUOTE_STRING_START = "'string" - SINGLE_QUOTE_STRING_END = "string'" - DOUBLE_QUOTE_STRING_START = '"string' - DOUBLE_QUOTE_STRING_END = 'string"' - TEMPLATE_STRING_START = '`string' - TEMPLATE_STRING_END = 'string`' - STRING_TEXT = 'string' - START_BLOCK = '{' - END_BLOCK = '}' - START_PAREN = '(' - END_PAREN = ')' - START_BRACKET = '[' - END_BRACKET = ']' - REGEX = '/regex/' - FUNCTION_DECLARATION = 'function(...)' - FUNCTION_NAME = 'function functionName(...)' - START_PARAMETERS = 'startparams(' - PARAMETERS = 'pa,ra,ms' - END_PARAMETERS = ')endparams' - SEMICOLON = ';' - DOC_FLAG = '@flag' - DOC_INLINE_FLAG = '{@flag ...}' - DOC_START_BRACE = 'doc {' - DOC_END_BRACE = 'doc }' - DOC_PREFIX = 'comment prefix: * ' - DOC_TYPE_START_BLOCK = 'Type <' - DOC_TYPE_END_BLOCK = 'Type >' - DOC_TYPE_MODIFIER = 'modifier' - SIMPLE_LVALUE = 'lvalue=' - KEYWORD = 'keyword' - OPERATOR = 'operator' - IDENTIFIER = 'identifier' - - STRING_TYPES = frozenset([ - SINGLE_QUOTE_STRING_START, SINGLE_QUOTE_STRING_END, - DOUBLE_QUOTE_STRING_START, DOUBLE_QUOTE_STRING_END, - TEMPLATE_STRING_START, TEMPLATE_STRING_END, STRING_TEXT]) - - COMMENT_TYPES = frozenset([ - START_SINGLE_LINE_COMMENT, COMMENT, - START_BLOCK_COMMENT, START_DOC_COMMENT, - END_BLOCK_COMMENT, END_DOC_COMMENT, - DOC_START_BRACE, DOC_END_BRACE, - DOC_FLAG, DOC_INLINE_FLAG, DOC_PREFIX, - DOC_TYPE_START_BLOCK, DOC_TYPE_END_BLOCK, DOC_TYPE_MODIFIER]) - - FLAG_DESCRIPTION_TYPES = frozenset([ - DOC_INLINE_FLAG, COMMENT, DOC_START_BRACE, DOC_END_BRACE, - DOC_TYPE_START_BLOCK, DOC_TYPE_END_BLOCK, DOC_TYPE_MODIFIER]) - - FLAG_ENDING_TYPES = frozenset([DOC_FLAG, END_DOC_COMMENT]) - - NON_CODE_TYPES = COMMENT_TYPES | frozenset([ - tokens.TokenType.WHITESPACE, tokens.TokenType.BLANK_LINE]) - - UNARY_OPERATORS = ['!', 'new', 'delete', 'typeof', 'void'] - - UNARY_OK_OPERATORS = ['--', '++', '-', '+'] + UNARY_OPERATORS - - UNARY_POST_OPERATORS = ['--', '++'] - - # An expression ender is any token that can end an object - i.e. we could have - # x.y or [1, 2], or (10 + 9) or {a: 10}. - EXPRESSION_ENDER_TYPES = [tokens.TokenType.NORMAL, IDENTIFIER, NUMBER, - SIMPLE_LVALUE, END_BRACKET, END_PAREN, END_BLOCK, - SINGLE_QUOTE_STRING_END, DOUBLE_QUOTE_STRING_END, - TEMPLATE_STRING_END] - - -class JavaScriptToken(tokens.Token): - """JavaScript token subclass of Token, provides extra instance checks. - - The following token types have data in attached_object: - - All JsDoc flags: a parser.JsDocFlag object. - """ - - def IsKeyword(self, keyword): - """Tests if this token is the given keyword. - - Args: - keyword: The keyword to compare to. - - Returns: - True if this token is a keyword token with the given name. - """ - return self.type == JavaScriptTokenType.KEYWORD and self.string == keyword - - def IsOperator(self, operator): - """Tests if this token is the given operator. - - Args: - operator: The operator to compare to. - - Returns: - True if this token is a operator token with the given name. - """ - return self.type == JavaScriptTokenType.OPERATOR and self.string == operator - - def IsAssignment(self): - """Tests if this token is an assignment operator. - - Returns: - True if this token is an assignment operator. - """ - return (self.type == JavaScriptTokenType.OPERATOR and - self.string.endswith('=') and - self.string not in ('==', '!=', '>=', '<=', '===', '!==')) - - def IsComment(self): - """Tests if this token is any part of a comment. - - Returns: - True if this token is any part of a comment. - """ - return self.type in JavaScriptTokenType.COMMENT_TYPES - - def IsCode(self): - """Tests if this token is code, as opposed to a comment or whitespace.""" - return self.type not in JavaScriptTokenType.NON_CODE_TYPES - - def __repr__(self): - return '<JavaScriptToken: %d, %s, "%s", %r, %r>' % (self.line_number, - self.type, self.string, - self.values, - self.metadata)
diff --git a/third_party/closure_linter/closure_linter/not_strict_test.py b/third_party/closure_linter/closure_linter/not_strict_test.py deleted file mode 100755 index c92c13ee..0000000 --- a/third_party/closure_linter/closure_linter/not_strict_test.py +++ /dev/null
@@ -1,74 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2011 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Tests for gjslint --nostrict. - -Tests errors that can be thrown by gjslint when not in strict mode. -""" - - - -import os -import sys -import unittest - -import gflags as flags -import unittest as googletest - -from closure_linter import errors -from closure_linter import runner -from closure_linter.common import filetestcase - -_RESOURCE_PREFIX = 'closure_linter/testdata' - -flags.FLAGS.strict = False -flags.FLAGS.custom_jsdoc_tags = ('customtag', 'requires') -flags.FLAGS.closurized_namespaces = ('goog', 'dummy') -flags.FLAGS.limited_doc_files = ('externs.js', 'dummy.js', - 'limited_doc_checks.js') - - -# List of files under testdata to test. -# We need to list files explicitly since pyglib can't list directories. -_TEST_FILES = [ - 'not_strict.js' - ] - - -class GJsLintTestSuite(unittest.TestSuite): - """Test suite to run a GJsLintTest for each of several files. - - If sys.argv[1:] is non-empty, it is interpreted as a list of filenames in - testdata to test. Otherwise, _TEST_FILES is used. - """ - - def __init__(self, tests=()): - unittest.TestSuite.__init__(self, tests) - - argv = sys.argv and sys.argv[1:] or [] - if argv: - test_files = argv - else: - test_files = _TEST_FILES - for test_file in test_files: - resource_path = os.path.join(_RESOURCE_PREFIX, test_file) - self.addTest(filetestcase.AnnotatedFileTestCase(resource_path, - runner.Run, - errors.ByName)) - -if __name__ == '__main__': - # Don't let main parse args; it happens in the TestSuite. - googletest.main(argv=sys.argv[0:1], defaultTest='GJsLintTestSuite')
diff --git a/third_party/closure_linter/closure_linter/requireprovidesorter.py b/third_party/closure_linter/closure_linter/requireprovidesorter.py deleted file mode 100755 index e7e08a1..0000000 --- a/third_party/closure_linter/closure_linter/requireprovidesorter.py +++ /dev/null
@@ -1,329 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2011 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Contains logic for sorting goog.provide and goog.require statements. - -Closurized JavaScript files use goog.provide and goog.require statements at the -top of the file to manage dependencies. These statements should be sorted -alphabetically, however, it is common for them to be accompanied by inline -comments or suppression annotations. In order to sort these statements without -disrupting their comments and annotations, the association between statements -and comments/annotations must be maintained while sorting. - - RequireProvideSorter: Handles checking/fixing of provide/require statements. -""" - - - -from closure_linter import javascripttokens -from closure_linter import tokenutil - -# Shorthand -Type = javascripttokens.JavaScriptTokenType - - -class RequireProvideSorter(object): - """Checks for and fixes alphabetization of provide and require statements. - - When alphabetizing, comments on the same line or comments directly above a - goog.provide or goog.require statement are associated with that statement and - stay with the statement as it gets sorted. - """ - - def CheckProvides(self, token): - """Checks alphabetization of goog.provide statements. - - Iterates over tokens in given token stream, identifies goog.provide tokens, - and checks that they occur in alphabetical order by the object being - provided. - - Args: - token: A token in the token stream before any goog.provide tokens. - - Returns: - The first provide token in the token stream. - - None is returned if all goog.provide statements are already sorted. - """ - provide_tokens = self._GetRequireOrProvideTokens(token, 'goog.provide') - provide_strings = self._GetRequireOrProvideTokenStrings(provide_tokens) - sorted_provide_strings = sorted(provide_strings) - if provide_strings != sorted_provide_strings: - return provide_tokens[0] - return None - - def CheckRequires(self, token): - """Checks alphabetization of goog.require statements. - - Iterates over tokens in given token stream, identifies goog.require tokens, - and checks that they occur in alphabetical order by the dependency being - required. - - Args: - token: A token in the token stream before any goog.require tokens. - - Returns: - The first require token in the token stream. - - None is returned if all goog.require statements are already sorted. - """ - require_tokens = self._GetRequireOrProvideTokens(token, 'goog.require') - require_strings = self._GetRequireOrProvideTokenStrings(require_tokens) - sorted_require_strings = sorted(require_strings) - if require_strings != sorted_require_strings: - return require_tokens[0] - return None - - def FixProvides(self, token): - """Sorts goog.provide statements in the given token stream alphabetically. - - Args: - token: The first token in the token stream. - """ - self._FixProvidesOrRequires( - self._GetRequireOrProvideTokens(token, 'goog.provide')) - - def FixRequires(self, token): - """Sorts goog.require statements in the given token stream alphabetically. - - Args: - token: The first token in the token stream. - """ - self._FixProvidesOrRequires( - self._GetRequireOrProvideTokens(token, 'goog.require')) - - def _FixProvidesOrRequires(self, tokens): - """Sorts goog.provide or goog.require statements. - - Args: - tokens: A list of goog.provide or goog.require tokens in the order they - appear in the token stream. i.e. the first token in this list must - be the first goog.provide or goog.require token. - """ - strings = self._GetRequireOrProvideTokenStrings(tokens) - sorted_strings = sorted(strings) - - # Make a separate pass to remove any blank lines between goog.require/ - # goog.provide tokens. - first_token = tokens[0] - last_token = tokens[-1] - i = last_token - while i != first_token and i is not None: - if i.type is Type.BLANK_LINE: - tokenutil.DeleteToken(i) - i = i.previous - - # A map from required/provided object name to tokens that make up the line - # it was on, including any comments immediately before it or after it on the - # same line. - tokens_map = self._GetTokensMap(tokens) - - # Iterate over the map removing all tokens. - for name in tokens_map: - tokens_to_delete = tokens_map[name] - for i in tokens_to_delete: - tokenutil.DeleteToken(i) - - # Save token to rest of file. Sorted token will be inserted before this. - rest_of_file = tokens_map[strings[-1]][-1].next - - # Re-add all tokens in the map in alphabetical order. - insert_after = tokens[0].previous - for string in sorted_strings: - for i in tokens_map[string]: - if rest_of_file: - tokenutil.InsertTokenBefore(i, rest_of_file) - else: - tokenutil.InsertTokenAfter(i, insert_after) - insert_after = i - - def _GetRequireOrProvideTokens(self, token, token_string): - """Gets all goog.provide or goog.require tokens in the given token stream. - - Args: - token: The first token in the token stream. - token_string: One of 'goog.provide' or 'goog.require' to indicate which - tokens to find. - - Returns: - A list of goog.provide or goog.require tokens in the order they appear in - the token stream. - """ - tokens = [] - while token: - if token.type == Type.IDENTIFIER: - if token.string == token_string: - tokens.append(token) - elif token.string not in [ - 'goog.provide', 'goog.require', 'goog.setTestOnly']: - # These 3 identifiers are at the top of the file. So if any other - # identifier is encountered, return. - # TODO(user): Once it's decided what ordering goog.require - # should use, add 'goog.module' to the list above and implement the - # decision. - break - token = token.next - - return tokens - - def _GetRequireOrProvideTokenStrings(self, tokens): - """Gets a list of strings corresponding to the given list of tokens. - - The string will be the next string in the token stream after each token in - tokens. This is used to find the object being provided/required by a given - goog.provide or goog.require token. - - Args: - tokens: A list of goog.provide or goog.require tokens. - - Returns: - A list of object names that are being provided or required by the given - list of tokens. For example: - - ['object.a', 'object.c', 'object.b'] - """ - token_strings = [] - for token in tokens: - if not token.is_deleted: - name = tokenutil.GetStringAfterToken(token) - token_strings.append(name) - return token_strings - - def _GetTokensMap(self, tokens): - """Gets a map from object name to tokens associated with that object. - - Starting from the goog.provide/goog.require token, searches backwards in the - token stream for any lines that start with a comment. These lines are - associated with the goog.provide/goog.require token. Also associates any - tokens on the same line as the goog.provide/goog.require token with that - token. - - Args: - tokens: A list of goog.provide or goog.require tokens. - - Returns: - A dictionary that maps object names to the tokens associated with the - goog.provide or goog.require of that object name. For example: - - { - 'object.a': [JavaScriptToken, JavaScriptToken, ...], - 'object.b': [...] - } - - The list of tokens includes any comment lines above the goog.provide or - goog.require statement and everything after the statement on the same - line. For example, all of the following would be associated with - 'object.a': - - /** @suppress {extraRequire} */ - goog.require('object.a'); // Some comment. - """ - tokens_map = {} - for token in tokens: - object_name = tokenutil.GetStringAfterToken(token) - # If the previous line starts with a comment, presume that the comment - # relates to the goog.require or goog.provide and keep them together when - # sorting. - first_token = token - previous_first_token = tokenutil.GetFirstTokenInPreviousLine(first_token) - while (previous_first_token and - previous_first_token.IsAnyType(Type.COMMENT_TYPES)): - first_token = previous_first_token - previous_first_token = tokenutil.GetFirstTokenInPreviousLine( - first_token) - - # Find the last token on the line. - last_token = tokenutil.GetLastTokenInSameLine(token) - - all_tokens = self._GetTokenList(first_token, last_token) - tokens_map[object_name] = all_tokens - return tokens_map - - def _GetTokenList(self, first_token, last_token): - """Gets a list of all tokens from first_token to last_token, inclusive. - - Args: - first_token: The first token to get. - last_token: The last token to get. - - Returns: - A list of all tokens between first_token and last_token, including both - first_token and last_token. - - Raises: - Exception: If the token stream ends before last_token is reached. - """ - token_list = [] - token = first_token - while token != last_token: - if not token: - raise Exception('ran out of tokens') - token_list.append(token) - token = token.next - token_list.append(last_token) - - return token_list - - def GetFixedRequireString(self, token): - """Get fixed/sorted order of goog.require statements. - - Args: - token: The first token in the token stream. - - Returns: - A string for correct sorted order of goog.require. - """ - return self._GetFixedRequireOrProvideString( - self._GetRequireOrProvideTokens(token, 'goog.require')) - - def GetFixedProvideString(self, token): - """Get fixed/sorted order of goog.provide statements. - - Args: - token: The first token in the token stream. - - Returns: - A string for correct sorted order of goog.provide. - """ - return self._GetFixedRequireOrProvideString( - self._GetRequireOrProvideTokens(token, 'goog.provide')) - - def _GetFixedRequireOrProvideString(self, tokens): - """Sorts goog.provide or goog.require statements. - - Args: - tokens: A list of goog.provide or goog.require tokens in the order they - appear in the token stream. i.e. the first token in this list must - be the first goog.provide or goog.require token. - - Returns: - A string for sorted goog.require or goog.provide statements - """ - - # A map from required/provided object name to tokens that make up the line - # it was on, including any comments immediately before it or after it on the - # same line. - tokens_map = self._GetTokensMap(tokens) - sorted_strings = sorted(tokens_map.keys()) - - new_order = '' - for string in sorted_strings: - for i in tokens_map[string]: - new_order += i.string - if i.IsLastInLine(): - new_order += '\n' - - return new_order
diff --git a/third_party/closure_linter/closure_linter/requireprovidesorter_test.py b/third_party/closure_linter/closure_linter/requireprovidesorter_test.py deleted file mode 100644 index fecb6d0..0000000 --- a/third_party/closure_linter/closure_linter/requireprovidesorter_test.py +++ /dev/null
@@ -1,155 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Unit tests for RequireProvideSorter.""" - - - -import unittest as googletest -from closure_linter import javascripttokens -from closure_linter import requireprovidesorter -from closure_linter import testutil - -# pylint: disable=g-bad-name -TokenType = javascripttokens.JavaScriptTokenType - - -class RequireProvideSorterTest(googletest.TestCase): - """Tests for RequireProvideSorter.""" - - def testGetFixedProvideString(self): - """Tests that fixed string constains proper comments also.""" - input_lines = [ - 'goog.provide(\'package.xyz\');', - '/** @suppress {extraprovide} **/', - 'goog.provide(\'package.abcd\');' - ] - - expected_lines = [ - '/** @suppress {extraprovide} **/', - 'goog.provide(\'package.abcd\');', - 'goog.provide(\'package.xyz\');' - ] - - token = testutil.TokenizeSourceAndRunEcmaPass(input_lines) - - sorter = requireprovidesorter.RequireProvideSorter() - fixed_provide_string = sorter.GetFixedProvideString(token) - - self.assertEquals(expected_lines, fixed_provide_string.splitlines()) - - def testGetFixedRequireString(self): - """Tests that fixed string constains proper comments also.""" - input_lines = [ - 'goog.require(\'package.xyz\');', - '/** This is needed for scope. **/', - 'goog.require(\'package.abcd\');' - ] - - expected_lines = [ - '/** This is needed for scope. **/', - 'goog.require(\'package.abcd\');', - 'goog.require(\'package.xyz\');' - ] - - token = testutil.TokenizeSourceAndRunEcmaPass(input_lines) - - sorter = requireprovidesorter.RequireProvideSorter() - fixed_require_string = sorter.GetFixedRequireString(token) - - self.assertEquals(expected_lines, fixed_require_string.splitlines()) - - def testFixRequires_removeBlankLines(self): - """Tests that blank lines are omitted in sorted goog.require statements.""" - input_lines = [ - 'goog.provide(\'package.subpackage.Whatever\');', - '', - 'goog.require(\'package.subpackage.ClassB\');', - '', - 'goog.require(\'package.subpackage.ClassA\');' - ] - expected_lines = [ - 'goog.provide(\'package.subpackage.Whatever\');', - '', - 'goog.require(\'package.subpackage.ClassA\');', - 'goog.require(\'package.subpackage.ClassB\');' - ] - token = testutil.TokenizeSourceAndRunEcmaPass(input_lines) - - sorter = requireprovidesorter.RequireProvideSorter() - sorter.FixRequires(token) - - self.assertEquals(expected_lines, self._GetLines(token)) - - def fixRequiresTest_withTestOnly(self, position): - """Regression-tests sorting even with a goog.setTestOnly statement. - - Args: - position: The position in the list where to insert the goog.setTestOnly - statement. Will be used to test all possible combinations for - this test. - """ - input_lines = [ - 'goog.provide(\'package.subpackage.Whatever\');', - '', - 'goog.require(\'package.subpackage.ClassB\');', - 'goog.require(\'package.subpackage.ClassA\');' - ] - expected_lines = [ - 'goog.provide(\'package.subpackage.Whatever\');', - '', - 'goog.require(\'package.subpackage.ClassA\');', - 'goog.require(\'package.subpackage.ClassB\');' - ] - input_lines.insert(position, 'goog.setTestOnly();') - expected_lines.insert(position, 'goog.setTestOnly();') - - token = testutil.TokenizeSourceAndRunEcmaPass(input_lines) - - sorter = requireprovidesorter.RequireProvideSorter() - sorter.FixRequires(token) - - self.assertEquals(expected_lines, self._GetLines(token)) - - def testFixRequires_withTestOnly(self): - """Regression-tests sorting even after a goog.setTestOnly statement.""" - - # goog.setTestOnly at first line. - self.fixRequiresTest_withTestOnly(position=0) - - # goog.setTestOnly after goog.provide. - self.fixRequiresTest_withTestOnly(position=1) - - # goog.setTestOnly before goog.require. - self.fixRequiresTest_withTestOnly(position=2) - - # goog.setTestOnly after goog.require. - self.fixRequiresTest_withTestOnly(position=4) - - def _GetLines(self, token): - """Returns an array of lines based on the specified token stream.""" - lines = [] - line = '' - while token: - line += token.string - if token.IsLastInLine(): - lines.append(line) - line = '' - token = token.next - return lines - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/runner.py b/third_party/closure_linter/closure_linter/runner.py deleted file mode 100644 index 04e7fa4..0000000 --- a/third_party/closure_linter/closure_linter/runner.py +++ /dev/null
@@ -1,198 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Main lint function. Tokenizes file, runs passes, and feeds to checker.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = 'nnaze@google.com (Nathan Naze)' - -import traceback - -import gflags as flags - -from closure_linter import checker -from closure_linter import ecmalintrules -from closure_linter import ecmametadatapass -from closure_linter import error_check -from closure_linter import errors -from closure_linter import javascriptstatetracker -from closure_linter import javascripttokenizer - -from closure_linter.common import error -from closure_linter.common import htmlutil -from closure_linter.common import tokens - -flags.DEFINE_list('limited_doc_files', ['dummy.js', 'externs.js'], - 'List of files with relaxed documentation checks. Will not ' - 'report errors for missing documentation, some missing ' - 'descriptions, or methods whose @return tags don\'t have a ' - 'matching return statement.') -flags.DEFINE_boolean('error_trace', False, - 'Whether to show error exceptions.') -flags.ADOPT_module_key_flags(checker) -flags.ADOPT_module_key_flags(ecmalintrules) -flags.ADOPT_module_key_flags(error_check) - - -def _GetLastNonWhiteSpaceToken(start_token): - """Get the last non-whitespace token in a token stream.""" - ret_token = None - - whitespace_tokens = frozenset([ - tokens.TokenType.WHITESPACE, tokens.TokenType.BLANK_LINE]) - for t in start_token: - if t.type not in whitespace_tokens: - ret_token = t - - return ret_token - - -def _IsHtml(filename): - return filename.endswith('.html') or filename.endswith('.htm') - - -def _Tokenize(fileobj): - """Tokenize a file. - - Args: - fileobj: file-like object (or iterable lines) with the source. - - Returns: - The first token in the token stream and the ending mode of the tokenizer. - """ - tokenizer = javascripttokenizer.JavaScriptTokenizer() - start_token = tokenizer.TokenizeFile(fileobj) - return start_token, tokenizer.mode - - -def _IsLimitedDocCheck(filename, limited_doc_files): - """Whether this this a limited-doc file. - - Args: - filename: The filename. - limited_doc_files: Iterable of strings. Suffixes of filenames that should - be limited doc check. - - Returns: - Whether the file should be limited check. - """ - for limited_doc_filename in limited_doc_files: - if filename.endswith(limited_doc_filename): - return True - return False - - -def Run(filename, error_handler, source=None): - """Tokenize, run passes, and check the given file. - - Args: - filename: The path of the file to check - error_handler: The error handler to report errors to. - source: A file-like object with the file source. If omitted, the file will - be read from the filename path. - """ - if not source: - try: - source = open(filename) - except IOError: - error_handler.HandleFile(filename, None) - error_handler.HandleError( - error.Error(errors.FILE_NOT_FOUND, 'File not found')) - error_handler.FinishFile() - return - - if _IsHtml(filename): - source_file = htmlutil.GetScriptLines(source) - else: - source_file = source - - token, tokenizer_mode = _Tokenize(source_file) - - error_handler.HandleFile(filename, token) - - # If we did not end in the basic mode, this a failed parse. - if tokenizer_mode is not javascripttokenizer.JavaScriptModes.TEXT_MODE: - error_handler.HandleError( - error.Error(errors.FILE_IN_BLOCK, - 'File ended in mode "%s".' % tokenizer_mode, - _GetLastNonWhiteSpaceToken(token))) - - # Run the ECMA pass - error_token = None - - ecma_pass = ecmametadatapass.EcmaMetaDataPass() - error_token = RunMetaDataPass(token, ecma_pass, error_handler, filename) - - is_limited_doc_check = ( - _IsLimitedDocCheck(filename, flags.FLAGS.limited_doc_files)) - - _RunChecker(token, error_handler, - is_limited_doc_check, - is_html=_IsHtml(filename), - stop_token=error_token) - - error_handler.FinishFile() - - -def RunMetaDataPass(start_token, metadata_pass, error_handler, filename=''): - """Run a metadata pass over a token stream. - - Args: - start_token: The first token in a token stream. - metadata_pass: Metadata pass to run. - error_handler: The error handler to report errors to. - filename: Filename of the source. - - Returns: - The token where the error occurred (if any). - """ - - try: - metadata_pass.Process(start_token) - except ecmametadatapass.ParseError, parse_err: - if flags.FLAGS.error_trace: - traceback.print_exc() - error_token = parse_err.token - error_msg = str(parse_err) - error_handler.HandleError( - error.Error(errors.FILE_DOES_NOT_PARSE, - ('Error parsing file at token "%s". Unable to ' - 'check the rest of file.' - '\nError "%s"' % (error_token, error_msg)), error_token)) - return error_token - except Exception: # pylint: disable=broad-except - traceback.print_exc() - error_handler.HandleError( - error.Error( - errors.FILE_DOES_NOT_PARSE, - 'Internal error in %s' % filename)) - - -def _RunChecker(start_token, error_handler, - limited_doc_checks, is_html, - stop_token=None): - - state_tracker = javascriptstatetracker.JavaScriptStateTracker() - - style_checker = checker.JavaScriptStyleChecker( - state_tracker=state_tracker, - error_handler=error_handler) - - style_checker.Check(start_token, - is_html=is_html, - limited_doc_checks=limited_doc_checks, - stop_token=stop_token)
diff --git a/third_party/closure_linter/closure_linter/runner_test.py b/third_party/closure_linter/closure_linter/runner_test.py deleted file mode 100644 index da5857d..0000000 --- a/third_party/closure_linter/closure_linter/runner_test.py +++ /dev/null
@@ -1,101 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Unit tests for the runner module.""" - -__author__ = ('nnaze@google.com (Nathan Naze)') - -import StringIO - - -import mox - - -import unittest as googletest - -from closure_linter import errors -from closure_linter import runner -from closure_linter.common import error -from closure_linter.common import errorhandler -from closure_linter.common import tokens - - -class LimitedDocTest(googletest.TestCase): - - def testIsLimitedDocCheck(self): - self.assertTrue(runner._IsLimitedDocCheck('foo_test.js', ['_test.js'])) - self.assertFalse(runner._IsLimitedDocCheck('foo_bar.js', ['_test.js'])) - - self.assertTrue(runner._IsLimitedDocCheck( - 'foo_moo.js', ['moo.js', 'quack.js'])) - self.assertFalse(runner._IsLimitedDocCheck( - 'foo_moo.js', ['woof.js', 'quack.js'])) - - -class RunnerTest(googletest.TestCase): - - def setUp(self): - self.mox = mox.Mox() - - def testRunOnMissingFile(self): - mock_error_handler = self.mox.CreateMock(errorhandler.ErrorHandler) - - def ValidateError(err): - return (isinstance(err, error.Error) and - err.code is errors.FILE_NOT_FOUND and - err.token is None) - - mock_error_handler.HandleFile('does_not_exist.js', None) - mock_error_handler.HandleError(mox.Func(ValidateError)) - mock_error_handler.FinishFile() - - self.mox.ReplayAll() - - runner.Run('does_not_exist.js', mock_error_handler) - - self.mox.VerifyAll() - - def testBadTokenization(self): - mock_error_handler = self.mox.CreateMock(errorhandler.ErrorHandler) - - def ValidateError(err): - return (isinstance(err, error.Error) and - err.code is errors.FILE_IN_BLOCK and - err.token.string == '}') - - mock_error_handler.HandleFile('foo.js', mox.IsA(tokens.Token)) - mock_error_handler.HandleError(mox.Func(ValidateError)) - mock_error_handler.HandleError(mox.IsA(error.Error)) - mock_error_handler.FinishFile() - - self.mox.ReplayAll() - - source = StringIO.StringIO(_BAD_TOKENIZATION_SCRIPT) - runner.Run('foo.js', mock_error_handler, source) - - self.mox.VerifyAll() - - -_BAD_TOKENIZATION_SCRIPT = """ -function foo () { - var a = 3; - var b = 2; - return b + a; /* Comment not closed -} -""" - - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/scopeutil.py b/third_party/closure_linter/closure_linter/scopeutil.py deleted file mode 100644 index a7ca9b6..0000000 --- a/third_party/closure_linter/closure_linter/scopeutil.py +++ /dev/null
@@ -1,206 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Tools to match goog.scope alias statements.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = ('nnaze@google.com (Nathan Naze)') - -import itertools - -from closure_linter import ecmametadatapass -from closure_linter import tokenutil -from closure_linter.javascripttokens import JavaScriptTokenType - - - -def IsGoogScopeBlock(context): - """Whether the given context is a goog.scope block. - - This function only checks that the block is a function block inside - a goog.scope() call. - - TODO(nnaze): Implement goog.scope checks that verify the call is - in the root context and contains only a single function literal. - - Args: - context: An EcmaContext of type block. - - Returns: - Whether the context is a goog.scope block. - """ - - if context.type != ecmametadatapass.EcmaContext.BLOCK: - return False - - if not _IsFunctionLiteralBlock(context): - return False - - # Check that this function is contained by a group - # of form "goog.scope(...)". - parent = context.parent - if parent and parent.type is ecmametadatapass.EcmaContext.GROUP: - - last_code_token = parent.start_token.metadata.last_code - - if (last_code_token and - last_code_token.type is JavaScriptTokenType.IDENTIFIER and - last_code_token.string == 'goog.scope'): - return True - - return False - - -def _IsFunctionLiteralBlock(block_context): - """Check if a context is a function literal block (without parameters). - - Example function literal block: 'function() {}' - - Args: - block_context: An EcmaContext of type block. - - Returns: - Whether this context is a function literal block. - """ - - previous_code_tokens_iter = itertools.ifilter( - lambda token: token not in JavaScriptTokenType.NON_CODE_TYPES, - reversed(block_context.start_token)) - - # Ignore the current token - next(previous_code_tokens_iter, None) - - # Grab the previous three tokens and put them in correct order. - previous_code_tokens = list(itertools.islice(previous_code_tokens_iter, 3)) - previous_code_tokens.reverse() - - # There aren't three previous tokens. - if len(previous_code_tokens) is not 3: - return False - - # Check that the previous three code tokens are "function ()" - previous_code_token_types = [token.type for token in previous_code_tokens] - if (previous_code_token_types == [ - JavaScriptTokenType.FUNCTION_DECLARATION, - JavaScriptTokenType.START_PARAMETERS, - JavaScriptTokenType.END_PARAMETERS]): - return True - - return False - - -def IsInClosurizedNamespace(symbol, closurized_namespaces): - """Match a goog.scope alias. - - Args: - symbol: An identifier like 'goog.events.Event'. - closurized_namespaces: Iterable of valid Closurized namespaces (strings). - - Returns: - True if symbol is an identifier in a Closurized namespace, otherwise False. - """ - for ns in closurized_namespaces: - if symbol.startswith(ns + '.'): - return True - - return False - - -def _GetVarAssignmentTokens(context): - """Returns the tokens from context if it is a var assignment. - - Args: - context: An EcmaContext. - - Returns: - If a var assignment, the tokens contained within it w/o the trailing - semicolon. - """ - if context.type != ecmametadatapass.EcmaContext.VAR: - return - - # Get the tokens in this statement. - if context.start_token and context.end_token: - statement_tokens = tokenutil.GetTokenRange(context.start_token, - context.end_token) - else: - return - - # And now just those tokens that are actually code. - is_non_code_type = lambda t: t.type not in JavaScriptTokenType.NON_CODE_TYPES - code_tokens = filter(is_non_code_type, statement_tokens) - - # Pop off the semicolon if present. - if code_tokens and code_tokens[-1].IsType(JavaScriptTokenType.SEMICOLON): - code_tokens.pop() - - if len(code_tokens) < 4: - return - - if (code_tokens[0].IsKeyword('var') and - code_tokens[1].IsType(JavaScriptTokenType.SIMPLE_LVALUE) and - code_tokens[2].IsOperator('=')): - return code_tokens - - -def MatchAlias(context): - """Match an alias statement (some identifier assigned to a variable). - - Example alias: var MyClass = proj.longNamespace.MyClass. - - Args: - context: An EcmaContext of type EcmaContext.VAR. - - Returns: - If a valid alias, returns a tuple of alias and symbol, otherwise None. - """ - code_tokens = _GetVarAssignmentTokens(context) - if code_tokens is None: - return - - if all(tokenutil.IsIdentifierOrDot(t) for t in code_tokens[3:]): - # var Foo = bar.Foo; - alias, symbol = code_tokens[1], code_tokens[3] - # Mark both tokens as an alias definition to not count them as usages. - alias.metadata.is_alias_definition = True - symbol.metadata.is_alias_definition = True - return alias.string, tokenutil.GetIdentifierForToken(symbol) - - -def MatchModuleAlias(context): - """Match an alias statement in a goog.module style import. - - Example alias: var MyClass = goog.require('proj.longNamespace.MyClass'). - - Args: - context: An EcmaContext. - - Returns: - If a valid alias, returns a tuple of alias and symbol, otherwise None. - """ - code_tokens = _GetVarAssignmentTokens(context) - if code_tokens is None: - return - - if(code_tokens[3].IsType(JavaScriptTokenType.IDENTIFIER) and - code_tokens[3].string == 'goog.require'): - # var Foo = goog.require('bar.Foo'); - alias = code_tokens[1] - symbol = tokenutil.GetStringAfterToken(code_tokens[3]) - if symbol: - alias.metadata.is_alias_definition = True - return alias.string, symbol
diff --git a/third_party/closure_linter/closure_linter/scopeutil_test.py b/third_party/closure_linter/closure_linter/scopeutil_test.py deleted file mode 100644 index 722a953..0000000 --- a/third_party/closure_linter/closure_linter/scopeutil_test.py +++ /dev/null
@@ -1,222 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Unit tests for the scopeutil module.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = ('nnaze@google.com (Nathan Naze)') - - -import unittest as googletest - -from closure_linter import ecmametadatapass -from closure_linter import scopeutil -from closure_linter import testutil - - -def _FindContexts(start_token): - """Depth first search of all contexts referenced by a token stream. - - Includes contexts' parents, which might not be directly referenced - by any token in the stream. - - Args: - start_token: First token in the token stream. - - Yields: - All contexts referenced by this token stream. - """ - - seen_contexts = set() - - # For each token, yield the context if we haven't seen it before. - for token in start_token: - - token_context = token.metadata.context - contexts = [token_context] - - # Also grab all the context's ancestors. - parent = token_context.parent - while parent: - contexts.append(parent) - parent = parent.parent - - # Yield each of these contexts if we've not seen them. - for context in contexts: - if context not in seen_contexts: - yield context - - seen_contexts.add(context) - - -def _FindFirstContextOfType(token, context_type): - """Returns the first statement context.""" - for context in _FindContexts(token): - if context.type == context_type: - return context - - -def _ParseAssignment(script): - start_token = testutil.TokenizeSourceAndRunEcmaPass(script) - statement = _FindFirstContextOfType( - start_token, ecmametadatapass.EcmaContext.VAR) - return statement - - -class StatementTest(googletest.TestCase): - - def assertAlias(self, expected_match, script): - statement = _ParseAssignment(script) - match = scopeutil.MatchAlias(statement) - self.assertEquals(expected_match, match) - - def assertModuleAlias(self, expected_match, script): - statement = _ParseAssignment(script) - match = scopeutil.MatchModuleAlias(statement) - self.assertEquals(expected_match, match) - - def testSimpleAliases(self): - self.assertAlias( - ('foo', 'goog.foo'), - 'var foo = goog.foo;') - - self.assertAlias( - ('foo', 'goog.foo'), - 'var foo = goog.foo') # No semicolon - - def testAliasWithComment(self): - self.assertAlias( - ('Component', 'goog.ui.Component'), - 'var Component = /* comment */ goog.ui.Component;') - - def testMultilineAlias(self): - self.assertAlias( - ('Component', 'goog.ui.Component'), - 'var Component = \n goog.ui.\n Component;') - - def testNonSymbolAliasVarStatements(self): - self.assertAlias(None, 'var foo = 3;') - self.assertAlias(None, 'var foo = function() {};') - self.assertAlias(None, 'var foo = bar ? baz : qux;') - - def testModuleAlias(self): - self.assertModuleAlias( - ('foo', 'goog.foo'), - 'var foo = goog.require("goog.foo");') - self.assertModuleAlias( - None, - 'var foo = goog.require(notastring);') - - -class ScopeBlockTest(googletest.TestCase): - - @staticmethod - def _GetBlocks(source): - start_token = testutil.TokenizeSourceAndRunEcmaPass(source) - for context in _FindContexts(start_token): - if context.type is ecmametadatapass.EcmaContext.BLOCK: - yield context - - def assertNoBlocks(self, script): - blocks = list(self._GetBlocks(script)) - self.assertEquals([], blocks) - - def testNotBlocks(self): - # Ensure these are not considered blocks. - self.assertNoBlocks('goog.scope(if{});') - self.assertNoBlocks('goog.scope(for{});') - self.assertNoBlocks('goog.scope(switch{});') - self.assertNoBlocks('goog.scope(function foo{});') - - def testNonScopeBlocks(self): - - blocks = list(self._GetBlocks('goog.scope(try{});')) - self.assertEquals(1, len(blocks)) - self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop())) - - blocks = list(self._GetBlocks('goog.scope(function(a,b){});')) - self.assertEquals(1, len(blocks)) - self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop())) - - blocks = list(self._GetBlocks('goog.scope(try{} catch(){});')) - # Two blocks: try and catch. - self.assertEquals(2, len(blocks)) - self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop())) - self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop())) - - blocks = list(self._GetBlocks('goog.scope(try{} catch(){} finally {});')) - self.assertEquals(3, len(blocks)) - self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop())) - self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop())) - self.assertFalse(scopeutil.IsGoogScopeBlock(blocks.pop())) - - -class AliasTest(googletest.TestCase): - - def setUp(self): - self.start_token = testutil.TokenizeSourceAndRunEcmaPass(_TEST_SCRIPT) - - def testMatchAliasStatement(self): - matches = set() - for context in _FindContexts(self.start_token): - match = scopeutil.MatchAlias(context) - if match: - matches.add(match) - - self.assertEquals( - set([('bar', 'baz'), - ('foo', 'this.foo_'), - ('Component', 'goog.ui.Component'), - ('MyClass', 'myproject.foo.MyClass'), - ('NonClosurizedClass', 'aaa.bbb.NonClosurizedClass')]), - matches) - - def testMatchAliasStatement_withClosurizedNamespaces(self): - - closurized_namepaces = frozenset(['goog', 'myproject']) - - matches = set() - for context in _FindContexts(self.start_token): - match = scopeutil.MatchAlias(context) - if match: - unused_alias, symbol = match - if scopeutil.IsInClosurizedNamespace(symbol, closurized_namepaces): - matches.add(match) - - self.assertEquals( - set([('MyClass', 'myproject.foo.MyClass'), - ('Component', 'goog.ui.Component')]), - matches) - -_TEST_SCRIPT = """ -goog.scope(function() { - var Component = goog.ui.Component; // scope alias - var MyClass = myproject.foo.MyClass; // scope alias - - // Scope alias of non-Closurized namespace. - var NonClosurizedClass = aaa.bbb.NonClosurizedClass; - - var foo = this.foo_; // non-scope object property alias - var bar = baz; // variable alias - - var component = new Component(); -}); - -""" - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/statetracker.py b/third_party/closure_linter/closure_linter/statetracker.py deleted file mode 100755 index 5730facb8..0000000 --- a/third_party/closure_linter/closure_linter/statetracker.py +++ /dev/null
@@ -1,1300 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Light weight EcmaScript state tracker that reads tokens and tracks state.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -import re - -from closure_linter import javascripttokenizer -from closure_linter import javascripttokens -from closure_linter import tokenutil -from closure_linter import typeannotation - -# Shorthand -Type = javascripttokens.JavaScriptTokenType - - -class DocFlag(object): - """Generic doc flag object. - - Attribute: - flag_type: param, return, define, type, etc. - flag_token: The flag token. - type_start_token: The first token specifying the flag type, - including braces. - type_end_token: The last token specifying the flag type, - including braces. - type: The type spec string. - jstype: The type spec, a TypeAnnotation instance. - name_token: The token specifying the flag name. - name: The flag name - description_start_token: The first token in the description. - description_end_token: The end token in the description. - description: The description. - """ - - # Please keep these lists alphabetized. - - # The list of standard jsdoc tags is from - STANDARD_DOC = frozenset([ - 'author', - 'bug', - 'classTemplate', - 'consistentIdGenerator', - 'const', - 'constructor', - 'define', - 'deprecated', - 'dict', - 'enum', - 'export', - 'expose', - 'extends', - 'externs', - 'fileoverview', - 'idGenerator', - 'implements', - 'implicitCast', - 'interface', - 'lends', - 'license', - 'ngInject', # This annotation is specific to AngularJS. - 'noalias', - 'nocompile', - 'nosideeffects', - 'override', - 'owner', - 'nocollapse', - 'package', - 'param', - 'polymerBehavior', # This annotation is specific to Polymer. - 'preserve', - 'private', - 'protected', - 'public', - 'return', - 'see', - 'stableIdGenerator', - 'struct', - 'supported', - 'template', - 'this', - 'type', - 'typedef', - 'unrestricted', - ]) - - ANNOTATION = frozenset(['preserveTry', 'suppress']) - - LEGAL_DOC = STANDARD_DOC | ANNOTATION - - # Includes all Closure Compiler @suppress types. - # Not all of these annotations are interpreted by Closure Linter. - # - # Specific cases: - # - accessControls is supported by the compiler at the expression - # and method level to suppress warnings about private/protected - # access (method level applies to all references in the method). - # The linter mimics the compiler behavior. - SUPPRESS_TYPES = frozenset([ - 'accessControls', - 'ambiguousFunctionDecl', - 'checkDebuggerStatement', - 'checkRegExp', - 'checkStructDictInheritance', - 'checkTypes', - 'checkVars', - 'const', - 'constantProperty', - 'deprecated', - 'duplicate', - 'es5Strict', - 'externsValidation', - 'extraProvide', - 'extraRequire', - 'fileoverviewTags', - 'globalThis', - 'internetExplorerChecks', - 'invalidCasts', - 'missingProperties', - 'missingProvide', - 'missingRequire', - 'missingReturn', - 'nonStandardJsDocs', - 'reportUnknownTypes', - 'strictModuleDepCheck', - 'suspiciousCode', - 'tweakValidation', - 'typeInvalidation', - 'undefinedNames', - 'undefinedVars', - 'underscore', - 'unknownDefines', - 'unnecessaryCasts', - 'unusedPrivateMembers', - 'uselessCode', - 'visibility', - 'with', - ]) - - HAS_DESCRIPTION = frozenset([ - 'define', - 'deprecated', - 'desc', - 'fileoverview', - 'license', - 'param', - 'preserve', - 'return', - 'supported', - ]) - - # Docflags whose argument should be parsed using the typeannotation parser. - HAS_TYPE = frozenset([ - 'const', - 'define', - 'enum', - 'export', - 'extends', - 'final', - 'implements', - 'mods', - 'package', - 'param', - 'private', - 'protected', - 'public', - 'return', - 'suppress', - 'type', - 'typedef', - ]) - - # Docflags for which it's ok to omit the type (flag without an argument). - CAN_OMIT_TYPE = frozenset([ - 'const', - 'enum', - 'export', - 'final', - 'package', - 'private', - 'protected', - 'public', - 'suppress', # We'll raise a separate INCORRECT_SUPPRESS_SYNTAX instead. - ]) - - # Docflags that only take a type as an argument and should not parse a - # following description. - TYPE_ONLY = frozenset([ - 'const', - 'enum', - 'extends', - 'implements', - 'package', - 'suppress', - 'type', - ]) - - HAS_NAME = frozenset(['param']) - - EMPTY_COMMENT_LINE = re.compile(r'^\s*\*?\s*$') - EMPTY_STRING = re.compile(r'^\s*$') - - def __init__(self, flag_token, error_handler=None): - """Creates the DocFlag object and attaches it to the given start token. - - Args: - flag_token: The starting token of the flag. - error_handler: An optional error handler for errors occurring while - parsing the doctype. - """ - self.flag_token = flag_token - self.flag_type = flag_token.string.strip().lstrip('@') - - # Extract type, if applicable. - self.type = None - self.jstype = None - self.type_start_token = None - self.type_end_token = None - if self.flag_type in self.HAS_TYPE: - brace = tokenutil.SearchUntil(flag_token, [Type.DOC_START_BRACE], - Type.FLAG_ENDING_TYPES) - if brace: - end_token, contents = _GetMatchingEndBraceAndContents(brace) - self.type = contents - self.jstype = typeannotation.Parse(brace, end_token, - error_handler) - self.type_start_token = brace - self.type_end_token = end_token - elif (self.flag_type in self.TYPE_ONLY and - flag_token.next.type not in Type.FLAG_ENDING_TYPES and - flag_token.line_number == flag_token.next.line_number): - # b/10407058. If the flag is expected to be followed by a type then - # search for type in same line only. If no token after flag in same - # line then conclude that no type is specified. - self.type_start_token = flag_token.next - self.type_end_token, self.type = _GetEndTokenAndContents( - self.type_start_token) - if self.type is not None: - self.type = self.type.strip() - self.jstype = typeannotation.Parse(flag_token, self.type_end_token, - error_handler) - - # Extract name, if applicable. - self.name_token = None - self.name = None - if self.flag_type in self.HAS_NAME: - # Handle bad case, name could be immediately after flag token. - self.name_token = _GetNextPartialIdentifierToken(flag_token) - - # Handle good case, if found token is after type start, look for - # a identifier (substring to cover cases like [cnt] b/4197272) after - # type end, since types contain identifiers. - if (self.type and self.name_token and - tokenutil.Compare(self.name_token, self.type_start_token) > 0): - self.name_token = _GetNextPartialIdentifierToken(self.type_end_token) - - if self.name_token: - self.name = self.name_token.string - - # Extract description, if applicable. - self.description_start_token = None - self.description_end_token = None - self.description = None - if self.flag_type in self.HAS_DESCRIPTION: - search_start_token = flag_token - if self.name_token and self.type_end_token: - if tokenutil.Compare(self.type_end_token, self.name_token) > 0: - search_start_token = self.type_end_token - else: - search_start_token = self.name_token - elif self.name_token: - search_start_token = self.name_token - elif self.type: - search_start_token = self.type_end_token - - interesting_token = tokenutil.Search(search_start_token, - Type.FLAG_DESCRIPTION_TYPES | Type.FLAG_ENDING_TYPES) - if interesting_token.type in Type.FLAG_DESCRIPTION_TYPES: - self.description_start_token = interesting_token - self.description_end_token, self.description = ( - _GetEndTokenAndContents(interesting_token)) - - def HasType(self): - """Returns whether this flag should have a type annotation.""" - return self.flag_type in self.HAS_TYPE - - def __repr__(self): - return '<Flag: %s, type:%s>' % (self.flag_type, repr(self.jstype)) - - -class DocComment(object): - """JavaScript doc comment object. - - Attributes: - ordered_params: Ordered list of parameters documented. - start_token: The token that starts the doc comment. - end_token: The token that ends the doc comment. - suppressions: Map of suppression type to the token that added it. - """ - def __init__(self, start_token): - """Create the doc comment object. - - Args: - start_token: The first token in the doc comment. - """ - self.__flags = [] - self.start_token = start_token - self.end_token = None - self.suppressions = {} - self.invalidated = False - - @property - def ordered_params(self): - """Gives the list of parameter names as a list of strings.""" - params = [] - for flag in self.__flags: - if flag.flag_type == 'param' and flag.name: - params.append(flag.name) - return params - - def Invalidate(self): - """Indicate that the JSDoc is well-formed but we had problems parsing it. - - This is a short-circuiting mechanism so that we don't emit false - positives about well-formed doc comments just because we don't support - hot new syntaxes. - """ - self.invalidated = True - - def IsInvalidated(self): - """Test whether Invalidate() has been called.""" - return self.invalidated - - def AddSuppression(self, token): - """Add a new error suppression flag. - - Args: - token: The suppression flag token. - """ - flag = token and token.attached_object - if flag and flag.jstype: - for suppression in flag.jstype.IterIdentifiers(): - self.suppressions[suppression] = token - - def SuppressionOnly(self): - """Returns whether this comment contains only suppression flags.""" - if not self.__flags: - return False - - for flag in self.__flags: - if flag.flag_type != 'suppress': - return False - - return True - - def AddFlag(self, flag): - """Add a new document flag. - - Args: - flag: DocFlag object. - """ - self.__flags.append(flag) - - def InheritsDocumentation(self): - """Test if the jsdoc implies documentation inheritance. - - Returns: - True if documentation may be pulled off the superclass. - """ - return self.HasFlag('inheritDoc') or self.HasFlag('override') - - def HasFlag(self, flag_type): - """Test if the given flag has been set. - - Args: - flag_type: The type of the flag to check. - - Returns: - True if the flag is set. - """ - for flag in self.__flags: - if flag.flag_type == flag_type: - return True - return False - - def GetFlag(self, flag_type): - """Gets the last flag of the given type. - - Args: - flag_type: The type of the flag to get. - - Returns: - The last instance of the given flag type in this doc comment. - """ - for flag in reversed(self.__flags): - if flag.flag_type == flag_type: - return flag - - def GetDocFlags(self): - """Return the doc flags for this comment.""" - return list(self.__flags) - - def _YieldDescriptionTokens(self): - for token in self.start_token: - - if (token is self.end_token or - token.type is javascripttokens.JavaScriptTokenType.DOC_FLAG or - token.type not in javascripttokens.JavaScriptTokenType.COMMENT_TYPES): - return - - if token.type not in [ - javascripttokens.JavaScriptTokenType.START_DOC_COMMENT, - javascripttokens.JavaScriptTokenType.END_DOC_COMMENT, - javascripttokens.JavaScriptTokenType.DOC_PREFIX]: - yield token - - @property - def description(self): - return tokenutil.TokensToString( - self._YieldDescriptionTokens()) - - def GetTargetIdentifier(self): - """Returns the identifier (as a string) that this is a comment for. - - Note that this uses method uses GetIdentifierForToken to get the full - identifier, even if broken up by whitespace, newlines, or comments, - and thus could be longer than GetTargetToken().string. - - Returns: - The identifier for the token this comment is for. - """ - token = self.GetTargetToken() - if token: - return tokenutil.GetIdentifierForToken(token) - - def GetTargetToken(self): - """Get this comment's target token. - - Returns: - The token that is the target of this comment, or None if there isn't one. - """ - - # File overviews describe the file, not a token. - if self.HasFlag('fileoverview'): - return - - skip_types = frozenset([ - Type.WHITESPACE, - Type.BLANK_LINE, - Type.START_PAREN]) - - target_types = frozenset([ - Type.FUNCTION_NAME, - Type.IDENTIFIER, - Type.SIMPLE_LVALUE]) - - token = self.end_token.next - while token: - if token.type in target_types: - return token - - # Handles the case of a comment on "var foo = ...' - if token.IsKeyword('var'): - next_code_token = tokenutil.CustomSearch( - token, - lambda t: t.type not in Type.NON_CODE_TYPES) - - if (next_code_token and - next_code_token.IsType(Type.SIMPLE_LVALUE)): - return next_code_token - - return - - # Handles the case of a comment on "function foo () {}" - if token.type is Type.FUNCTION_DECLARATION: - next_code_token = tokenutil.CustomSearch( - token, - lambda t: t.type not in Type.NON_CODE_TYPES) - - if next_code_token.IsType(Type.FUNCTION_NAME): - return next_code_token - - return - - # Skip types will end the search. - if token.type not in skip_types: - return - - token = token.next - - def CompareParameters(self, params): - """Computes the edit distance and list from the function params to the docs. - - Uses the Levenshtein edit distance algorithm, with code modified from - http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Levenshtein_distance#Python - - Args: - params: The parameter list for the function declaration. - - Returns: - The edit distance, the edit list. - """ - source_len, target_len = len(self.ordered_params), len(params) - edit_lists = [[]] - distance = [[]] - for i in range(target_len+1): - edit_lists[0].append(['I'] * i) - distance[0].append(i) - - for j in range(1, source_len+1): - edit_lists.append([['D'] * j]) - distance.append([j]) - - for i in range(source_len): - for j in range(target_len): - cost = 1 - if self.ordered_params[i] == params[j]: - cost = 0 - - deletion = distance[i][j+1] + 1 - insertion = distance[i+1][j] + 1 - substitution = distance[i][j] + cost - - edit_list = None - best = None - if deletion <= insertion and deletion <= substitution: - # Deletion is best. - best = deletion - edit_list = list(edit_lists[i][j+1]) - edit_list.append('D') - - elif insertion <= substitution: - # Insertion is best. - best = insertion - edit_list = list(edit_lists[i+1][j]) - edit_list.append('I') - edit_lists[i+1].append(edit_list) - - else: - # Substitution is best. - best = substitution - edit_list = list(edit_lists[i][j]) - if cost: - edit_list.append('S') - else: - edit_list.append('=') - - edit_lists[i+1].append(edit_list) - distance[i+1].append(best) - - return distance[source_len][target_len], edit_lists[source_len][target_len] - - def __repr__(self): - """Returns a string representation of this object. - - Returns: - A string representation of this object. - """ - return '<DocComment: %s, %s>' % ( - str(self.ordered_params), str(self.__flags)) - - -# -# Helper methods used by DocFlag and DocComment to parse out flag information. -# - - -def _GetMatchingEndBraceAndContents(start_brace): - """Returns the matching end brace and contents between the two braces. - - If any FLAG_ENDING_TYPE token is encountered before a matching end brace, then - that token is used as the matching ending token. Contents will have all - comment prefixes stripped out of them, and all comment prefixes in between the - start and end tokens will be split out into separate DOC_PREFIX tokens. - - Args: - start_brace: The DOC_START_BRACE token immediately before desired contents. - - Returns: - The matching ending token (DOC_END_BRACE or FLAG_ENDING_TYPE) and a string - of the contents between the matching tokens, minus any comment prefixes. - """ - open_count = 1 - close_count = 0 - contents = [] - - # We don't consider the start brace part of the type string. - token = start_brace.next - while open_count != close_count: - if token.type == Type.DOC_START_BRACE: - open_count += 1 - elif token.type == Type.DOC_END_BRACE: - close_count += 1 - - if token.type != Type.DOC_PREFIX: - contents.append(token.string) - - if token.type in Type.FLAG_ENDING_TYPES: - break - token = token.next - - #Don't include the end token (end brace, end doc comment, etc.) in type. - token = token.previous - contents = contents[:-1] - - return token, ''.join(contents) - - -def _GetNextPartialIdentifierToken(start_token): - """Returns the first token having identifier as substring after a token. - - Searches each token after the start to see if it contains an identifier. - If found, token is returned. If no identifier is found returns None. - Search is abandoned when a FLAG_ENDING_TYPE token is found. - - Args: - start_token: The token to start searching after. - - Returns: - The token found containing identifier, None otherwise. - """ - token = start_token.next - - while token and token.type not in Type.FLAG_ENDING_TYPES: - match = javascripttokenizer.JavaScriptTokenizer.IDENTIFIER.search( - token.string) - if match is not None and token.type == Type.COMMENT: - return token - - token = token.next - - return None - - -def _GetEndTokenAndContents(start_token): - """Returns last content token and all contents before FLAG_ENDING_TYPE token. - - Comment prefixes are split into DOC_PREFIX tokens and stripped from the - returned contents. - - Args: - start_token: The token immediately before the first content token. - - Returns: - The last content token and a string of all contents including start and - end tokens, with comment prefixes stripped. - """ - iterator = start_token - last_line = iterator.line_number - last_token = None - contents = '' - doc_depth = 0 - while not iterator.type in Type.FLAG_ENDING_TYPES or doc_depth > 0: - if (iterator.IsFirstInLine() and - DocFlag.EMPTY_COMMENT_LINE.match(iterator.line)): - # If we have a blank comment line, consider that an implicit - # ending of the description. This handles a case like: - # - # * @return {boolean} True - # * - # * Note: This is a sentence. - # - # The note is not part of the @return description, but there was - # no definitive ending token. Rather there was a line containing - # only a doc comment prefix or whitespace. - break - - # b/2983692 - # don't prematurely match against a @flag if inside a doc flag - # need to think about what is the correct behavior for unterminated - # inline doc flags - if (iterator.type == Type.DOC_START_BRACE and - iterator.next.type == Type.DOC_INLINE_FLAG): - doc_depth += 1 - elif (iterator.type == Type.DOC_END_BRACE and - doc_depth > 0): - doc_depth -= 1 - - if iterator.type in Type.FLAG_DESCRIPTION_TYPES: - contents += iterator.string - last_token = iterator - - iterator = iterator.next - if iterator.line_number != last_line: - contents += '\n' - last_line = iterator.line_number - - end_token = last_token - if DocFlag.EMPTY_STRING.match(contents): - contents = None - else: - # Strip trailing newline. - contents = contents[:-1] - - return end_token, contents - - -class Function(object): - """Data about a JavaScript function. - - Attributes: - block_depth: Block depth the function began at. - doc: The DocComment associated with the function. - has_return: If the function has a return value. - has_this: If the function references the 'this' object. - is_assigned: If the function is part of an assignment. - is_constructor: If the function is a constructor. - name: The name of the function, whether given in the function keyword or - as the lvalue the function is assigned to. - start_token: First token of the function (the function' keyword token). - end_token: Last token of the function (the closing '}' token). - parameters: List of parameter names. - """ - - def __init__(self, block_depth, is_assigned, doc, name): - self.block_depth = block_depth - self.is_assigned = is_assigned - self.is_constructor = doc and doc.HasFlag('constructor') - self.is_interface = doc and doc.HasFlag('interface') - self.has_return = False - self.has_throw = False - self.has_this = False - self.name = name - self.doc = doc - self.start_token = None - self.end_token = None - self.parameters = None - - -class StateTracker(object): - """EcmaScript state tracker. - - Tracks block depth, function names, etc. within an EcmaScript token stream. - """ - - OBJECT_LITERAL = 'o' - CODE = 'c' - - def __init__(self, doc_flag=DocFlag): - """Initializes a JavaScript token stream state tracker. - - Args: - doc_flag: An optional custom DocFlag used for validating - documentation flags. - """ - self._doc_flag = doc_flag - self.Reset() - - def Reset(self): - """Resets the state tracker to prepare for processing a new page.""" - self._block_depth = 0 - self._is_block_close = False - self._paren_depth = 0 - self._function_stack = [] - self._functions_by_name = {} - self._last_comment = None - self._doc_comment = None - self._cumulative_params = None - self._block_types = [] - self._last_non_space_token = None - self._last_line = None - self._first_token = None - self._documented_identifiers = set() - self._variables_in_scope = [] - - def DocFlagPass(self, start_token, error_handler): - """Parses doc flags. - - This pass needs to be executed before the aliaspass and we don't want to do - a full-blown statetracker dry run for these. - - Args: - start_token: The token at which to start iterating - error_handler: An error handler for error reporting. - """ - if not start_token: - return - doc_flag_types = (Type.DOC_FLAG, Type.DOC_INLINE_FLAG) - for token in start_token: - if token.type in doc_flag_types: - token.attached_object = self._doc_flag(token, error_handler) - - def InFunction(self): - """Returns true if the current token is within a function. - - Returns: - True if the current token is within a function. - """ - return bool(self._function_stack) - - def InConstructor(self): - """Returns true if the current token is within a constructor. - - Returns: - True if the current token is within a constructor. - """ - return self.InFunction() and self._function_stack[-1].is_constructor - - def InInterfaceMethod(self): - """Returns true if the current token is within an interface method. - - Returns: - True if the current token is within an interface method. - """ - if self.InFunction(): - if self._function_stack[-1].is_interface: - return True - else: - name = self._function_stack[-1].name - prototype_index = name.find('.prototype.') - if prototype_index != -1: - class_function_name = name[0:prototype_index] - if (class_function_name in self._functions_by_name and - self._functions_by_name[class_function_name].is_interface): - return True - - return False - - def InTopLevelFunction(self): - """Returns true if the current token is within a top level function. - - Returns: - True if the current token is within a top level function. - """ - return len(self._function_stack) == 1 and self.InTopLevel() - - def InAssignedFunction(self): - """Returns true if the current token is within a function variable. - - Returns: - True if if the current token is within a function variable - """ - return self.InFunction() and self._function_stack[-1].is_assigned - - def IsFunctionOpen(self): - """Returns true if the current token is a function block open. - - Returns: - True if the current token is a function block open. - """ - return (self._function_stack and - self._function_stack[-1].block_depth == self._block_depth - 1) - - def IsFunctionClose(self): - """Returns true if the current token is a function block close. - - Returns: - True if the current token is a function block close. - """ - return (self._function_stack and - self._function_stack[-1].block_depth == self._block_depth) - - def InBlock(self): - """Returns true if the current token is within a block. - - Returns: - True if the current token is within a block. - """ - return bool(self._block_depth) - - def IsBlockClose(self): - """Returns true if the current token is a block close. - - Returns: - True if the current token is a block close. - """ - return self._is_block_close - - def InObjectLiteral(self): - """Returns true if the current token is within an object literal. - - Returns: - True if the current token is within an object literal. - """ - return self._block_depth and self._block_types[-1] == self.OBJECT_LITERAL - - def InObjectLiteralDescendant(self): - """Returns true if the current token has an object literal ancestor. - - Returns: - True if the current token has an object literal ancestor. - """ - return self.OBJECT_LITERAL in self._block_types - - def InParentheses(self): - """Returns true if the current token is within parentheses. - - Returns: - True if the current token is within parentheses. - """ - return bool(self._paren_depth) - - def ParenthesesDepth(self): - """Returns the number of parens surrounding the token. - - Returns: - The number of parenthesis surrounding the token. - """ - return self._paren_depth - - def BlockDepth(self): - """Returns the number of blocks in which the token is nested. - - Returns: - The number of blocks in which the token is nested. - """ - return self._block_depth - - def FunctionDepth(self): - """Returns the number of functions in which the token is nested. - - Returns: - The number of functions in which the token is nested. - """ - return len(self._function_stack) - - def InTopLevel(self): - """Whether we are at the top level in the class. - - This function call is language specific. In some languages like - JavaScript, a function is top level if it is not inside any parenthesis. - In languages such as ActionScript, a function is top level if it is directly - within a class. - """ - raise TypeError('Abstract method InTopLevel not implemented') - - def GetBlockType(self, token): - """Determine the block type given a START_BLOCK token. - - Code blocks come after parameters, keywords like else, and closing parens. - - Args: - token: The current token. Can be assumed to be type START_BLOCK. - Returns: - Code block type for current token. - """ - raise TypeError('Abstract method GetBlockType not implemented') - - def GetParams(self): - """Returns the accumulated input params as an array. - - In some EcmasSript languages, input params are specified like - (param:Type, param2:Type2, ...) - in other they are specified just as - (param, param2) - We handle both formats for specifying parameters here and leave - it to the compilers for each language to detect compile errors. - This allows more code to be reused between lint checkers for various - EcmaScript languages. - - Returns: - The accumulated input params as an array. - """ - params = [] - if self._cumulative_params: - params = re.compile(r'\s+').sub('', self._cumulative_params).split(',') - # Strip out the type from parameters of the form name:Type. - params = map(lambda param: param.split(':')[0], params) - - return params - - def GetLastComment(self): - """Return the last plain comment that could be used as documentation. - - Returns: - The last plain comment that could be used as documentation. - """ - return self._last_comment - - def GetDocComment(self): - """Return the most recent applicable documentation comment. - - Returns: - The last applicable documentation comment. - """ - return self._doc_comment - - def HasDocComment(self, identifier): - """Returns whether the identifier has been documented yet. - - Args: - identifier: The identifier. - - Returns: - Whether the identifier has been documented yet. - """ - return identifier in self._documented_identifiers - - def InDocComment(self): - """Returns whether the current token is in a doc comment. - - Returns: - Whether the current token is in a doc comment. - """ - return self._doc_comment and self._doc_comment.end_token is None - - def GetDocFlag(self): - """Returns the current documentation flags. - - Returns: - The current documentation flags. - """ - return self._doc_flag - - def IsTypeToken(self, t): - if self.InDocComment() and t.type not in (Type.START_DOC_COMMENT, - Type.DOC_FLAG, Type.DOC_INLINE_FLAG, Type.DOC_PREFIX): - f = tokenutil.SearchUntil(t, [Type.DOC_FLAG], [Type.START_DOC_COMMENT], - None, True) - if (f and f.attached_object.type_start_token is not None and - f.attached_object.type_end_token is not None): - return (tokenutil.Compare(t, f.attached_object.type_start_token) > 0 and - tokenutil.Compare(t, f.attached_object.type_end_token) < 0) - return False - - def GetFunction(self): - """Return the function the current code block is a part of. - - Returns: - The current Function object. - """ - if self._function_stack: - return self._function_stack[-1] - - def GetBlockDepth(self): - """Return the block depth. - - Returns: - The current block depth. - """ - return self._block_depth - - def GetLastNonSpaceToken(self): - """Return the last non whitespace token.""" - return self._last_non_space_token - - def GetLastLine(self): - """Return the last line.""" - return self._last_line - - def GetFirstToken(self): - """Return the very first token in the file.""" - return self._first_token - - def IsVariableInScope(self, token_string): - """Checks if string is variable in current scope. - - For given string it checks whether the string is a defined variable - (including function param) in current state. - - E.g. if variables defined (variables in current scope) is docs - then docs, docs.length etc will be considered as variable in current - scope. This will help in avoding extra goog.require for variables. - - Args: - token_string: String to check if its is a variable in current scope. - - Returns: - true if given string is a variable in current scope. - """ - for variable in self._variables_in_scope: - if (token_string == variable - or token_string.startswith(variable + '.')): - return True - - return False - - def HandleToken(self, token, last_non_space_token): - """Handles the given token and updates state. - - Args: - token: The token to handle. - last_non_space_token: - """ - self._is_block_close = False - - if not self._first_token: - self._first_token = token - - # Track block depth. - type = token.type - if type == Type.START_BLOCK: - self._block_depth += 1 - - # Subclasses need to handle block start very differently because - # whether a block is a CODE or OBJECT_LITERAL block varies significantly - # by language. - self._block_types.append(self.GetBlockType(token)) - - # When entering a function body, record its parameters. - if self.InFunction(): - function = self._function_stack[-1] - if self._block_depth == function.block_depth + 1: - function.parameters = self.GetParams() - - # Track block depth. - elif type == Type.END_BLOCK: - self._is_block_close = not self.InObjectLiteral() - self._block_depth -= 1 - self._block_types.pop() - - # Track parentheses depth. - elif type == Type.START_PAREN: - self._paren_depth += 1 - - # Track parentheses depth. - elif type == Type.END_PAREN: - self._paren_depth -= 1 - - elif type == Type.COMMENT: - self._last_comment = token.string - - elif type == Type.START_DOC_COMMENT: - self._last_comment = None - self._doc_comment = DocComment(token) - - elif type == Type.END_DOC_COMMENT: - self._doc_comment.end_token = token - - elif type in (Type.DOC_FLAG, Type.DOC_INLINE_FLAG): - # Don't overwrite flags if they were already parsed in a previous pass. - if token.attached_object is None: - flag = self._doc_flag(token) - token.attached_object = flag - else: - flag = token.attached_object - self._doc_comment.AddFlag(flag) - - if flag.flag_type == 'suppress': - self._doc_comment.AddSuppression(token) - - elif type == Type.FUNCTION_DECLARATION: - last_code = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES, None, - True) - doc = None - # Only top-level functions are eligible for documentation. - if self.InTopLevel(): - doc = self._doc_comment - - name = '' - is_assigned = last_code and (last_code.IsOperator('=') or - last_code.IsOperator('||') or last_code.IsOperator('&&') or - (last_code.IsOperator(':') and not self.InObjectLiteral())) - if is_assigned: - # TODO(robbyw): This breaks for x[2] = ... - # Must use loop to find full function name in the case of line-wrapped - # declarations (bug 1220601) like: - # my.function.foo. - # bar = function() ... - identifier = tokenutil.Search(last_code, Type.SIMPLE_LVALUE, None, True) - while identifier and tokenutil.IsIdentifierOrDot(identifier): - name = identifier.string + name - # Traverse behind us, skipping whitespace and comments. - while True: - identifier = identifier.previous - if not identifier or not identifier.type in Type.NON_CODE_TYPES: - break - - else: - next_token = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES) - while next_token and next_token.IsType(Type.FUNCTION_NAME): - name += next_token.string - next_token = tokenutil.Search(next_token, Type.FUNCTION_NAME, 2) - - function = Function(self._block_depth, is_assigned, doc, name) - function.start_token = token - - self._function_stack.append(function) - self._functions_by_name[name] = function - - # Add a delimiter in stack for scope variables to define start of - # function. This helps in popping variables of this function when - # function declaration ends. - self._variables_in_scope.append('') - - elif type == Type.START_PARAMETERS: - self._cumulative_params = '' - - elif type == Type.PARAMETERS: - self._cumulative_params += token.string - self._variables_in_scope.extend(self.GetParams()) - - elif type == Type.KEYWORD and token.string == 'return': - next_token = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES) - if not next_token.IsType(Type.SEMICOLON): - function = self.GetFunction() - if function: - function.has_return = True - - elif type == Type.KEYWORD and token.string == 'throw': - function = self.GetFunction() - if function: - function.has_throw = True - - elif type == Type.KEYWORD and token.string == 'var': - function = self.GetFunction() - next_token = tokenutil.Search(token, [Type.IDENTIFIER, - Type.SIMPLE_LVALUE]) - - if next_token: - if next_token.type == Type.SIMPLE_LVALUE: - self._variables_in_scope.append(next_token.values['identifier']) - else: - self._variables_in_scope.append(next_token.string) - - elif type == Type.SIMPLE_LVALUE: - identifier = token.values['identifier'] - jsdoc = self.GetDocComment() - if jsdoc: - self._documented_identifiers.add(identifier) - - self._HandleIdentifier(identifier, True) - - elif type == Type.IDENTIFIER: - self._HandleIdentifier(token.string, False) - - # Detect documented non-assignments. - next_token = tokenutil.SearchExcept(token, Type.NON_CODE_TYPES) - if next_token and next_token.IsType(Type.SEMICOLON): - if (self._last_non_space_token and - self._last_non_space_token.IsType(Type.END_DOC_COMMENT)): - self._documented_identifiers.add(token.string) - - def _HandleIdentifier(self, identifier, is_assignment): - """Process the given identifier. - - Currently checks if it references 'this' and annotates the function - accordingly. - - Args: - identifier: The identifer to process. - is_assignment: Whether the identifer is being written to. - """ - if identifier == 'this' or identifier.startswith('this.'): - function = self.GetFunction() - if function: - function.has_this = True - - def HandleAfterToken(self, token): - """Handle updating state after a token has been checked. - - This function should be used for destructive state changes such as - deleting a tracked object. - - Args: - token: The token to handle. - """ - type = token.type - if type == Type.SEMICOLON or type == Type.END_PAREN or ( - type == Type.END_BRACKET and - self._last_non_space_token.type not in ( - Type.SINGLE_QUOTE_STRING_END, Type.DOUBLE_QUOTE_STRING_END, - Type.TEMPLATE_STRING_END)): - # We end on any numeric array index, but keep going for string based - # array indices so that we pick up manually exported identifiers. - self._doc_comment = None - self._last_comment = None - - elif type == Type.END_BLOCK: - self._doc_comment = None - self._last_comment = None - - if self.InFunction() and self.IsFunctionClose(): - # TODO(robbyw): Detect the function's name for better errors. - function = self._function_stack.pop() - function.end_token = token - - # Pop all variables till delimiter ('') those were defined in the - # function being closed so make them out of scope. - while self._variables_in_scope and self._variables_in_scope[-1]: - self._variables_in_scope.pop() - - # Pop delimiter - if self._variables_in_scope: - self._variables_in_scope.pop() - - elif type == Type.END_PARAMETERS and self._doc_comment: - self._doc_comment = None - self._last_comment = None - - if not token.IsAnyType(Type.WHITESPACE, Type.BLANK_LINE): - self._last_non_space_token = token - - self._last_line = token.line
diff --git a/third_party/closure_linter/closure_linter/statetracker_test.py b/third_party/closure_linter/closure_linter/statetracker_test.py deleted file mode 100644 index 494dc642..0000000 --- a/third_party/closure_linter/closure_linter/statetracker_test.py +++ /dev/null
@@ -1,123 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Unit tests for the statetracker module.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = ('nnaze@google.com (Nathan Naze)') - - - -import unittest as googletest - -from closure_linter import javascripttokens -from closure_linter import statetracker -from closure_linter import testutil - - -class _FakeDocFlag(object): - - def __repr__(self): - return '@%s %s' % (self.flag_type, self.name) - - -class IdentifierTest(googletest.TestCase): - - def testJustIdentifier(self): - a = javascripttokens.JavaScriptToken( - 'abc', javascripttokens.JavaScriptTokenType.IDENTIFIER, 'abc', 1) - - st = statetracker.StateTracker() - st.HandleToken(a, None) - - -class DocCommentTest(googletest.TestCase): - - @staticmethod - def _MakeDocFlagFake(flag_type, name=None): - flag = _FakeDocFlag() - flag.flag_type = flag_type - flag.name = name - return flag - - def testDocFlags(self): - comment = statetracker.DocComment(None) - - a = self._MakeDocFlagFake('param', 'foo') - comment.AddFlag(a) - - b = self._MakeDocFlagFake('param', '') - comment.AddFlag(b) - - c = self._MakeDocFlagFake('param', 'bar') - comment.AddFlag(c) - - self.assertEquals( - ['foo', 'bar'], - comment.ordered_params) - - self.assertEquals( - [a, b, c], - comment.GetDocFlags()) - - def testInvalidate(self): - comment = statetracker.DocComment(None) - - self.assertFalse(comment.invalidated) - self.assertFalse(comment.IsInvalidated()) - - comment.Invalidate() - - self.assertTrue(comment.invalidated) - self.assertTrue(comment.IsInvalidated()) - - def testSuppressionOnly(self): - comment = statetracker.DocComment(None) - - self.assertFalse(comment.SuppressionOnly()) - comment.AddFlag(self._MakeDocFlagFake('suppress')) - self.assertTrue(comment.SuppressionOnly()) - comment.AddFlag(self._MakeDocFlagFake('foo')) - self.assertFalse(comment.SuppressionOnly()) - - def testRepr(self): - comment = statetracker.DocComment(None) - comment.AddFlag(self._MakeDocFlagFake('param', 'foo')) - comment.AddFlag(self._MakeDocFlagFake('param', 'bar')) - - self.assertEquals( - '<DocComment: [\'foo\', \'bar\'], [@param foo, @param bar]>', - repr(comment)) - - def testDocFlagParam(self): - comment = self._ParseComment(""" - /** - * @param {string} [name] Name of customer. - */""") - flag = comment.GetFlag('param') - self.assertEquals('string', flag.type) - self.assertEquals('string', flag.jstype.ToString()) - self.assertEquals('[name]', flag.name) - - def _ParseComment(self, script): - """Parse a script that contains one comment and return it.""" - _, comments = testutil.ParseFunctionsAndComments(script) - self.assertEquals(1, len(comments)) - return comments[0] - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/strict_test.py b/third_party/closure_linter/closure_linter/strict_test.py deleted file mode 100644 index 75044e8..0000000 --- a/third_party/closure_linter/closure_linter/strict_test.py +++ /dev/null
@@ -1,68 +0,0 @@ -#!/usr/bin/env python -# Copyright 2013 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Tests for gjslint --strict. - -Tests errors that can be thrown by gjslint when in strict mode. -""" - - - -import unittest - -import gflags as flags -import unittest as googletest - -from closure_linter import errors -from closure_linter import runner -from closure_linter.common import erroraccumulator - -flags.FLAGS.strict = True - - -class StrictTest(unittest.TestCase): - """Tests scenarios where strict generates warnings.""" - - def testUnclosedString(self): - """Tests warnings are reported when nothing is disabled. - - b/11450054. - """ - original = [ - 'bug = function() {', - ' (\'foo\'\');', - '};', - '', - ] - - expected = [errors.FILE_DOES_NOT_PARSE, errors.MULTI_LINE_STRING, - errors.FILE_IN_BLOCK] - self._AssertErrors(original, expected) - - def _AssertErrors(self, original, expected_errors): - """Asserts that the error fixer corrects original to expected.""" - - # Trap gjslint's output parse it to get messages added. - error_accumulator = erroraccumulator.ErrorAccumulator() - runner.Run('testing.js', error_accumulator, source=original) - error_nums = [e.code for e in error_accumulator.GetErrors()] - - error_nums.sort() - expected_errors.sort() - self.assertListEqual(error_nums, expected_errors) - -if __name__ == '__main__': - googletest.main() -
diff --git a/third_party/closure_linter/closure_linter/testutil.py b/third_party/closure_linter/closure_linter/testutil.py deleted file mode 100644 index f7084ee..0000000 --- a/third_party/closure_linter/closure_linter/testutil.py +++ /dev/null
@@ -1,94 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Utility functions for testing gjslint components.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = ('nnaze@google.com (Nathan Naze)') - -import StringIO - -from closure_linter import ecmametadatapass -from closure_linter import javascriptstatetracker -from closure_linter import javascripttokenizer - - -def TokenizeSource(source): - """Convert a source into a string of tokens. - - Args: - source: A source file as a string or file-like object (iterates lines). - - Returns: - The first token of the resulting token stream. - """ - - if isinstance(source, basestring): - source = StringIO.StringIO(source) - - tokenizer = javascripttokenizer.JavaScriptTokenizer() - return tokenizer.TokenizeFile(source) - - -def TokenizeSourceAndRunEcmaPass(source): - """Tokenize a source and run the EcmaMetaDataPass on it. - - Args: - source: A source file as a string or file-like object (iterates lines). - - Returns: - The first token of the resulting token stream. - """ - start_token = TokenizeSource(source) - ecma_pass = ecmametadatapass.EcmaMetaDataPass() - ecma_pass.Process(start_token) - return start_token - - -def ParseFunctionsAndComments(source, error_handler=None): - """Run the tokenizer and tracker and return comments and functions found. - - Args: - source: A source file as a string or file-like object (iterates lines). - error_handler: An error handler. - - Returns: - The functions and comments as a tuple. - """ - start_token = TokenizeSourceAndRunEcmaPass(source) - - tracker = javascriptstatetracker.JavaScriptStateTracker() - if error_handler is not None: - tracker.DocFlagPass(start_token, error_handler) - - functions = [] - comments = [] - for token in start_token: - tracker.HandleToken(token, tracker.GetLastNonSpaceToken()) - - function = tracker.GetFunction() - if function and function not in functions: - functions.append(function) - - comment = tracker.GetDocComment() - if comment and comment not in comments: - comments.append(comment) - - tracker.HandleAfterToken(token) - - return functions, comments
diff --git a/third_party/closure_linter/closure_linter/tokenutil.py b/third_party/closure_linter/closure_linter/tokenutil.py deleted file mode 100755 index dedf5aa..0000000 --- a/third_party/closure_linter/closure_linter/tokenutil.py +++ /dev/null
@@ -1,698 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2007 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -"""Token utility functions.""" - -__author__ = ('robbyw@google.com (Robert Walker)', - 'ajp@google.com (Andy Perelson)') - -import copy -import StringIO - -from closure_linter.common import tokens -from closure_linter.javascripttokens import JavaScriptToken -from closure_linter.javascripttokens import JavaScriptTokenType - -# Shorthand -Type = tokens.TokenType - - -def GetFirstTokenInSameLine(token): - """Returns the first token in the same line as token. - - Args: - token: Any token in the line. - - Returns: - The first token in the same line as token. - """ - while not token.IsFirstInLine(): - token = token.previous - return token - - -def GetFirstTokenInPreviousLine(token): - """Returns the first token in the previous line as token. - - Args: - token: Any token in the line. - - Returns: - The first token in the previous line as token, or None if token is on the - first line. - """ - first_in_line = GetFirstTokenInSameLine(token) - if first_in_line.previous: - return GetFirstTokenInSameLine(first_in_line.previous) - - return None - - -def GetLastTokenInSameLine(token): - """Returns the last token in the same line as token. - - Args: - token: Any token in the line. - - Returns: - The last token in the same line as token. - """ - while not token.IsLastInLine(): - token = token.next - return token - - -def GetAllTokensInSameLine(token): - """Returns all tokens in the same line as the given token. - - Args: - token: Any token in the line. - - Returns: - All tokens on the same line as the given token. - """ - first_token = GetFirstTokenInSameLine(token) - last_token = GetLastTokenInSameLine(token) - - tokens_in_line = [] - while first_token != last_token: - tokens_in_line.append(first_token) - first_token = first_token.next - tokens_in_line.append(last_token) - - return tokens_in_line - - -def CustomSearch(start_token, func, end_func=None, distance=None, - reverse=False): - """Returns the first token where func is True within distance of this token. - - Args: - start_token: The token to start searching from - func: The function to call to test a token for applicability - end_func: The function to call to test a token to determine whether to abort - the search. - distance: The number of tokens to look through before failing search. Must - be positive. If unspecified, will search until the end of the token - chain - reverse: When true, search the tokens before this one instead of the tokens - after it - - Returns: - The first token matching func within distance of this token, or None if no - such token is found. - """ - token = start_token - if reverse: - while token and (distance is None or distance > 0): - previous = token.previous - if previous: - if func(previous): - return previous - if end_func and end_func(previous): - return None - - token = previous - if distance is not None: - distance -= 1 - - else: - while token and (distance is None or distance > 0): - next_token = token.next - if next_token: - if func(next_token): - return next_token - if end_func and end_func(next_token): - return None - - token = next_token - if distance is not None: - distance -= 1 - - return None - - -def Search(start_token, token_types, distance=None, reverse=False): - """Returns the first token of type in token_types within distance. - - Args: - start_token: The token to start searching from - token_types: The allowable types of the token being searched for - distance: The number of tokens to look through before failing search. Must - be positive. If unspecified, will search until the end of the token - chain - reverse: When true, search the tokens before this one instead of the tokens - after it - - Returns: - The first token of any type in token_types within distance of this token, or - None if no such token is found. - """ - return CustomSearch(start_token, lambda token: token.IsAnyType(token_types), - None, distance, reverse) - - -def SearchExcept(start_token, token_types, distance=None, reverse=False): - """Returns the first token not of any type in token_types within distance. - - Args: - start_token: The token to start searching from - token_types: The unallowable types of the token being searched for - distance: The number of tokens to look through before failing search. Must - be positive. If unspecified, will search until the end of the token - chain - reverse: When true, search the tokens before this one instead of the tokens - after it - - Returns: - The first token of any type in token_types within distance of this token, or - None if no such token is found. - """ - return CustomSearch(start_token, - lambda token: not token.IsAnyType(token_types), - None, distance, reverse) - - -def SearchUntil(start_token, token_types, end_types, distance=None, - reverse=False): - """Returns the first token of type in token_types before a token of end_type. - - Args: - start_token: The token to start searching from. - token_types: The allowable types of the token being searched for. - end_types: Types of tokens to abort search if we find. - distance: The number of tokens to look through before failing search. Must - be positive. If unspecified, will search until the end of the token - chain - reverse: When true, search the tokens before this one instead of the tokens - after it - - Returns: - The first token of any type in token_types within distance of this token - before any tokens of type in end_type, or None if no such token is found. - """ - return CustomSearch(start_token, lambda token: token.IsAnyType(token_types), - lambda token: token.IsAnyType(end_types), - distance, reverse) - - -def DeleteToken(token): - """Deletes the given token from the linked list. - - Args: - token: The token to delete - """ - # When deleting a token, we do not update the deleted token itself to make - # sure the previous and next pointers are still pointing to tokens which are - # not deleted. Also it is very hard to keep track of all previously deleted - # tokens to update them when their pointers become invalid. So we add this - # flag that any token linked list iteration logic can skip deleted node safely - # when its current token is deleted. - token.is_deleted = True - if token.previous: - token.previous.next = token.next - - if token.next: - token.next.previous = token.previous - - following_token = token.next - while following_token and following_token.metadata.last_code == token: - following_token.metadata.last_code = token.metadata.last_code - following_token = following_token.next - - -def DeleteTokens(token, token_count): - """Deletes the given number of tokens starting with the given token. - - Args: - token: The token to start deleting at. - token_count: The total number of tokens to delete. - """ - for i in xrange(1, token_count): - DeleteToken(token.next) - DeleteToken(token) - - -def InsertTokenBefore(new_token, token): - """Insert new_token before token. - - Args: - new_token: A token to be added to the stream - token: A token already in the stream - """ - new_token.next = token - new_token.previous = token.previous - - new_token.metadata = copy.copy(token.metadata) - - if new_token.IsCode(): - old_last_code = token.metadata.last_code - following_token = token - while (following_token and - following_token.metadata.last_code == old_last_code): - following_token.metadata.last_code = new_token - following_token = following_token.next - - token.previous = new_token - if new_token.previous: - new_token.previous.next = new_token - - if new_token.start_index is None: - if new_token.line_number == token.line_number: - new_token.start_index = token.start_index - else: - previous_token = new_token.previous - if previous_token: - new_token.start_index = (previous_token.start_index + - len(previous_token.string)) - else: - new_token.start_index = 0 - - iterator = new_token.next - while iterator and iterator.line_number == new_token.line_number: - iterator.start_index += len(new_token.string) - iterator = iterator.next - - -def InsertTokenAfter(new_token, token): - """Insert new_token after token. - - Args: - new_token: A token to be added to the stream - token: A token already in the stream - """ - new_token.previous = token - new_token.next = token.next - - new_token.metadata = copy.copy(token.metadata) - - if token.IsCode(): - new_token.metadata.last_code = token - - if new_token.IsCode(): - following_token = token.next - while following_token and following_token.metadata.last_code == token: - following_token.metadata.last_code = new_token - following_token = following_token.next - - token.next = new_token - if new_token.next: - new_token.next.previous = new_token - - if new_token.start_index is None: - if new_token.line_number == token.line_number: - new_token.start_index = token.start_index + len(token.string) - else: - new_token.start_index = 0 - - iterator = new_token.next - while iterator and iterator.line_number == new_token.line_number: - iterator.start_index += len(new_token.string) - iterator = iterator.next - - -def InsertTokensAfter(new_tokens, token): - """Insert multiple tokens after token. - - Args: - new_tokens: An array of tokens to be added to the stream - token: A token already in the stream - """ - # TODO(user): It would be nicer to have InsertTokenAfter defer to here - # instead of vice-versa. - current_token = token - for new_token in new_tokens: - InsertTokenAfter(new_token, current_token) - current_token = new_token - - -def InsertSpaceTokenAfter(token): - """Inserts a space token after the given token. - - Args: - token: The token to insert a space token after - - Returns: - A single space token - """ - space_token = JavaScriptToken(' ', Type.WHITESPACE, token.line, - token.line_number) - InsertTokenAfter(space_token, token) - - -def InsertBlankLineAfter(token): - """Inserts a blank line after the given token. - - Args: - token: The token to insert a blank line after - - Returns: - A single space token - """ - blank_token = JavaScriptToken('', Type.BLANK_LINE, '', - token.line_number + 1) - InsertLineAfter(token, [blank_token]) - - -def InsertLineAfter(token, new_tokens): - """Inserts a new line consisting of new_tokens after the given token. - - Args: - token: The token to insert after. - new_tokens: The tokens that will make up the new line. - """ - insert_location = token - for new_token in new_tokens: - InsertTokenAfter(new_token, insert_location) - insert_location = new_token - - # Update all subsequent line numbers. - next_token = new_tokens[-1].next - while next_token: - next_token.line_number += 1 - next_token = next_token.next - - -def SplitToken(token, position): - """Splits the token into two tokens at position. - - Args: - token: The token to split - position: The position to split at. Will be the beginning of second token. - - Returns: - The new second token. - """ - new_string = token.string[position:] - token.string = token.string[:position] - - new_token = JavaScriptToken(new_string, token.type, token.line, - token.line_number) - InsertTokenAfter(new_token, token) - - return new_token - - -def Compare(token1, token2): - """Compares two tokens and determines their relative order. - - Args: - token1: The first token to compare. - token2: The second token to compare. - - Returns: - A negative integer, zero, or a positive integer as the first token is - before, equal, or after the second in the token stream. - """ - if token2.line_number != token1.line_number: - return token1.line_number - token2.line_number - else: - return token1.start_index - token2.start_index - - -def GoogScopeOrNoneFromStartBlock(token): - """Determines if the given START_BLOCK is part of a goog.scope statement. - - Args: - token: A token of type START_BLOCK. - - Returns: - The goog.scope function call token, or None if such call doesn't exist. - """ - if token.type != JavaScriptTokenType.START_BLOCK: - return None - - # Search for a goog.scope statement, which will be 5 tokens before the - # block. Illustration of the tokens found prior to the start block: - # goog.scope(function() { - # 5 4 3 21 ^ - - maybe_goog_scope = token - for unused_i in xrange(5): - maybe_goog_scope = (maybe_goog_scope.previous if maybe_goog_scope and - maybe_goog_scope.previous else None) - if maybe_goog_scope and maybe_goog_scope.string == 'goog.scope': - return maybe_goog_scope - - -def GetTokenRange(start_token, end_token): - """Returns a list of tokens between the two given, inclusive. - - Args: - start_token: Start token in the range. - end_token: End token in the range. - - Returns: - A list of tokens, in order, from start_token to end_token (including start - and end). Returns none if the tokens do not describe a valid range. - """ - - token_range = [] - token = start_token - - while token: - token_range.append(token) - - if token == end_token: - return token_range - - token = token.next - - -def TokensToString(token_iterable): - """Convert a number of tokens into a string. - - Newlines will be inserted whenever the line_number of two neighboring - strings differ. - - Args: - token_iterable: The tokens to turn to a string. - - Returns: - A string representation of the given tokens. - """ - - buf = StringIO.StringIO() - token_list = list(token_iterable) - if not token_list: - return '' - - line_number = token_list[0].line_number - - for token in token_list: - - while line_number < token.line_number: - line_number += 1 - buf.write('\n') - - if line_number > token.line_number: - line_number = token.line_number - buf.write('\n') - - buf.write(token.string) - - return buf.getvalue() - - -def GetPreviousCodeToken(token): - """Returns the code token before the specified token. - - Args: - token: A token. - - Returns: - The code token before the specified token or None if no such token - exists. - """ - - return CustomSearch( - token, - lambda t: t and t.type not in JavaScriptTokenType.NON_CODE_TYPES, - reverse=True) - - -def GetNextCodeToken(token): - """Returns the next code token after the specified token. - - Args: - token: A token. - - Returns: - The next code token after the specified token or None if no such token - exists. - """ - - return CustomSearch( - token, - lambda t: t and t.type not in JavaScriptTokenType.NON_CODE_TYPES, - reverse=False) - - -def GetIdentifierStart(token): - """Returns the first token in an identifier. - - Given a token which is part of an identifier, returns the token at the start - of the identifier. - - Args: - token: A token which is part of an identifier. - - Returns: - The token at the start of the identifier or None if the identifier was not - of the form 'a.b.c' (e.g. "['a']['b'].c"). - """ - - start_token = token - previous_code_token = GetPreviousCodeToken(token) - - while (previous_code_token and ( - previous_code_token.IsType(JavaScriptTokenType.IDENTIFIER) or - IsDot(previous_code_token))): - start_token = previous_code_token - previous_code_token = GetPreviousCodeToken(previous_code_token) - - if IsDot(start_token): - return None - - return start_token - - -def GetIdentifierForToken(token): - """Get the symbol specified by a token. - - Given a token, this function additionally concatenates any parts of an - identifying symbol being identified that are split by whitespace or a - newline. - - The function will return None if the token is not the first token of an - identifier. - - Args: - token: The first token of a symbol. - - Returns: - The whole symbol, as a string. - """ - - # Search backward to determine if this token is the first token of the - # identifier. If it is not the first token, return None to signal that this - # token should be ignored. - prev_token = token.previous - while prev_token: - if (prev_token.IsType(JavaScriptTokenType.IDENTIFIER) or - IsDot(prev_token)): - return None - - if (prev_token.IsType(tokens.TokenType.WHITESPACE) or - prev_token.IsAnyType(JavaScriptTokenType.COMMENT_TYPES)): - prev_token = prev_token.previous - else: - break - - # A "function foo()" declaration. - if token.type is JavaScriptTokenType.FUNCTION_NAME: - return token.string - - # A "var foo" declaration (if the previous token is 'var') - previous_code_token = GetPreviousCodeToken(token) - - if previous_code_token and previous_code_token.IsKeyword('var'): - return token.string - - # Otherwise, this is potentially a namespaced (goog.foo.bar) identifier that - # could span multiple lines or be broken up by whitespace. We need - # to concatenate. - identifier_types = set([ - JavaScriptTokenType.IDENTIFIER, - JavaScriptTokenType.SIMPLE_LVALUE - ]) - - assert token.type in identifier_types - - # Start with the first token - symbol_tokens = [token] - - if token.next: - for t in token.next: - last_symbol_token = symbol_tokens[-1] - - # A dot is part of the previous symbol. - if IsDot(t): - symbol_tokens.append(t) - continue - - # An identifier is part of the previous symbol if the previous one was a - # dot. - if t.type in identifier_types: - if IsDot(last_symbol_token): - symbol_tokens.append(t) - continue - else: - break - - # Skip any whitespace - if t.type in JavaScriptTokenType.NON_CODE_TYPES: - continue - - # This is the end of the identifier. Stop iterating. - break - - if symbol_tokens: - return ''.join([t.string for t in symbol_tokens]) - - -def GetStringAfterToken(token): - """Get string after token. - - Args: - token: Search will be done after this token. - - Returns: - String if found after token else None (empty string will also - return None). - - Search until end of string as in case of empty string Type.STRING_TEXT is not - present/found and don't want to return next string. - E.g. - a = ''; - b = 'test'; - When searching for string after 'a' if search is not limited by end of string - then it will return 'test' which is not desirable as there is a empty string - before that. - - This will return None for cases where string is empty or no string found - as in both cases there is no Type.STRING_TEXT. - """ - string_token = SearchUntil(token, JavaScriptTokenType.STRING_TEXT, - [JavaScriptTokenType.SINGLE_QUOTE_STRING_END, - JavaScriptTokenType.DOUBLE_QUOTE_STRING_END, - JavaScriptTokenType.TEMPLATE_STRING_END]) - if string_token: - return string_token.string - else: - return None - - -def IsDot(token): - """Whether the token represents a "dot" operator (foo.bar).""" - return token.type is JavaScriptTokenType.OPERATOR and token.string == '.' - - -def IsIdentifierOrDot(token): - """Whether the token is either an identifier or a '.'.""" - return (token.type in [JavaScriptTokenType.IDENTIFIER, - JavaScriptTokenType.SIMPLE_LVALUE] or - IsDot(token))
diff --git a/third_party/closure_linter/closure_linter/tokenutil_test.py b/third_party/closure_linter/closure_linter/tokenutil_test.py deleted file mode 100644 index c7d3854..0000000 --- a/third_party/closure_linter/closure_linter/tokenutil_test.py +++ /dev/null
@@ -1,297 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2012 The Closure Linter Authors. All Rights Reserved. -# 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. - -"""Unit tests for the scopeutil module.""" - -# Allow non-Google copyright -# pylint: disable=g-bad-file-header - -__author__ = ('nnaze@google.com (Nathan Naze)') - -import unittest as googletest - -from closure_linter import ecmametadatapass -from closure_linter import javascripttokens -from closure_linter import testutil -from closure_linter import tokenutil - - -class FakeToken(object): - pass - - -class TokenUtilTest(googletest.TestCase): - - def testGetTokenRange(self): - - a = FakeToken() - b = FakeToken() - c = FakeToken() - d = FakeToken() - e = FakeToken() - - a.next = b - b.next = c - c.next = d - - self.assertEquals([a, b, c, d], tokenutil.GetTokenRange(a, d)) - - # This is an error as e does not come after a in the token chain. - self.assertRaises(Exception, lambda: tokenutil.GetTokenRange(a, e)) - - def testTokensToString(self): - - a = FakeToken() - b = FakeToken() - c = FakeToken() - d = FakeToken() - e = FakeToken() - - a.string = 'aaa' - b.string = 'bbb' - c.string = 'ccc' - d.string = 'ddd' - e.string = 'eee' - - a.line_number = 5 - b.line_number = 6 - c.line_number = 6 - d.line_number = 10 - e.line_number = 11 - - self.assertEquals( - 'aaa\nbbbccc\n\n\n\nddd\neee', - tokenutil.TokensToString([a, b, c, d, e])) - - self.assertEquals( - 'ddd\neee\naaa\nbbbccc', - tokenutil.TokensToString([d, e, a, b, c]), - 'Neighboring tokens not in line_number order should have a newline ' - 'between them.') - - def testGetPreviousCodeToken(self): - - tokens = testutil.TokenizeSource(""" -start1. // comment - /* another comment */ - end1 -""") - - def _GetTokenStartingWith(token_starts_with): - for t in tokens: - if t.string.startswith(token_starts_with): - return t - - self.assertEquals( - None, - tokenutil.GetPreviousCodeToken(_GetTokenStartingWith('start1'))) - - self.assertEquals( - '.', - tokenutil.GetPreviousCodeToken(_GetTokenStartingWith('end1')).string) - - self.assertEquals( - 'start1', - tokenutil.GetPreviousCodeToken(_GetTokenStartingWith('.')).string) - - def testGetNextCodeToken(self): - - tokens = testutil.TokenizeSource(""" -start1. // comment - /* another comment */ - end1 -""") - - def _GetTokenStartingWith(token_starts_with): - for t in tokens: - if t.string.startswith(token_starts_with): - return t - - self.assertEquals( - '.', - tokenutil.GetNextCodeToken(_GetTokenStartingWith('start1')).string) - - self.assertEquals( - 'end1', - tokenutil.GetNextCodeToken(_GetTokenStartingWith('.')).string) - - self.assertEquals( - None, - tokenutil.GetNextCodeToken(_GetTokenStartingWith('end1'))) - - def testGetIdentifierStart(self): - - tokens = testutil.TokenizeSource(""" -start1 . // comment - prototype. /* another comment */ - end1 - -['edge'][case].prototype. - end2 = function() {} -""") - - def _GetTokenStartingWith(token_starts_with): - for t in tokens: - if t.string.startswith(token_starts_with): - return t - - self.assertEquals( - 'start1', - tokenutil.GetIdentifierStart(_GetTokenStartingWith('end1')).string) - - self.assertEquals( - 'start1', - tokenutil.GetIdentifierStart(_GetTokenStartingWith('start1')).string) - - self.assertEquals( - None, - tokenutil.GetIdentifierStart(_GetTokenStartingWith('end2'))) - - def testInsertTokenBefore(self): - - self.AssertInsertTokenAfterBefore(False) - - def testInsertTokenAfter(self): - - self.AssertInsertTokenAfterBefore(True) - - def AssertInsertTokenAfterBefore(self, after): - - new_token = javascripttokens.JavaScriptToken( - 'a', javascripttokens.JavaScriptTokenType.IDENTIFIER, 1, 1) - - existing_token1 = javascripttokens.JavaScriptToken( - 'var', javascripttokens.JavaScriptTokenType.KEYWORD, 1, 1) - existing_token1.start_index = 0 - existing_token1.metadata = ecmametadatapass.EcmaMetaData() - - existing_token2 = javascripttokens.JavaScriptToken( - ' ', javascripttokens.JavaScriptTokenType.WHITESPACE, 1, 1) - existing_token2.start_index = 3 - existing_token2.metadata = ecmametadatapass.EcmaMetaData() - existing_token2.metadata.last_code = existing_token1 - - existing_token1.next = existing_token2 - existing_token2.previous = existing_token1 - - if after: - tokenutil.InsertTokenAfter(new_token, existing_token1) - else: - tokenutil.InsertTokenBefore(new_token, existing_token2) - - self.assertEquals(existing_token1, new_token.previous) - self.assertEquals(existing_token2, new_token.next) - - self.assertEquals(new_token, existing_token1.next) - self.assertEquals(new_token, existing_token2.previous) - - self.assertEquals(existing_token1, new_token.metadata.last_code) - self.assertEquals(new_token, existing_token2.metadata.last_code) - - self.assertEquals(0, existing_token1.start_index) - self.assertEquals(3, new_token.start_index) - self.assertEquals(4, existing_token2.start_index) - - def testGetIdentifierForToken(self): - - tokens = testutil.TokenizeSource(""" -start1.abc.def.prototype. - onContinuedLine - -(start2.abc.def - .hij.klm - .nop) - -start3.abc.def - .hij = function() {}; - -// An absurd multi-liner. -start4.abc.def. - hij. - klm = function() {}; - -start5 . aaa . bbb . ccc - shouldntBePartOfThePreviousSymbol - -start6.abc.def ghi.shouldntBePartOfThePreviousSymbol - -var start7 = 42; - -function start8() { - -} - -start9.abc. // why is there a comment here? - def /* another comment */ - shouldntBePart - -start10.abc // why is there a comment here? - .def /* another comment */ - shouldntBePart - -start11.abc. middle1.shouldNotBeIdentifier -""") - - def _GetTokenStartingWith(token_starts_with): - for t in tokens: - if t.string.startswith(token_starts_with): - return t - - self.assertEquals( - 'start1.abc.def.prototype.onContinuedLine', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start1'))) - - self.assertEquals( - 'start2.abc.def.hij.klm.nop', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start2'))) - - self.assertEquals( - 'start3.abc.def.hij', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start3'))) - - self.assertEquals( - 'start4.abc.def.hij.klm', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start4'))) - - self.assertEquals( - 'start5.aaa.bbb.ccc', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start5'))) - - self.assertEquals( - 'start6.abc.def', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start6'))) - - self.assertEquals( - 'start7', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start7'))) - - self.assertEquals( - 'start8', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start8'))) - - self.assertEquals( - 'start9.abc.def', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start9'))) - - self.assertEquals( - 'start10.abc.def', - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('start10'))) - - self.assertIsNone( - tokenutil.GetIdentifierForToken(_GetTokenStartingWith('middle1'))) - - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/trailing_comma_test.py b/third_party/closure_linter/closure_linter/trailing_comma_test.py deleted file mode 100644 index ddac3045..0000000 --- a/third_party/closure_linter/closure_linter/trailing_comma_test.py +++ /dev/null
@@ -1,64 +0,0 @@ -#!/usr/bin/env python -# Copyright 2013 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -""" -Tests for trailing commas (ES3) errors - -""" - - -import gflags as flags -import unittest as googletest - -from closure_linter import errors -from closure_linter import runner -from closure_linter.common import erroraccumulator - -flags.FLAGS.check_trailing_comma = True -class TrailingCommaTest(googletest.TestCase): - """Test case to for gjslint errorrules.""" - - def testGetTrailingCommaArray(self): - """ warning for trailing commas before closing array - """ - original = ['q = [1,]', ] - - # Expect line too long. - expected = errors.COMMA_AT_END_OF_LITERAL - - self._AssertInError(original, expected) - - def testGetTrailingCommaDict(self): - """ warning for trailing commas before closing array - """ - original = ['q = {1:1,}', ] - - # Expect line too long. - expected = errors.COMMA_AT_END_OF_LITERAL - - self._AssertInError(original, expected) - - def _AssertInError(self, original, expected): - """Asserts that the error fixer corrects original to expected.""" - - # Trap gjslint's output parse it to get messages added. - error_accumulator = erroraccumulator.ErrorAccumulator() - runner.Run('testing.js', error_accumulator, source=original) - error_nums = [e.code for e in error_accumulator.GetErrors()] - - self.assertIn(expected, error_nums) - -if __name__ == '__main__': - googletest.main()
diff --git a/third_party/closure_linter/closure_linter/typeannotation.py b/third_party/closure_linter/closure_linter/typeannotation.py deleted file mode 100644 index e8e270d..0000000 --- a/third_party/closure_linter/closure_linter/typeannotation.py +++ /dev/null
@@ -1,410 +0,0 @@ -#!/usr/bin/env python -#*-* coding: utf-8 -"""Closure typeannotation parsing and utilities.""" - - - -from closure_linter import errors -from closure_linter import javascripttokens -from closure_linter.common import error - -# Shorthand -TYPE = javascripttokens.JavaScriptTokenType - - -class TypeAnnotation(object): - """Represents a structured view of a closure type annotation. - - Attribute: - identifier: The name of the type. - key_type: The name part before a colon. - sub_types: The list of sub_types used e.g. for Array.<…> - or_null: The '?' annotation - not_null: The '!' annotation - type_group: If this a a grouping (a|b), but does not include function(a). - return_type: The return type of a function definition. - alias: The actual type set by closurizednamespaceinfo if the identifier uses - an alias to shorten the name. - tokens: An ordered list of tokens used for this type. May contain - TypeAnnotation instances for sub_types, key_type or return_type. - """ - - IMPLICIT_TYPE_GROUP = 2 - - NULLABILITY_UNKNOWN = 2 - - FUNCTION_TYPE = 'function' - NULL_TYPE = 'null' - VAR_ARGS_TYPE = '...' - - # Frequently used known non-nullable types. - NON_NULLABLE = frozenset([ - 'boolean', FUNCTION_TYPE, 'number', 'string', 'undefined']) - # Frequently used known nullable types. - NULLABLE_TYPE_WHITELIST = frozenset([ - 'Array', 'Document', 'Element', 'Function', 'Node', 'NodeList', - 'Object']) - - def __init__(self): - self.identifier = '' - self.sub_types = [] - self.or_null = False - self.not_null = False - self.type_group = False - self.alias = None - self.key_type = None - self.record_type = False - self.opt_arg = False - self.return_type = None - self.tokens = [] - - def IsFunction(self): - """Determines whether this is a function definition.""" - return self.identifier == TypeAnnotation.FUNCTION_TYPE - - def IsConstructor(self): - """Determines whether this is a function definition for a constructor.""" - key_type = self.sub_types and self.sub_types[0].key_type - return self.IsFunction() and key_type.identifier == 'new' - - def IsRecordType(self): - """Returns True if this type is a record type.""" - return (self.record_type or - any(t.IsRecordType() for t in self.sub_types)) - - def IsVarArgsType(self): - """Determines if the type is a var_args type, i.e. starts with '...'.""" - return self.identifier.startswith(TypeAnnotation.VAR_ARGS_TYPE) or ( - self.type_group == TypeAnnotation.IMPLICIT_TYPE_GROUP and - self.sub_types[0].identifier.startswith(TypeAnnotation.VAR_ARGS_TYPE)) - - def IsEmpty(self): - """Returns True if the type is empty.""" - return not self.tokens - - def IsUnknownType(self): - """Returns True if this is the unknown type {?}.""" - return (self.or_null - and not self.identifier - and not self.sub_types - and not self.return_type) - - def Append(self, item): - """Adds a sub_type to this type and finalizes it. - - Args: - item: The TypeAnnotation item to append. - """ - # item is a TypeAnnotation instance, so pylint: disable=protected-access - self.sub_types.append(item._Finalize(self)) - - def __repr__(self): - """Reconstructs the type definition.""" - append = '' - if self.sub_types: - separator = (',' if not self.type_group else '|') - if self.IsFunction(): - surround = '(%s)' - else: - surround = {False: '{%s}' if self.record_type else '<%s>', - True: '(%s)', - TypeAnnotation.IMPLICIT_TYPE_GROUP: '%s'}[self.type_group] - append = surround % separator.join(repr(t) for t in self.sub_types) - if self.return_type: - append += ':%s' % repr(self.return_type) - append += '=' if self.opt_arg else '' - prefix = '' + ('?' if self.or_null else '') + ('!' if self.not_null else '') - keyword = '%s:' % repr(self.key_type) if self.key_type else '' - return keyword + prefix + '%s' % (self.alias or self.identifier) + append - - def ToString(self): - """Concats the type's tokens to form a string again.""" - ret = [] - for token in self.tokens: - if not isinstance(token, TypeAnnotation): - ret.append(token.string) - else: - ret.append(token.ToString()) - return ''.join(ret) - - def Dump(self, indent=''): - """Dumps this type's structure for debugging purposes.""" - result = [] - for t in self.tokens: - if isinstance(t, TypeAnnotation): - result.append(indent + str(t) + ' =>\n' + t.Dump(indent + ' ')) - else: - result.append(indent + str(t)) - return '\n'.join(result) - - def IterIdentifiers(self): - """Iterates over all identifiers in this type and its subtypes.""" - if self.identifier: - yield self.identifier - for subtype in self.IterTypes(): - for identifier in subtype.IterIdentifiers(): - yield identifier - - def IterTypeGroup(self): - """Iterates over all types in the type group including self. - - Yields: - If this is a implicit or manual type-group: all sub_types. - Otherwise: self - E.g. for @type {Foo.<Bar>} this will yield only Foo.<Bar>, - for @type {Foo|(Bar|Sample)} this will yield Foo, Bar and Sample. - - """ - if self.type_group: - for sub_type in self.sub_types: - for sub_type in sub_type.IterTypeGroup(): - yield sub_type - else: - yield self - - def IterTypes(self): - """Iterates over each subtype as well as return and key types.""" - if self.return_type: - yield self.return_type - - if self.key_type: - yield self.key_type - - for sub_type in self.sub_types: - yield sub_type - - def GetNullability(self, modifiers=True): - """Computes whether the type may be null. - - Args: - modifiers: Whether the modifiers ? and ! should be considered in the - evaluation. - Returns: - True if the type allows null, False if the type is strictly non nullable - and NULLABILITY_UNKNOWN if the nullability cannot be determined. - """ - - # Explicitly marked nullable types or 'null' are nullable. - if ((modifiers and self.or_null) or - self.identifier == TypeAnnotation.NULL_TYPE): - return True - - # Explicitly marked non-nullable types or non-nullable base types: - if ((modifiers and self.not_null) or self.record_type - or self.identifier in TypeAnnotation.NON_NULLABLE): - return False - - # A type group is nullable if any of its elements are nullable. - if self.type_group: - maybe_nullable = False - for sub_type in self.sub_types: - nullability = sub_type.GetNullability() - if nullability == self.NULLABILITY_UNKNOWN: - maybe_nullable = nullability - elif nullability: - return True - return maybe_nullable - - # Whitelisted types are nullable. - if self.identifier.rstrip('.') in TypeAnnotation.NULLABLE_TYPE_WHITELIST: - return True - - # All other types are unknown (most should be nullable, but - # enums are not and typedefs might not be). - return TypeAnnotation.NULLABILITY_UNKNOWN - - def WillAlwaysBeNullable(self): - """Computes whether the ! flag is illegal for this type. - - This is the case if this type or any of the subtypes is marked as - explicitly nullable. - - Returns: - True if the ! flag would be illegal. - """ - if self.or_null or self.identifier == TypeAnnotation.NULL_TYPE: - return True - - if self.type_group: - return any(t.WillAlwaysBeNullable() for t in self.sub_types) - - return False - - def _Finalize(self, parent): - """Fixes some parsing issues once the TypeAnnotation is complete.""" - - # Normalize functions whose definition ended up in the key type because - # they defined a return type after a colon. - if (self.key_type and - self.key_type.identifier == TypeAnnotation.FUNCTION_TYPE): - current = self.key_type - current.return_type = self - self.key_type = None - # opt_arg never refers to the return type but to the function itself. - current.opt_arg = self.opt_arg - self.opt_arg = False - return current - - # If a typedef just specified the key, it will not end up in the key type. - if parent.record_type and not self.key_type: - current = TypeAnnotation() - current.key_type = self - current.tokens.append(self) - return current - return self - - def FirstToken(self): - """Returns the first token used in this type or any of its subtypes.""" - first = self.tokens[0] - return first.FirstToken() if isinstance(first, TypeAnnotation) else first - - -def Parse(token, token_end, error_handler): - """Parses a type annotation and returns a TypeAnnotation object.""" - return TypeAnnotationParser(error_handler).Parse(token.next, token_end) - - -class TypeAnnotationParser(object): - """A parser for type annotations constructing the TypeAnnotation object.""" - - def __init__(self, error_handler): - self._stack = [] - self._error_handler = error_handler - self._closing_error = False - - def Parse(self, token, token_end): - """Parses a type annotation and returns a TypeAnnotation object.""" - root = TypeAnnotation() - self._stack.append(root) - current = TypeAnnotation() - root.tokens.append(current) - - while token and token != token_end: - if token.type in (TYPE.DOC_TYPE_START_BLOCK, TYPE.DOC_START_BRACE): - if token.string == '(': - if current.identifier and current.identifier not in [ - TypeAnnotation.FUNCTION_TYPE, TypeAnnotation.VAR_ARGS_TYPE]: - self.Error(token, - 'Invalid identifier for (): "%s"' % current.identifier) - current.type_group = ( - current.identifier != TypeAnnotation.FUNCTION_TYPE) - elif token.string == '{': - current.record_type = True - current.tokens.append(token) - self._stack.append(current) - current = TypeAnnotation() - self._stack[-1].tokens.append(current) - - elif token.type in (TYPE.DOC_TYPE_END_BLOCK, TYPE.DOC_END_BRACE): - prev = self._stack.pop() - prev.Append(current) - current = prev - - # If an implicit type group was created, close it as well. - if prev.type_group == TypeAnnotation.IMPLICIT_TYPE_GROUP: - prev = self._stack.pop() - prev.Append(current) - current = prev - current.tokens.append(token) - - elif token.type == TYPE.DOC_TYPE_MODIFIER: - if token.string == '!': - current.tokens.append(token) - current.not_null = True - elif token.string == '?': - current.tokens.append(token) - current.or_null = True - elif token.string == ':': - current.tokens.append(token) - prev = current - current = TypeAnnotation() - prev.tokens.append(current) - current.key_type = prev - elif token.string == '=': - # For implicit type groups the '=' refers to the parent. - try: - if self._stack[-1].type_group == TypeAnnotation.IMPLICIT_TYPE_GROUP: - self._stack[-1].tokens.append(token) - self._stack[-1].opt_arg = True - else: - current.tokens.append(token) - current.opt_arg = True - except IndexError: - self.ClosingError(token) - elif token.string == '|': - # If a type group has explicitly been opened, do a normal append. - # Otherwise we have to open the type group and move the current - # type into it, before appending - if not self._stack[-1].type_group: - type_group = TypeAnnotation() - if (current.key_type and - current.key_type.identifier != TypeAnnotation.FUNCTION_TYPE): - type_group.key_type = current.key_type - current.key_type = None - type_group.type_group = TypeAnnotation.IMPLICIT_TYPE_GROUP - # Fix the token order - prev = self._stack[-1].tokens.pop() - self._stack[-1].tokens.append(type_group) - type_group.tokens.append(prev) - self._stack.append(type_group) - self._stack[-1].tokens.append(token) - self.Append(current, error_token=token) - current = TypeAnnotation() - self._stack[-1].tokens.append(current) - elif token.string == ',': - self.Append(current, error_token=token) - current = TypeAnnotation() - self._stack[-1].tokens.append(token) - self._stack[-1].tokens.append(current) - else: - current.tokens.append(token) - self.Error(token, 'Invalid token') - - elif token.type == TYPE.COMMENT: - current.tokens.append(token) - current.identifier += token.string.strip() - - elif token.type in [TYPE.DOC_PREFIX, TYPE.WHITESPACE]: - current.tokens.append(token) - - else: - current.tokens.append(token) - self.Error(token, 'Unexpected token') - - token = token.next - - self.Append(current, error_token=token) - try: - ret = self._stack.pop() - except IndexError: - self.ClosingError(token) - # The type is screwed up, but let's return something. - return current - - if self._stack and (len(self._stack) != 1 or - ret.type_group != TypeAnnotation.IMPLICIT_TYPE_GROUP): - self.Error(token, 'Too many opening items.') - - return ret if len(ret.sub_types) > 1 else ret.sub_types[0] - - def Append(self, type_obj, error_token): - """Appends a new TypeAnnotation object to the current parent.""" - if self._stack: - self._stack[-1].Append(type_obj) - else: - self.ClosingError(error_token) - - def ClosingError(self, token): - """Reports an error about too many closing items, but only once.""" - if not self._closing_error: - self._closing_error = True - self.Error(token, 'Too many closing items.') - - def Error(self, token, message): - """Calls the error_handler to post an error message.""" - if self._error_handler: - self._error_handler.HandleError(error.Error( - errors.JSDOC_DOES_NOT_PARSE, - 'Error parsing jsdoc type at token "%s" (column: %d): %s' % - (token.string, token.start_index, message), token)) -
diff --git a/third_party/closure_linter/closure_linter/typeannotation_test.py b/third_party/closure_linter/closure_linter/typeannotation_test.py deleted file mode 100644 index 4c60059c..0000000 --- a/third_party/closure_linter/closure_linter/typeannotation_test.py +++ /dev/null
@@ -1,233 +0,0 @@ -#!/usr/bin/env python -"""Unit tests for the typeannotation module.""" - - - - -import unittest as googletest - -from closure_linter import testutil -from closure_linter.common import erroraccumulator - -CRAZY_TYPE = ('Array.<!function(new:X,{a:null},...(c|d)):' - 'function(...(Object.<string>))>') - - -class TypeErrorException(Exception): - """Exception for TypeErrors.""" - - def __init__(self, errors): - super(TypeErrorException, self).__init__() - self.errors = errors - - -class TypeParserTest(googletest.TestCase): - """Tests for typeannotation parsing.""" - - def _ParseComment(self, script): - """Parse a script that contains one comment and return it.""" - accumulator = erroraccumulator.ErrorAccumulator() - _, comments = testutil.ParseFunctionsAndComments(script, accumulator) - if accumulator.GetErrors(): - raise TypeErrorException(accumulator.GetErrors()) - self.assertEquals(1, len(comments)) - return comments[0] - - def _ParseType(self, type_str): - """Creates a comment to parse and returns the parsed type.""" - comment = self._ParseComment('/** @type {%s} **/' % type_str) - return comment.GetDocFlags()[0].jstype - - def assertProperReconstruction(self, type_str, matching_str=None): - """Parses the type and asserts the its repr matches the type. - - If matching_str is specified, it will assert that the repr matches this - string instead. - - Args: - type_str: The type string to parse. - matching_str: A string the __repr__ of the parsed type should match. - Returns: - The parsed js_type. - """ - parsed_type = self._ParseType(type_str) - # Use listEqual assertion to more easily identify the difference - self.assertListEqual(list(matching_str or type_str), - list(repr(parsed_type))) - self.assertEquals(matching_str or type_str, repr(parsed_type)) - - # Newlines will be inserted by the file writer. - self.assertEquals(type_str.replace('\n', ''), parsed_type.ToString()) - return parsed_type - - def assertNullable(self, type_str, nullable=True): - parsed_type = self.assertProperReconstruction(type_str) - self.assertEquals(nullable, parsed_type.GetNullability(), - '"%s" should %sbe nullable' % - (type_str, 'not ' if nullable else '')) - - def assertNotNullable(self, type_str): - return self.assertNullable(type_str, nullable=False) - - def testReconstruction(self): - self.assertProperReconstruction('*') - self.assertProperReconstruction('number') - self.assertProperReconstruction('(((number)))') - self.assertProperReconstruction('!number') - self.assertProperReconstruction('?!number') - self.assertProperReconstruction('number=') - self.assertProperReconstruction('number=!?', '?!number=') - self.assertProperReconstruction('number|?string') - self.assertProperReconstruction('(number|string)') - self.assertProperReconstruction('?(number|string)') - self.assertProperReconstruction('Object.<number,string>') - self.assertProperReconstruction('function(new:Object)') - self.assertProperReconstruction('function(new:Object):number') - self.assertProperReconstruction('function(new:Object,Element):number') - self.assertProperReconstruction('function(this:T,...)') - self.assertProperReconstruction('{a:?number}') - self.assertProperReconstruction('{a:?number,b:(number|string)}') - self.assertProperReconstruction('{c:{nested_element:*}|undefined}') - self.assertProperReconstruction('{handleEvent:function(?):?}') - self.assertProperReconstruction('function():?|null') - self.assertProperReconstruction('null|function():?|bar') - - def testOptargs(self): - self.assertProperReconstruction('number=') - self.assertProperReconstruction('number|string=') - self.assertProperReconstruction('(number|string)=') - self.assertProperReconstruction('(number|string=)') - self.assertProperReconstruction('(number=|string)') - self.assertProperReconstruction('function(...):number=') - - def testIndepth(self): - # Do an deeper check of the crazy identifier - crazy = self.assertProperReconstruction(CRAZY_TYPE) - self.assertEquals('Array.', crazy.identifier) - self.assertEquals(1, len(crazy.sub_types)) - func1 = crazy.sub_types[0] - func2 = func1.return_type - self.assertEquals('function', func1.identifier) - self.assertEquals('function', func2.identifier) - self.assertEquals(3, len(func1.sub_types)) - self.assertEquals(1, len(func2.sub_types)) - self.assertEquals('Object.', func2.sub_types[0].sub_types[0].identifier) - - def testIterIdentifiers(self): - nested_identifiers = self._ParseType('(a|{b:(c|function(new:d):e)})') - for identifier in ('a', 'b', 'c', 'd', 'e'): - self.assertIn(identifier, nested_identifiers.IterIdentifiers()) - - def testIsEmpty(self): - self.assertTrue(self._ParseType('').IsEmpty()) - self.assertFalse(self._ParseType('?').IsEmpty()) - self.assertFalse(self._ParseType('!').IsEmpty()) - self.assertFalse(self._ParseType('<?>').IsEmpty()) - - def testIsConstructor(self): - self.assertFalse(self._ParseType('').IsConstructor()) - self.assertFalse(self._ParseType('Array.<number>').IsConstructor()) - self.assertTrue(self._ParseType('function(new:T)').IsConstructor()) - - def testIsVarArgsType(self): - self.assertTrue(self._ParseType('...number').IsVarArgsType()) - self.assertTrue(self._ParseType('...Object|Array').IsVarArgsType()) - self.assertTrue(self._ParseType('...(Object|Array)').IsVarArgsType()) - self.assertFalse(self._ParseType('Object|...Array').IsVarArgsType()) - self.assertFalse(self._ParseType('(...Object|Array)').IsVarArgsType()) - - def testIsUnknownType(self): - self.assertTrue(self._ParseType('?').IsUnknownType()) - self.assertTrue(self._ParseType('Foo.<?>').sub_types[0].IsUnknownType()) - self.assertFalse(self._ParseType('?|!').IsUnknownType()) - self.assertTrue(self._ParseType('?|!').sub_types[0].IsUnknownType()) - self.assertFalse(self._ParseType('!').IsUnknownType()) - - long_type = 'function():?|{handleEvent:function(?=):?,sample:?}|?=' - record = self._ParseType(long_type) - # First check that there's not just one type with 3 return types, but three - # top-level types. - self.assertEquals(3, len(record.sub_types)) - - # Now extract all unknown type instances and verify that they really are. - handle_event, sample = record.sub_types[1].sub_types - for i, sub_type in enumerate([ - record.sub_types[0].return_type, - handle_event.return_type, - handle_event.sub_types[0], - sample, - record.sub_types[2]]): - self.assertTrue(sub_type.IsUnknownType(), - 'Type %d should be the unknown type: %s\n%s' % ( - i, sub_type.tokens, record.Dump())) - - def testTypedefNames(self): - easy = self._ParseType('{a}') - self.assertTrue(easy.record_type) - - easy = self.assertProperReconstruction('{a}', '{a:}').sub_types[0] - self.assertEquals('a', easy.key_type.identifier) - self.assertEquals('', easy.identifier) - - easy = self.assertProperReconstruction('{a:b}').sub_types[0] - self.assertEquals('a', easy.key_type.identifier) - self.assertEquals('b', easy.identifier) - - def assertTypeError(self, type_str): - """Asserts that parsing the given type raises a linter error.""" - self.assertRaises(TypeErrorException, self._ParseType, type_str) - - def testParseBadTypes(self): - """Tests that several errors in types don't break the parser.""" - self.assertTypeError('<') - self.assertTypeError('>') - self.assertTypeError('Foo.<Bar') - self.assertTypeError('Foo.Bar>=') - self.assertTypeError('Foo.<Bar>>=') - self.assertTypeError('(') - self.assertTypeError(')') - self.assertTypeError('Foo.<Bar)>') - self._ParseType(':') - self._ParseType(':foo') - self.assertTypeError(':)foo') - self.assertTypeError('(a|{b:(c|function(new:d):e') - - def testNullable(self): - self.assertNullable('null') - self.assertNullable('Object') - self.assertNullable('?string') - self.assertNullable('?number') - - self.assertNotNullable('string') - self.assertNotNullable('number') - self.assertNotNullable('boolean') - self.assertNotNullable('function(Object)') - self.assertNotNullable('function(Object):Object') - self.assertNotNullable('function(?Object):?Object') - self.assertNotNullable('!Object') - - self.assertNotNullable('boolean|string') - self.assertNotNullable('(boolean|string)') - - self.assertNullable('(boolean|string|null)') - self.assertNullable('(?boolean)') - self.assertNullable('?(boolean)') - - self.assertNullable('(boolean|Object)') - self.assertNotNullable('(boolean|(string|{a:}))') - - def testSpaces(self): - """Tests that spaces don't change the outcome.""" - type_str = (' A < b | ( c | ? ! d e f ) > | ' - 'function ( x : . . . ) : { y : z = } ') - two_spaces = type_str.replace(' ', ' ') - no_spaces = type_str.replace(' ', '') - newlines = type_str.replace(' ', '\n * ') - self.assertProperReconstruction(no_spaces) - self.assertProperReconstruction(type_str, no_spaces) - self.assertProperReconstruction(two_spaces, no_spaces) - self.assertProperReconstruction(newlines, no_spaces) - -if __name__ == '__main__': - googletest.main() -
diff --git a/third_party/closure_linter/setup.py b/third_party/closure_linter/setup.py deleted file mode 100755 index 52bf566a..0000000 --- a/third_party/closure_linter/setup.py +++ /dev/null
@@ -1,38 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 The Closure Linter Authors. All Rights Reserved. -# -# 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. - -try: - from setuptools import setup -except ImportError: - from distutils.core import setup - -setup(name='closure_linter', - version='2.3.19', - description='Closure Linter', - license='Apache', - author='The Closure Linter Authors', - author_email='opensource@google.com', - url='https://github.com/google/closure-linter', - install_requires=['python-gflags'], - package_dir={'closure_linter': 'closure_linter'}, - packages=['closure_linter', 'closure_linter.common'], - entry_points = { - 'console_scripts': [ - 'gjslint = closure_linter.gjslint:main', - 'fixjsstyle = closure_linter.fixjsstyle:main' - ] - } -)
diff --git a/tools/checkperms/checkperms.py b/tools/checkperms/checkperms.py index 81b0f4f0..8e75974 100755 --- a/tools/checkperms/checkperms.py +++ b/tools/checkperms/checkperms.py
@@ -183,7 +183,6 @@ 'out/', # TODO(maruel): Fix these. 'third_party/bintrees/', - 'third_party/closure_linter/', 'third_party/devscripts/licensecheck.pl.vanilla', 'third_party/hyphen/', 'third_party/lcov-1.9/contrib/galaxy/conglomerate_functions.pl',
diff --git a/ui/aura/mus/focus_synchronizer.cc b/ui/aura/mus/focus_synchronizer.cc index 74ad3e09..b211315f 100644 --- a/ui/aura/mus/focus_synchronizer.cc +++ b/ui/aura/mus/focus_synchronizer.cc
@@ -16,16 +16,13 @@ FocusSynchronizer::FocusSynchronizer(FocusSynchronizerDelegate* delegate, ui::mojom::WindowTree* window_tree) - : delegate_(delegate), window_tree_(window_tree), env_(Env::GetInstance()) { - DCHECK(env_); - env_->AddObserver(this); + : delegate_(delegate), window_tree_(window_tree) { + Env::GetInstance()->AddObserver(this); } FocusSynchronizer::~FocusSynchronizer() { - if (env_) { - SetActiveFocusClient(nullptr); - env_->RemoveObserver(this); - } + SetActiveFocusClient(nullptr); + Env::GetInstance()->RemoveObserver(this); } void FocusSynchronizer::SetFocusFromServer(WindowMus* window) { @@ -84,13 +81,6 @@ void FocusSynchronizer::OnWindowInitialized(Window* window) {} -void FocusSynchronizer::OnWillDestroyEnv() { - // TODO(sky): this override should not be necessary. http://crbug.com/674803. - SetActiveFocusClient(nullptr); - env_->RemoveObserver(this); - env_ = nullptr; -} - void FocusSynchronizer::OnActiveFocusClientChanged( client::FocusClient* focus_client, Window* window) {
diff --git a/ui/aura/mus/focus_synchronizer.h b/ui/aura/mus/focus_synchronizer.h index 8a67a8b..db2556d7 100644 --- a/ui/aura/mus/focus_synchronizer.h +++ b/ui/aura/mus/focus_synchronizer.h
@@ -17,7 +17,6 @@ namespace aura { -class Env; class FocusSynchronizerDelegate; class WindowMus; @@ -53,7 +52,6 @@ // Overrided from EnvObserver: void OnWindowInitialized(Window* window) override; - void OnWillDestroyEnv() override; void OnActiveFocusClientChanged(client::FocusClient* focus_client, Window* window) override; @@ -66,9 +64,6 @@ WindowMus* window_setting_focus_to_ = nullptr; WindowMus* focused_window_ = nullptr; - // Cached so we can detect if Env is destroyed before us. - Env* env_; - DISALLOW_COPY_AND_ASSIGN(FocusSynchronizer); };
diff --git a/ui/views/mus/aura_init.h b/ui/views/mus/aura_init.h index 3558d73..fc37b5b6 100644 --- a/ui/views/mus/aura_init.h +++ b/ui/views/mus/aura_init.h
@@ -75,8 +75,8 @@ const std::string resource_file_; const std::string resource_file_200_; - std::unique_ptr<MusClient> mus_client_; std::unique_ptr<aura::Env> env_; + std::unique_ptr<MusClient> mus_client_; std::unique_ptr<ViewsDelegate> views_delegate_; DISALLOW_COPY_AND_ASSIGN(AuraInit);
diff --git a/ui/views/mus/mus_client.cc b/ui/views/mus/mus_client.cc index e01e1ff..203d74a2 100644 --- a/ui/views/mus/mus_client.cc +++ b/ui/views/mus/mus_client.cc
@@ -64,6 +64,7 @@ bool create_wm_state) : identity_(identity) { DCHECK(!instance_); + DCHECK(aura::Env::GetInstance()); instance_ = this; if (!io_task_runner) { @@ -131,6 +132,7 @@ base::DiscardableMemoryAllocator::SetInstance(nullptr); DCHECK_EQ(instance_, this); instance_ = nullptr; + DCHECK(aura::Env::GetInstance()); } // static
diff --git a/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html b/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html index e5d4ef90..0a36633 100644 --- a/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html +++ b/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html
@@ -1,4 +1,5 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <dom-module id="cr-action-menu"> <template> @@ -16,6 +17,27 @@ background-color: transparent; } + :host ::content .dropdown-item { + background: none; + border: none; + box-sizing: border-box; + color: var(--paper-grey-800); + font: inherit; + min-height: 32px; + padding: 0 24px; + text-align: start; + width: 100%; + } + + :host ::content .dropdown-item:not([hidden]) { + align-items: center; + display: flex; + } + + :host ::content .dropdown-item:not([disabled]) { + @apply(--cr-actionable); + } + :host ::content .dropdown-item:focus { background-color: var(--paper-grey-300); outline: none;
diff --git a/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp b/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp deleted file mode 100644 index 745731b..0000000 --- a/ui/webui/resources/cr_elements/cr_shared_menu/compiled_resources2.gyp +++ /dev/null
@@ -1,18 +0,0 @@ -# Copyright 2016 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. -{ - 'targets': [ - { - 'target_name': 'cr_shared_menu', - 'dependencies': [ - '../../js/compiled_resources2.gyp:assert', - '../../js/compiled_resources2.gyp:cr', - '../../js/compiled_resources2.gyp:util', - '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/compiled_resources2.gyp:iron-a11y-keys-behavior-extracted', - ], - - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - ], -}
diff --git a/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.html b/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.html deleted file mode 100644 index c9b0070a..0000000 --- a/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.html +++ /dev/null
@@ -1,33 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/html/assert.html"> -<link rel="import" href="chrome://resources/html/cr.html"> -<link rel="import" href="chrome://resources/html/util.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-dropdown/iron-dropdown.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-in-animation.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/animations/fade-out-animation.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-listbox/paper-listbox.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/shadow.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu-button/paper-menu-button-animations.html"> - -<dom-module id="cr-shared-menu"> - <template> - <style> - paper-listbox { - @apply(--shadow-elevation-2dp); - overflow: hidden; - position: relative; - width: var(--cr-shared-menu-width); - } - </style> - <iron-dropdown id="dropdown" allow-outside-scroll restore-focus-on-close - vertical-align="auto" horizontal-align="right" opened="{{menuOpen}}" - open-animation-config="[[openAnimationConfig]]" - close-animation-config="[[closeAnimationConfig]]"> - <paper-listbox id="menu" class="dropdown-content"> - <content></content> - </paper-listbox> - </iron-dropdown> - </template> - <script src="cr_shared_menu.js"></script> -</dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js b/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js deleted file mode 100644 index 872b4b8..0000000 --- a/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js +++ /dev/null
@@ -1,179 +0,0 @@ -// Copyright 2016 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. - -/** Same as paper-menu-button's custom easing cubic-bezier param. */ -var SLIDE_CUBIC_BEZIER = 'cubic-bezier(0.3, 0.95, 0.5, 1)'; - -Polymer({ - is: 'cr-shared-menu', - - properties: { - menuOpen: { - type: Boolean, - observer: 'menuOpenChanged_', - value: false, - notify: true, - }, - - /** - * The contextual item that this menu was clicked for, e.g. the data used to - * render an item in an <iron-list> or <dom-repeat>. - * @type {?Object} - */ - itemData: { - type: Object, - value: null, - }, - - openAnimationConfig: { - type: Object, - value: function() { - return [{ - name: 'fade-in-animation', - timing: { - delay: 50, - duration: 200 - } - }, { - name: 'paper-menu-grow-width-animation', - timing: { - delay: 50, - duration: 150, - easing: SLIDE_CUBIC_BEZIER - } - }, { - name: 'paper-menu-grow-height-animation', - timing: { - delay: 100, - duration: 275, - easing: SLIDE_CUBIC_BEZIER - } - }]; - } - }, - - closeAnimationConfig: { - type: Object, - value: function() { - return [{ - name: 'fade-out-animation', - timing: { - duration: 150 - } - }]; - } - } - }, - - listeners: { - 'dropdown.iron-overlay-canceled': 'onOverlayCanceled_', - }, - - /** - * The last anchor that was used to open a menu. It's necessary for toggling. - * @private {?Element} - */ - lastAnchor_: null, - - /** @private {?function(!Event)} */ - keyHandler_: null, - - /** @override */ - attached: function() { - window.addEventListener('resize', this.closeMenu.bind(this)); - this.keyHandler_ = this.onCaptureKeyDown_.bind(this); - this.$.menu.addEventListener('keydown', this.keyHandler_, true); - }, - - /** @override */ - detached: function() { - this.$.menu.removeEventListener('keydown', this.keyHandler_, true); - }, - - /** Closes the menu. */ - closeMenu: function() { - if (this.root.activeElement == null) { - // Something else has taken focus away from the menu. Do not attempt to - // restore focus to the button which opened the menu. - this.$.dropdown.restoreFocusOnClose = false; - } - this.menuOpen = false; - }, - - /** - * Opens the menu at the anchor location. - * @param {!Element} anchor The location to display the menu. - * @param {!Object=} opt_itemData The contextual item's data. - */ - openMenu: function(anchor, opt_itemData) { - if (this.lastAnchor_ == anchor && this.menuOpen) - return; - - if (this.menuOpen) - this.closeMenu(); - - this.itemData = opt_itemData || null; - this.lastAnchor_ = anchor; - this.$.dropdown.restoreFocusOnClose = true; - this.$.menu.selected = -1; - - // Move the menu to the anchor. - this.$.dropdown.positionTarget = anchor; - this.menuOpen = true; - }, - - /** - * Toggles the menu for the anchor that is passed in. - * @param {!Element} anchor The location to display the menu. - * @param {!Object=} opt_itemData The contextual item's data. - */ - toggleMenu: function(anchor, opt_itemData) { - if (anchor == this.lastAnchor_ && this.menuOpen) - this.closeMenu(); - else - this.openMenu(anchor, opt_itemData); - }, - - /** - * Close the menu when tab is pressed. Note that we must - * explicitly add a capture event listener to do this as iron-menu-behavior - * eats all key events during bubbling. See - * https://github.com/PolymerElements/iron-menu-behavior/issues/56. - * This will move focus to the next focusable element before/after the - * anchor. - * @private - */ - onCaptureKeyDown_: function(e) { - if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(e, 'tab')) { - // Need to refocus the anchor synchronously so that the tab event takes - // effect on it. - this.$.dropdown.restoreFocusOnClose = false; - this.lastAnchor_.focus(); - this.closeMenu(); - } - }, - - /** - * Ensure the menu is reset properly when it is closed by the dropdown (eg, - * clicking outside). - * @private - */ - menuOpenChanged_: function() { - if (!this.menuOpen) { - this.itemData = null; - this.lastAnchor_ = null; - } - }, - - /** - * Prevent focus restoring when tapping outside the menu. This stops the - * focus moving around unexpectedly when closing the menu with the mouse. - * @param {CustomEvent} e - * @private - */ - onOverlayCanceled_: function(e) { - if (e.detail.type == 'tap') - this.$.dropdown.restoreFocusOnClose = false; - }, -});
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp index 8cf90917..2988c82 100644 --- a/ui/webui/resources/cr_elements_resources.grdp +++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -129,12 +129,6 @@ <structure name="IDR_CR_ELEMENTS_CR_SEARCH_FIELD_BEHAVIOR_JS" file="../../webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.js" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_SHARED_MENU_HTML" - file="../../webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.html" - type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_SHARED_MENU_JS" - file="../../webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js" - type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_SHARED_STYLE_CSS_HTML" file="../../webui/resources/cr_elements/shared_style_css.html" type="chrome_html"